📄 main_wheelkey 16f726.c
字号:
/****************************************************************************
* Title : mTouch Wheel Key Module *
* UpDate : 2008.5.08 *
* *
* Device : PIC16F726-I/SS *
* OSC : 4Mhz( Internal OSC 4Mhz ) *
* *
* Compiler: Hi-tech V9.60 std *
* IDE : MPLAB IDE V8.10 *
* Hardware: Captouch Black Demo Board *
*****************************************************************************
Pad Frequency ( TMR0 Interrupt Peroid : 1mSec @ 4Mhz, 1:4 Prescaler
Counter(Khz) @ Idle
CPS0:590 CPS1:501 CPS2:579 CPS3:638 CPS4:711 CPS5:708 CPS6:630 CPS7:518
Counter(Khz) @ Finger Detect
CPS0:485 CPS1:424 CPS2:475 CPS3:520 CPS4:580 CPS5:570 CPS6:510 CPS7:430
Percent ( Finger Detect/Idle )
CPS0:82.2 CPS1:84.6 CPS2:82.2 CPS3:81.5 CPS4:81.5 CPS5:80.5 CPS6:80.9 CPS7:83.0
Counter(Khz) @ Finger Detect on the Plastic(1mm)
CPS0:545 CPS1:470 CPS2:535 CPS3:590 CPS4:656 CPS5:647 CPS6:580 CPS7:485
CPSCON0 = 0b10000100; // control settings
22 18 21 23 26 26 23 19
CPSCON0 = 0b10001000; // control settings
82 70 80 88 98 98 87 72
CPSCON0 = 0b10001100; // control settings
594 505 584 645 719 714 628 525
****************************************************************************/
#include <pic.h>
#include <pic16f72x.h>
//***************************************************************************
__CONFIG(INTIO & WDTDIS & PWRTDIS & MCLREN & BORDIS & UNPROTECT & PLLEN);
__CONFIG(VCAPRA0);
//***************************************************************************
#define NUM_BTTNS 8
//----- Port Define -----//
#define TestPort1 RA1
#define TestPort1_Tris TRISA1
#define TestPort2 RA2
#define TestPort2_Tris TRISA2
#define PIC16F726_IRQ RC6
//-----I2C Port Define -----//
#define SCL RC3
#define SCL_DIR TRISC3
#define SDA RC4
#define SDA_DIR TRISC4
//-----Initial_I2C_Slave Routine -----//
void Initial_I2C_Slave(void);
void ISR_I2CSlave(void);
#define SLIDER_ADDR 0b00010000
#define MULTI_ADDR 0b00100000
#define WHEEL_ADDR 0b00110000
#define I2C_SIZE NUM_BTTNS*2
struct{
unsigned char TxData[I2C_SIZE];
unsigned char TxLeng;
}I2C_Packet;
#define TMR0VALUE 14 // TMR0 Interrupt Time 1msec @ 4Mhz, 1:4 Prescaler
#define THRESHOLD_50 1 // avg >> 1 = 1/2 = 50% as a threshold value below average
#define THRESHOLD_25 2 // avg >> 2 = 1/4 = 25% as a threshold value below average
#define THRESHOLD_12P5 3 // avg >> 3 = 1/8 = 12.5% as a threshold value below average
#define THRESHOLD_6P25 4 // avg >> 4 = 1/16 = 6.25% as a threshold value below average
#define THRESHOLD_3P12 5 // avg >> 5 = 1/32 = 3.12% as a threshold value below average
#define THRESHOLD_1P56 6 // avg >> 6 = 1/64 = 1.56% as a threshold value below average
#define THRESHOLD_0P78 7 // avg >> 7 = 1/128 = 0.78% as a threshold value below average
#define HYSTERESIS 3
/** Variables **/
bank1 unsigned int RawData[NUM_BTTNS]; // current RawData for each button
bank1 unsigned int Average[NUM_BTTNS]; // Average for each button
bank1 unsigned int Threshold[NUM_BTTNS]; // Threshold for each button
typedef struct{
char BTN0 :1; // {byte 0}
char BTN1 :1;
char BTN2 :1;
char BTN3 :1;
char BTN4 :1;
char BTN5 :1;
char BTN6 :1;
char BTN7 :1;
}BButtons;
BButtons Buttons;
unsigned char Index,Counter=0;
unsigned char ButtonData, ButtonDataBuff;
/** Prototypes **/
void Init(void);
void RestartTimers(void);
void SetNextChannel(void);
void interrupt isr(void);
void SLEEP_NOP(void);
void SaveButtonData(void);
//**************************************************************************
void Delay_Routine(unsigned int Delay)
{
while(--Delay){CLRWDT();}
}
//******************************************************************************************
void main(void)
{
Init();
while(1);
}
//******************************************************************************************
void Init(void)
{
OSCCON = 0b00010000; // Internal 4Mhz @PLL On
// Port Description
//--------------------------------------------------------------------------
// 7 6 5 4 3 2 1 0 |
// PORTA . CPS7(7) CPS6(6) Test2 Test1 |
// PORTB . . CPS5(5) CPS4(4) CPS3(3) CPS2(2) CPS1(1) CPS0(0) |
// PORTC . IRQ MISO SDA SCL . . . |
//--------------------------------------------------------------------------
TRISA = 0b00110000;
ANSELA= 0b00110000;
TRISB = 0b00111111;
ANSELB= 0b00111111;
TRISC = 0b10111111;
// Initialize for Timer0 time base
OPTION = 0b11000001; // Timer0 init ( Prescaler:TMR0, 1:4 )
T0IF = 0; // enable tmr0 intpt
T0IE = 1;
// Initialize for Timer1 time Resource
T1CON = 0b01000101; // Timer1 enable, system clock, 1:1 prescale,
// Cap Sense Module
CPSCON0 = 0b10001100; // control settings
CPSCON1 = 0x00; // init to channel select = 0 (4 LSb's)
Index = CPSCON1; // Start program ready to scan first channel
// Initialize for I2C Slave
Initial_I2C_Slave();
TestPort1_Tris=0;
TestPort2_Tris=0;
for (Index=0; Index<NUM_BTTNS; Index++) {
RawData[Index] = 0;
Average[Index] = 0;
}
// Interrupt Enable
GIE = 1;
}
//******************************************************************************************
void interrupt isr(void)
{
CLRWDT();
//----- I2C Slave Interrupt -----//
if(SSPIE && SSPIF){
SSPIF = 0;
ISR_I2CSlave();
}
//----- TMR0 Interrupt -----//
if(T0IE && T0IF){
TestPort1^=1;
TMR0=TMR0VALUE;
T0IF = 0; // Clear T0IF every time
TMR1ON = 0; // Timer1 off
RawData[Index] = TMR1L + (unsigned int)(TMR1H << 8);
// Threshold Define for each Button
switch (Index){
case 0: Threshold[Index] = Average[Index]>>THRESHOLD_3P12; break;
case 1: Threshold[Index] = Average[Index]>>THRESHOLD_3P12; break;
case 2: Threshold[Index] = Average[Index]>>THRESHOLD_3P12; break;
case 3: Threshold[Index] = Average[Index]>>THRESHOLD_3P12; break;
case 4: Threshold[Index] = Average[Index]>>THRESHOLD_3P12; break;
case 5: Threshold[Index] = Average[Index]>>THRESHOLD_3P12; break;
case 6: Threshold[Index] = Average[Index]>>THRESHOLD_3P12; break;
case 7: Threshold[Index] = Average[Index]>>THRESHOLD_3P12; break;
default: break;
}
// Button Pressed (no hysteresis provided)
if (RawData[Index] < (Average[Index] - Threshold[Index])){
switch(Index){
case 0: Buttons.BTN0 = 1; break; // The current button is pressed
case 1: Buttons.BTN1 = 1; break; // Relay button pressed information to application
case 2: Buttons.BTN2 = 1; break;
case 3: Buttons.BTN3 = 1; break;
case 4: Buttons.BTN4 = 1; break;
case 5: Buttons.BTN5 = 1; break;
case 6: Buttons.BTN6 = 1; break;
case 7: Buttons.BTN7 = 1; break;
default: break;
}
}
// Button unpressed (hysteresis provided)
else{// if(RawData[Index] > (Average[Index] - Threshold[Index])){
switch(Index){
case 0: Buttons.BTN0 = 0; break; // The current button is unpressed
case 1: Buttons.BTN1 = 0; break; // Relay button pressed information to application
case 2: Buttons.BTN2 = 0; break;
case 3: Buttons.BTN3 = 0; break;
case 4: Buttons.BTN4 = 0; break;
case 5: Buttons.BTN5 = 0; break;
case 6: Buttons.BTN6 = 0; break;
case 7: Buttons.BTN7 = 0; break;
default: break;
}
Average[Index] = (Average[Index]*31 + RawData[Index])/32; // Get the Average 32
}
SetNextChannel(); // Set up for next channel
RestartTimers(); // Restart timer1
SaveButtonData(); // Save Buttone Data
}
}
//******************************************************************************************
void SetNextChannel(void)
{
if(++Index>=NUM_BTTNS) Index=0;
CPSCON1 = Index; // Select external pin CPS0..CPS15
}
//******************************************************************************************
void RestartTimers(void)
{
TMR1L = 0; // reset Timer1
TMR1H = 0; // " "
TMR1ON = 1; // restart Timer1
TMR0 = TMR0VALUE; // reset Timer0
T0IF = 0; // clear the interrupt
}
//******************************************************************************************
void SaveButtonData(void)
{
//unsigned char i,j;
ButtonDataBuff=0;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTN0;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTN1;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTN2;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTN3;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTN4;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTN5;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTN6;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTN7;
if(ButtonData!=ButtonDataBuff){
if(ButtonData>ButtonDataBuff){
ButtonData=ButtonDataBuff=0;
}
ButtonData=ButtonDataBuff;
I2C_Packet.TxData[0]=ButtonData;
PIC16F726_IRQ=1;
NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();
PIC16F726_IRQ=0;
}
}
//******************************************************************************************
void Initial_I2C_Slave(void)
{
// I2C Port Define
SCL_DIR = 1;
SDA_DIR = 1;
// I2C Register Define
SSPMSK = WHEEL_ADDR;
SSPADD = WHEEL_ADDR; // Slave Address
Delay_Routine(50);
SSPCON = 0b00111001; // For Errata sheet ( DS80243E )
Delay_Routine(50);
SSPCON = 0b00111110; // SSPEN(5) = Enable I2C, CKP = Enable Clock
// SSPM3:SSPM0(3-0) = I2C Slave Mode, 7bit Address
SMP = 1; // Speed 100Khz(SSPSTAT.7)
CKE = 1; // I2C Spec. (SSPSTAT.6)
SSPIF = 0; // Synchronous Serial Port Interrupt Flag bit
SSPIE = 1; // Synchronous Serial Interrupt Enable bit
PEIE = 1; // Peripheral Interrupt Enable bit
}
//******************************************************************************************
void ISR_I2CSlave(void)
{
unsigned char Temp;
if(WCOL) WCOL = 0;
if(SSPOV) SSPOV = 0;
if (STOP == 1) {
// Stop Condition
RestartTimers();
// Wrap-up Transmission
SSPOV = 0; // Clear overflow err if applicable
CKP = 1; // Enable clock again
return; // Return to end SSP use
} else if (RW == 0 && BF == 0) {
// Start Condition
T0IF=0;
SSPOV = 0; // Clear overflow err if applicable
CKP = 1; // Enable clock again
return; // Return to finish start interrupt
}
// Address Byte
if(!DA){ // Address
Temp=SSPBUF;
I2C_Packet.TxLeng=0;
if(RW){ // 1st Transmitting Data
SSPBUF = I2C_Packet.TxData[I2C_Packet.TxLeng++];
CKP = 1;
}
}
// Data Bytes
else{
if(RW){ // 2nd~~ Transmitting Data
SSPBUF = I2C_Packet.TxData[I2C_Packet.TxLeng++];
CKP = 1;
}
else{ // Receiving Datas
Temp=SSPBUF;
}
}
}
//******************************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -