00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "pic24_all.h"
00031
00036
00037 uint8 processRotaryData(volatile uint8 u8_curr, volatile uint8 u8_last,
00038 volatile uint8 *cntr, volatile uint8 max) {
00039 int8 delta = 0;
00040
00041 switch (u8_curr) {
00042 case 0:
00043 if (u8_last == 1) delta = 1;
00044 else if (u8_last == 2) delta = -1;
00045 break;
00046 case 1:
00047 if (u8_last == 3) delta = 1;
00048 else if (u8_last == 0) delta = -1;
00049 break;
00050 case 3:
00051 if (u8_last == 2) delta = 1;
00052 else if (u8_last == 1) delta = -1;
00053 break;
00054 case 2:
00055 if (u8_last == 0) delta = 1;
00056 else if (u8_last == 3) delta = -1;
00057 break;
00058 default:
00059 break;
00060 }
00061 if (delta == 0) return(1);
00062
00063 if (( *cntr == 0 && delta == -1)
00064 || (*cntr == max && delta == 1)) return 0;
00065 (*cntr) = (*cntr) + delta;
00066 return 0;
00067 }
00068
00069 #define ROT1_RAW _RB13
00070 #define ROT0_RAW _RB12
00071 #define GET_ROT_STATE() ((ROT1_RAW << 1) | ROT0_RAW)
00072
00074 inline void configRotaryEncoder() {
00075 CONFIG_RB13_AS_DIG_INPUT();
00076 ENABLE_RB13_PULLUP();
00077 CONFIG_RB12_AS_DIG_INPUT();
00078 ENABLE_RB12_PULLUP();
00079 DELAY_US(1);
00080 }
00081
00082 #define ROT_MAX 32 //arbitrary limit
00083
00084 volatile uint8 u8_valueROT = 0;
00085 volatile uint8 u8_lastvalueROT = 0;
00086 volatile uint8 u8_errROT = 0;
00087 volatile uint8 u8_cntrROT = 0;
00088
00089
00090 void _ISRFAST _T3Interrupt (void) {
00091 u8_valueROT = GET_ROT_STATE();
00092 if (u8_lastvalueROT != u8_valueROT) {
00093 u8_errROT = processRotaryData(u8_valueROT, u8_lastvalueROT, &u8_cntrROT, ROT_MAX);
00094 u8_lastvalueROT = u8_valueROT;
00095 }
00096 _T3IF = 0;
00097 }
00098
00099
00100 #define ISR_PERIOD 15 // in ms
00101 void configTimer3(void) {
00102
00103 T2CONbits.T32 = 0;
00104
00105
00106 T3CON = T3_OFF | T3_IDLE_CON | T3_GATE_OFF
00107 | T3_SOURCE_INT
00108 | T3_PS_1_64 ;
00109 PR3 = msToU16Ticks (ISR_PERIOD, getTimerPrescale(T3CONbits)) - 1;
00110 TMR3 = 0;
00111 _T3IF = 0;
00112 _T3IP = 1;
00113 _T3IE = 1;
00114 T3CONbits.TON = 1;
00115 }
00116
00117 int main (void) {
00118 uint8 u8_lastCnt;
00119 configBasic(HELLO_MSG);
00121 configRotaryEncoder();
00122 u8_valueROT = GET_ROT_STATE();
00123 u8_lastvalueROT = u8_valueROT;
00124 u8_lastCnt = u8_cntrROT;
00126 configTimer3();
00127 while (1) {
00128 if (u8_lastCnt != u8_cntrROT) {
00129 u8_lastCnt = u8_cntrROT;
00130 outUint8(u8_lastCnt);
00131 outString("\n");
00132 if (u8_errROT) {
00133 outString("Rotary state error\n");
00134 u8_errROT = 0;
00135 }
00136 }
00137 doHeartbeat();
00138 }
00139 }