📄 16f727.c
字号:
/****************************************************************************
* Title : mTouch 16Button Module *
* UpDate : 2008.5.08 *
* *
* Device : PIC16F727-I/PT *
* OSC : 4Mhz( Internal OSC 4Mhz ) *
* *
* Compiler: Hi-tech V9.60 std *
* IDE : MPLAB IDE V8.10 *
* Hardware: Captouch Black Demo Board *
*****************************************************************************
****************************************************************************/
#include <pic.h>
//***************************************************************************
__CONFIG(INTIO & WDTDIS & PWRTDIS & MCLREN & BORDIS & UNPROTECT & PLLEN);
__CONFIG(VCAPRA0);
//***************************************************************************
#define NUM_BTTNS 16
#define TestPort1 RC7
#define TestPort1_Tris TRISC7
#define TestPort2 RA3
#define TestPort2_Tris TRISA3
//----- Port Define -----//
#define PIC16F727_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
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 **/
bank2 unsigned int RawData[NUM_BTTNS]; // current RawData for each button
bank2 unsigned int Average[NUM_BTTNS]; // Average for each button
bank2 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;
char BTN8 :1;
char BTN9 :1;
char BTNA :1;
char BTNB :1;
char BTNC :1;
char BTND :1;
char BTNSt:1;
char BTNSh:1;
}BButtons;
BButtons Buttons;
unsigned char Index,Counter=0;
unsigned int 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(0) CPS6(*) Test2 |
// PORTB . . CPS5(A) CPS4(3) CPS3(2) CPS2(1) CPS1(B) CPS0(6) |
// PORTC Test1 IRQ MISO SDA SCL . . . |
// PORTD CPS15(5)CPS14(4)CPS13(C)CPS12(9)CPS11(8)CPS10(7)CPS9(D) CPS8(#) |
//--------------------------------------------------------------------------
TRISA = 0b00110000;
ANSELA= 0b00110000;
TRISB = 0b00111111;
ANSELB= 0b00111111;
TRISC = 0b00111111;
TRISD = 0b11111111;
ANSELD= 0b11111111;
// 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_6P25; break;
case 1: Threshold[Index] = Average[Index]>>THRESHOLD_6P25; break;
case 2: Threshold[Index] = Average[Index]>>THRESHOLD_6P25; break;
case 3: Threshold[Index] = Average[Index]>>THRESHOLD_6P25; break;
case 4: Threshold[Index] = Average[Index]>>THRESHOLD_6P25; break;
case 5: Threshold[Index] = Average[Index]>>THRESHOLD_6P25; break;
case 6: Threshold[Index] = Average[Index]>>THRESHOLD_3P12; break;
case 7: Threshold[Index] = Average[Index]>>THRESHOLD_3P12; break;
case 8: Threshold[Index] = Average[Index]>>THRESHOLD_6P25; break;
case 9: Threshold[Index] = Average[Index]>>THRESHOLD_6P25; break;
case 10: Threshold[Index] = Average[Index]>>THRESHOLD_6P25; break;
case 11: Threshold[Index] = Average[Index]>>THRESHOLD_6P25; break;
case 12: Threshold[Index] = Average[Index]>>THRESHOLD_6P25; break;
case 13: Threshold[Index] = Average[Index]>>THRESHOLD_6P25; break;
case 14: Threshold[Index] = Average[Index]>>THRESHOLD_6P25; break;
case 15: Threshold[Index] = Average[Index]>>THRESHOLD_6P25; break;
default: break;
}
// Button Pressed (no hysteresis provided)
if (RawData[Index] < (Average[Index] - Threshold[Index])){
switch(Index){
case 0: Buttons.BTN6 = 1; break; // The current button is pressed
case 1: Buttons.BTNB = 1; break; // Relay button pressed information to application
case 2: Buttons.BTN1 = 1; break;
case 3: Buttons.BTN2 = 1; break;
case 4: Buttons.BTN3 = 1; break;
case 5: Buttons.BTNA = 1; break;
case 6: Buttons.BTNSt = 1; break;
case 7: Buttons.BTN0 = 1; break;
case 8: Buttons.BTNSh = 1; break;
case 9: Buttons.BTND = 1; break;
case 10: Buttons.BTN7 = 1; break;
case 11: Buttons.BTN8 = 1; break;
case 12: Buttons.BTN9 = 1; break;
case 13: Buttons.BTNC = 1; break;
case 14: Buttons.BTN4 = 1; break;
case 15: Buttons.BTN5 = 1; break;
default: break;
}
}
// Button unpressed (hysteresis provided)
else{// if(RawData[Index] > (Average[Index] - Threshold[Index])){
switch(Index){
case 0: Buttons.BTN6 = 0; break; // The current button is unpressed
case 1: Buttons.BTNB = 0; break; // Relay button pressed information to application
case 2: Buttons.BTN1 = 0; break;
case 3: Buttons.BTN2 = 0; break;
case 4: Buttons.BTN3 = 0; break;
case 5: Buttons.BTNA = 0; break;
case 6: Buttons.BTNSt = 0; break;
case 7: Buttons.BTN0 = 0; break;
case 8: Buttons.BTNSh = 0; break;
case 9: Buttons.BTND = 0; break;
case 10: Buttons.BTN7 = 0; break;
case 11: Buttons.BTN8 = 0; break;
case 12: Buttons.BTN9 = 0; break;
case 13: Buttons.BTNC = 0; break;
case 14: Buttons.BTN4 = 0; break;
case 15: Buttons.BTN5 = 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.BTN1;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTN2;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTN3;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTNA;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTN4;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTN5;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTN6;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTNB;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTN7;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTN8;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTN9;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTNC;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTNSt;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTN0;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTNSh;
ButtonDataBuff=(ButtonDataBuff<<1)|Buttons.BTND;
if(ButtonData!=ButtonDataBuff){
if(ButtonData>ButtonDataBuff){
ButtonData=ButtonDataBuff=0;
}
ButtonData=ButtonDataBuff;
I2C_Packet.TxData[0]=ButtonData>>8;
I2C_Packet.TxData[1]=ButtonData;
PIC16F727_IRQ=1;
NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();
PIC16F727_IRQ=0;
}
}
//******************************************************************************************
void Initial_I2C_Slave(void)
{
// I2C Port Define
SCL_DIR = 1;
SDA_DIR = 1;
// I2C Register Define
SSPMSK = MULTI_ADDR;
SSPADD = MULTI_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 + -