⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main_wheelkey 16f726.c

📁 基于PIC16F726芯片开发的例程,集合常用的功能.
💻 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 + -