Xin khai trương box này bằng một layout MTouch vẽ bằng Eagle, sử dụng 16F727.
Chỉ làm chức năng MTouch, kết nối với thiết bị khác thông qua UART.
Chỉ làm chức năng MTouch, kết nối với thiết bị khác thông qua UART.
/*Author
R&P Forwarding - Trading Co., Ltd.
58/48 Nguyen Minh Hoang, Ward 12, Tan Binh District, HCMC, Viet Nam.
http://dientu.rpc.vn
*/
#include<16f727.h>
#fuses HS, NOWDT, MCLR
#use delay(clock=20Mhz)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)
#byte ANSELA = 0x185
#byte ANSELB = 0x186
#byte ANSELD = 0x188
#byte ANSELE = 0x189
#byte PORTA = 0x5
#byte PORTB = 0x6
#byte PORTC = 0x7
#byte PORTD = 0x8
#byte PORTE = 0x9
#byte TRISA = 0x85
#byte TRISB = 0x86
#byte TRISC = 0x87
#byte TRISD = 0x88
#byte TRISE = 0x89
#byte T2CON = 0x012 // T2ON, prescale = 1:16
#byte T1CON = 0x010 // Timer1 enable, source= capacity sensing, 1:1 prescale, don't sync with sys clock
#byte T1GCON = 0x08F // T1GSS = Timer 2, toggle mode
#byte PR2 = 0x092
#byte OSCTUNE = 0x091
#byte OSCCON = 0x090
#byte CPSCON0 = 0x108 // control settings
#byte CPSCON1 = 0x109 // init to channel select = 0 (4 LSb's)
#bit TMR1GIF = 0x0C.7 // clear gate intpt flag
#bit TMR1GIE = 0x8C.7 // enable gate intpt
#bit PEIE = 0x8B.6 // enable peripheral intpts
#bit TMR2IF = 0x0C.1
#bit TMR2IE = 0x8C.1
#bit GIE = 0x8B.7
#bit TMR1ON = 0x10.0
#bit LED1_MUX = PORTA.0
#bit LED2_MUX = PORTA.1
#bit LED3_MUX = PORTA.2
#bit LED4_MUX = PORTA.3
#bit LED5_MUX = PORTB.6
#bit LED6_MUX = PORTB.7
#bit LED7_MUX = PORTC.0
#bit LED8_MUX = PORTE.2
#bit TRIS_LED1 = TRISA.0
#bit TRIS_LED2 = TRISA.1
#bit TRIS_LED3 = TRISA.2
#bit TRIS_LED4 = TRISA.3
#bit TRIS_LED5 = TRISB.6
#bit TRIS_LED6 = TRISB.7
#bit TRIS_LED7 = TRISC.0
#bit TRIS_LED8 = TRISE.2
#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 struct{
struct {
unsigned char bounce;
}BYTES;
struct {
unsigned char isPress:1;
unsigned char flagPress:1;
unsigned char isRelease:1;
unsigned char unused:5;
}FLAG;
} 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].FLAG.isPress) {
//Your code here when BTN[i] Pressed
//Must Clear when BTN Press Processed
BTN[i].FLAG.isPress = 0;
//button i is Released
}else if(BTN[i].FLAG.isRelease) {
//Your code here when BTN[i] Release
//Must Clear when BTN Release Processed
BTN[i].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] = 0;
//setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
//enable_interrupts(INT_RTCC);
}
#INT_DEFAULT
void global_isr() {
if (TMR1GIF && TMR1GIE) {
TMR1GIF = 0; // clear intpt flag
TMR1ON = 0; // Timer1 off
bigval = get_timer1();
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].FLAG.flagPress && BTN[index].BYTES.bounce == BOUNCE_TIME) {
BTN[index].FLAG.isPress = 1;
BTN[index].FLAG.flagPress = 1;
}
}
else
{
if(BTN[index].BYTES.bounce > 0) BTN[index].BYTES.bounce--;
if(BTN[index].FLAG.flagPress && BTN[index].BYTES.bounce == 0) {
BTN[index].FLAG.flagPress = 0;
BTN[index].FLAG.isRelease = 1;
}
// Perform average after detection comparison
average[index] += bigval/4 - smallavg;
}
set_timer1(0);
TMR1ON = 1; // Set up for next channel
index ++;
index &= 0x0F;;
CPSCON1 = index;
}else if(TMR2IF) {
TMR2IF = 0;
}
}
.
/*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;
}
}

Comment