DIGILIGHT
encoder.c
См. документацию.
1 
12 #include <avr/io.h>
13 #include "avr_helper.h"
14 #include "encoder.h"
15 #include "hardware.h"
16 
17 #define ENC_X BTN_UP
18 #define ENC_Y BTN_DN
19 #define ENC_ANY (ENC_X | ENC_Y)
20 #define ENC_PORT BTN_PORT
21 
26 static uint8_t get_enc_state(void){
27  return PIN(ENC_PORT) & ENC_ANY;
28 }
29 
30 // обозначения битов в слове состояния энкодера
31 #define X1 (ENC_X)
32 #define X2 (ENC_X << 8)
33 #define Y1 (ENC_Y)
34 #define Y2 (ENC_Y << 8)
35 
36 /*
37 № y2 y1 x2 x1 Вперёд Назад Состояние
38 ------------------------------------------------------------------
39 1 0 0 0 1 0 1 Назад X1
40 8 1 0 0 0 0 1 Назад Y2
41 7 0 1 1 1 0 1 Назад Y1 | X2 | X1
42 E 1 1 1 0 0 1 Назад Y2 | Y1 | X2
43 
44 2 0 0 1 0 1 0 Вперёд X2
45 4 0 1 0 0 1 0 Вперед Y1
46 B 1 0 1 1 1 0 Вперёд Y2 | X1 | X2
47 D 1 1 0 1 1 0 Вперёд Y1 | Y2 | X1
48  */
49 
57 int8_t get_encoder(void){
58  static uint8_t EncState;
59  static uint8_t r1, r2;
60 
61  uint8_t newValue = get_enc_state();
62  uint16_t fullState = newValue | (EncState << 8);
63  EncState = newValue;
64 
65  switch(fullState){
66  case X1:
67  case (Y1 | X2 | X1):
68  case Y2:
69  case (Y2 | Y1 | X2):
70  r1++;
71  break;
72  case X2:
73  case (Y2 | X1 | X2):
74  case Y1:
75  case (Y1 | Y2 | X1):
76  r2++;
77  break;
78  default:
79  break;
80  }
81  // на каждый "щелчок" энкодера формируется до 4 изменений счетчика,
82  // поэтому необходимо привести его значение к множеству [-1, 0, +1]
83  if(r1 >= 4){
84  r1 = 0;
85  return 1;
86  }
87  if(r2 >= 4){
88  r2 = 0;
89  return -1;
90  }
91  return 0;
92 }
93 
Аппаратно-зависимые определения
int8_t get_encoder(void)
Состояние энкодера
Definition: encoder.c:57
Обработка энкодера