Trích:
Nguyên văn bởi kimhuynguyen
Cảm ơn phamminhtuan đã ủng hộ về firmware.
Chức năng của mạch này là thay cái Keypad 4x4 (có bán ở Letran hoặc TMe)
Trên mạch có thiết kế Buzzer và Led. Khi chạm tay vào phím buzzer sẽ kêu và đèn sáng cho đến khi bỏ tay ra.
Đồng thời dữ liệu truyền ra UART là 2 byte (16 bit tương ứng với 16 phím-có thể nhấn nhiều phím cùng lúc)
Mong bạn phamminhtuan tiếp tục coding.
|
Mình nghĩ code như vậy đủ rồi, ai muốn viết thêm cái gì thì tùy người đó thôi, mình Post lên thêm code cho Hi-Tech C, lúc trước mình làm chạy rồi - nhưng phiên code này chưa test, nhưng có thể đảm bảo 99% là sẽ chạy trừ những trường hợp không chạy
.
Giải thuật Mtouch tham khảo ở App Notes của Microchip nếu không muốn nói là lấy của nó luôn
CODE HT-PIC C
Code:
/*Author
R&P Forwarding - Trading Co., Ltd.
58/48 Nguyen Minh Hoang, Ward 12, Tan Binh District, HCMC, Viet Nam.
http://dientu.rpc.vn
Hi-Tech PICC Version 0.10 XTAL 20Mhz
*/
#include<htc.h>
__CONFIG(HS & WDTDIS & UNPROTECT );
#define BOUNCE_TIME 2
unsigned char index;
unsigned long reading[16]; // current reading for each button
unsigned long average[16]; // running average for each button
unsigned long threshold; // threshold value is req'd # counts decrease from avg
unsigned long bigval; // current button bigval - for averaging technique
unsigned long smallavg; // current button smallavg - for averaging technique
typedef union{
unsigned short Val;
struct {
unsigned char bounce;
struct {
unsigned char isPress:1;
unsigned char flagPress:1;
unsigned char isRelease:1;
unsigned char unused:5;
}FLAG;
}BYTES;
} BUTTON;
BUTTON BTN[16];
void init();
void main() {
unsigned char i;
init();
while(1) {
for(i=0; i<16; i++) {
//button i is Pressed
if(BTN[i].BYTES.FLAG.isPress) {
//Your code here when BTN[i] Pressed
//Must Clear when BTN Press Processed
BTN[i].BYTES.FLAG.isPress = 0;
//button i is Released
}else if(BTN[i].BYTES.FLAG.isRelease) {
//Your code here when BTN[i] Release
//Must Clear when BTN Release Processed
BTN[i].BYTES.FLAG.isRelease = 0;
}
//end for
}
}
}
void init() {
char i;
//setup_oscillator(OSC_8MHZ);
for (index=0; index<16; index++){
average[index] = 0;
reading[index] = 0;
}
ANSELA = 0b00110000;
TRISA = 0b11111111;
ANSELB = 0b00111111;
TRISB = 0b11111111;
ANSELD = 0b11111111;
TRISD = 0b11111111;
TRISC = 0b11111111;
ANSELE = 0b00000000;
TRISE = 0b00000000;
T2CON = 0b011110111; // T2ON, prescale = 1:16
T1CON = 0b11000101; // Timer1 enable, source= capacity sensing, 1:1 prescale, don't sync with sys clock
T1GCON = 0b11100010; // T1GSS = Timer 2, toggle mode
PR2 = 0xB4;
CPSCON0 = 0b10001100; // control settings
CPSCON1 = 0x01; // init to channel select = 0 (4 LSb's)
index = 0;
TMR1GIF = 0; // clear gate intpt flag
TMR1GIE = 1; // enable gate intpt
PEIE = 1; // enable peripheral intpts
TMR2IF = 0;
TMR2IE = 1;
GIE = 1;
for(i=0; i<16; i++) BTN[i].Val = 0;
//setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
//enable_interrupts(INT_RTCC);
}
void interrupt
global_isr() {
if (TMR1GIF && TMR1GIE) {
TMR1GIF = 0; // clear intpt flag
TMR1ON = 0; // Timer1 off
bigval = (unsigned short)((TMR1H <<8) | TMR1L);
bigval = bigval * 4;
reading[index] = bigval;
smallavg = average[index] / 4;
threshold = average[index]>>1; // ratiometric threshold from avail above (& combinations)
if (bigval < average[index] - threshold)
{
if(BTN[index].BYTES.bounce < BOUNCE_TIME) BTN[index].BYTES.bounce++;
if(!BTN[index].BYTES.FLAG.flagPress && BTN[index].BYTES.bounce == BOUNCE_TIME) {
BTN[index].BYTES.FLAG.isPress = 1;
BTN[index].BYTES.FLAG.flagPress = 1;
}
}
else
{
if(BTN[index].BYTES.bounce > 0) BTN[index].BYTES.bounce--;
if(BTN[index].BYTES.FLAG.flagPress && BTN[index].BYTES.bounce == 0) {
BTN[index].BYTES.FLAG.flagPress = 0;
BTN[index].BYTES.FLAG.isRelease = 1;
}
// Perform average after detection comparison
average[index] += bigval/4 - smallavg;
}
TMR1H = 0;
TMR1L = 0;
TMR1ON = 1; // Set up for next channel
index ++;
index &= 0x0F;;
CPSCON1 = index;
}else if(TMR2IF) {
TMR2IF = 0;
}
}