📄 f_10_29_rotint_debounced.c
字号:
#include "config.h"#include "delay.h"#include "serial.c"#include "serio.c"#define S0 0#define S1 1#define S2 2#define S3 3volatile unsigned char state,last_state;volatile unsigned char count,last_count;volatile unsigned char int0_cnt,int0_last;volatile unsigned char int1_cnt,int1_last;volatile unsigned char update_flag;#define DEBOUNCE 5void update_state(void){ state = PORTB & 0x3; switch(state) { case S0: if (last_state == S1) count++; else if (last_state == S2) count--; break; case S1: if (last_state == S3) count++; else if (last_state == S0) count--; break; case S2: if (last_state == S0) count++; else if (last_state == S3) count--; break; case S3: if (last_state == S2) count++; else if (last_state == S1) count--; break; } if (last_count != count) { // valid pulse last_state = state; last_count = count; } else { // invalid transistion, reset last state last_state = state; }}// debounces rotary encoder inputs by sampling// their value at regular intervals#if defined(HI_TECH_C)void interrupt pic_isr(void)#endif#if defined(__18CXX)#pragma interrupt pic_isrvoid pic_isr(void)#endif{ if (TMR2IF) { // debouncing rotary inputs TMR2IF = 0; if (RB0 != int0_last) { int0_cnt++; if (int0_cnt == DEBOUNCE) { update_flag = 1; int0_cnt = 0;int0_last = RB0; } } // reset cnt, if pulse width not long enough else if (int0_cnt) int0_cnt = 0; if (RB1 != int1_last) { int1_cnt++; if (int1_cnt == DEBOUNCE) { update_flag = 1; int1_cnt = 0; int1_last = RB1; } } // reset cnt, if pulse width not long enough else if (int1_cnt) int1_cnt = 0; if (update_flag) { // can read the rotary inputs update_state(); update_flag = 0; } }}void main(void){ unsigned char count_old; // set RB0, RB1 for input TRISB0 = 1;TRISB1 = 1; RBPU = 0; // enable weak pullups int0_last = RB0; int1_last = RB1; last_state = PORTB & 0x03; // init last state serial_init(95,1); // 19200 in HSPLL mode, crystal = 7.3728 MHz // configure timer 2 // post scale of 11 TOUTPS3 = 1; TOUTPS2 = 0; TOUTPS1 = 1; TOUTPS0 = 0; // pre scale of 16 */ T2CKPS1 = 1; TMR2ON = 1 ; PR2 = 250; // interrupt interrupt interval of 6 mS // enable TMR2 interrupt IPEN = 0; TMR2IF = 0; TMR2IE = 1; PEIE = 1; GIE = 1; printf("With Timer2 Debounce"); pcrlf(); printf("Rotary Switch Test Started"); pcrlf(); count =0;count_old=0; while(1) { //tip: don't put volatile variables in printfs, may change // by the time the printf gets around to printing it! if (count != count_old){ count_old = count; printf("Count: %x",count_old); pcrlf(); } }}//for MCC18, place the interrupt vector goto#if defined(__18CXX)#if defined(HIGH_INTERRUPT)#pragma code HighVector=HIGH_INTERRUPT#else#pragma code HighVector=0x0008 #endifvoid HighVector (void){ _asm goto pic_isr _endasm}#pragma code#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -