|
程序功能:
1.上电,按按键进入学习目标遥控器的用户码,在没有遥控器信号到来之前,LED慢闪状态,当有遥控器信号到来和学习成功,LED快闪3下,表示学习成功;
2.断电,再上电,按一下遥控器,LED亮,再按一下遥控器,LED灭,如此循环;
3.长按按键,可以清除EEPROM里存的遥控器用户码(程序做的是:存3个遥控器,如果学习第4个,会把第一个遥控器的用户码代替,以此类推);
这个程序用到EEPROM读写,按键检测,timer0和timer2的使用;能让大家快速上手这款性价比超高的MCU(价格很爆炸,性能很稳定);
以下是程序代码:
#include "pic.h"
#include "pic16f685.h"
#define _XTAL_FREQ 16000000 //4T
#define COM_LED RA0
#define KEY_PORT RA1
#define KEY_VALUE_LEARN 1
#define KEY_VALUE_CLEAR 2
bit Flag_Timer0Overflow=0,Flag_KeyPress_1=0,Flag_KeyPress_2=0,Flag_IRDataHeadCome=0,Flag_IRDataHeadTrue=0,Flag_IRReceiveDone=0;
bit Flag_LearnMode=0,Flag_NeedRefreshEEPROM=0,Flag_NeedRefreshIndex=0,Flag_LearnOrClearDone=0,Flag_NeedClearEEPROM=0;
unsigned char uc8_ReadEEPROMIndex=0,uc8_ReadBuffer[4]={0,0,0,0};
unsigned char uc8_KeyScanCount=0,uc8_KeyValue=0;
unsigned int ui16_KeyPressCount=0;
unsigned char uc8_RefreshCount=0,uc8_LearnDoneFlashCount=0,uc8_LedFlashCount=0;
unsigned int ui16_CancelLearnModeCount=0,ui16_WaitIRDataComeCount=0;
unsigned char uc8_ClearCount=0,uc8_ClearIndex=0;
volatile unsigned char uc8_IRDataBitWidth=0,uc8_IRDataIndex=0,uc8_IRDataBitCount=0,uc8_IRDataBuffer[4]={0,0,0,0};
//===============Interrupt_Service_Routine===============
void interrupt ISR(void)
{
if(INTE&&INTF)
{
INTF = 0;
if(Flag_IRDataHeadCome==0)
{
TMR2 = 0;
TMR2IF = 0;
TMR2IE = 1;
TMR2ON = 1;
Flag_IRDataHeadCome = 1;
Flag_IRDataHeadTrue = 0;
Flag_IRReceiveDone = 0;
uc8_IRDataBitWidth = 0;
}
else if(Flag_IRDataHeadCome==1)
{
if(Flag_IRDataHeadTrue==0)
{
if((uc8_IRDataBitWidth>=130)&&(uc8_IRDataBitWidth<=140))
{
Flag_IRDataHeadTrue = 1;
uc8_IRDataIndex = 0;
uc8_IRDataBitCount = 0;
uc8_IRDataBuffer[0] = 0;
uc8_IRDataBuffer[1] = 0;
uc8_IRDataBuffer[2] = 0;
uc8_IRDataBuffer[3] = 0;
}
else
{
TMR2ON = 0;
TMR2IE = 0;
TMR2IF = 0;
Flag_IRDataHeadCome = 0;
}
}
else
{
if((uc8_IRDataBitWidth>=9)&&(uc8_IRDataBitWidth<=13))
{
uc8_IRDataBitCount++;
if(uc8_IRDataBitCount>=8)
{
uc8_IRDataBitCount = 0;
uc8_IRDataIndex++;
if(uc8_IRDataIndex>=4)
{
uc8_IRDataIndex = 0;
Flag_IRReceiveDone = 1;
TMR2ON = 0;
TMR2IE = 0;
TMR2IF = 0;
Flag_IRDataHeadCome = 0;
Flag_IRDataHeadTrue = 0;
}
}
}
else if((uc8_IRDataBitWidth>=20)&&(uc8_IRDataBitWidth<=24))
{
uc8_IRDataBuffer[uc8_IRDataIndex] = uc8_IRDataBuffer[uc8_IRDataIndex]|(1<<uc8_IRDataBitCount);
uc8_IRDataBitCount++;
if(uc8_IRDataBitCount>=8)
{
uc8_IRDataBitCount = 0;
uc8_IRDataIndex++;
if(uc8_IRDataIndex>=4)
{
uc8_IRDataIndex = 0;
Flag_IRReceiveDone = 1;
TMR2ON = 0;
TMR2IE = 0;
TMR2IF = 0;
Flag_IRDataHeadCome = 0;
Flag_IRDataHeadTrue = 0;
}
}
}
else
{
TMR2ON = 0;
TMR2IE = 0;
TMR2IF = 0;
Flag_IRDataHeadCome = 0;
Flag_IRDataHeadTrue = 0;
}
}
uc8_IRDataBitWidth = 0;
}
}
else if(TMR2IE&&TMR2IF)
{
TMR2IF = 0;
uc8_IRDataBitWidth++;
}
else if(T0IE&&T0IF)
{
T0IF = 0;
Flag_Timer0Overflow = 1;
}
}
//======================Subroutine=======================
/***函数功能:器件初始化***/
void Device_Initialize_Pro(void)
{
PCON = 0b00000011;
OSCCON = 0b01110000; //WDT 32KHZ IRCF=111=16MHZ/4=4MHZ,0.25us/T
WDTCON = 0b00000001;
INTCON = 0b00000000; //disable global interrupt
PIE1 = 0b00000000;
PIR1 = 0b00000000;
PORTA = 0b00000001;
TRISA = 0b00000110;
WPUA = 0b00000000;
IOCA = 0b00000000;
PORTC = 0b00000000;
TRISC = 0b11000000;
OPTION = 0b00000011; //TINER0 MODE,PSA=1:16 TIMER0 RATE
TMR0 = 0;
PR0 = 250;
TMR2 = 0;
PR2 = 100;
T2CON = 0b00000001; //PSA=1:4 TIMER2 RATE
CMCON0 = 0b00000111;
VRCON = 0b00000000;
}
/***函数功能:器件初始化***/
/***函数功能:读EEPROM一个字节数据***/
unsigned char Read_8bit_Data_Eeprom_Pro(unsigned char EepromAddress)
{
unsigned char EepromData;
CLRWDT();
EEADR = EepromAddress;
RD = 1;
EepromData = EEDAT;
RD = 0;
return(EepromData);
}
/***函数功能:读EEPROM一个字节数据***/
/***函数功能:写EEPROM一个字节数据***/
void Write_8bit_Data_Eeprom_Pro(unsigned char EepromAddress,unsigned char EepromData)
{
CLRWDT();
EEADR = EepromAddress;
EEDAT = EepromData;
EECON1 = 0x34;
WR = 1;
while(WR==1) CLRWDT();
WREN1 = 0;
WREN2 = 0;
WREN3 = 0;
}
/***函数功能:写EEPROM一个字节数据***/
/***函数功能:按键扫描***/
void Key_Scan(void)
{
CLRWDT();
if(KEY_PORT==0)
{
if(Flag_KeyPress_1==0)
{
if(ui16_KeyPressCount>=10) Flag_KeyPress_1 = 1;
else ui16_KeyPressCount++;
}
else if(Flag_KeyPress_1==1)
{
if(Flag_KeyPress_2==0)
{
if(ui16_KeyPressCount>=300)
{
ui16_KeyPressCount = 0;
Flag_KeyPress_2 = 1;
uc8_KeyValue = KEY_VALUE_CLEAR;
}
else ui16_KeyPressCount++;
}
}
}
else if(KEY_PORT==1)
{
if(Flag_KeyPress_1==0)
{
ui16_KeyPressCount = 0;
Flag_KeyPress_1 = 0;
Flag_KeyPress_2 = 0;
}
else if(Flag_KeyPress_1==1)
{
if(Flag_KeyPress_2==0)
{
uc8_KeyValue = KEY_VALUE_LEARN;
ui16_KeyPressCount = 0;
Flag_KeyPress_1 = 0;
Flag_KeyPress_2 = 0;
}
else if(Flag_KeyPress_2==1)
{
ui16_KeyPressCount = 0;
Flag_KeyPress_1 = 0;
Flag_KeyPress_2 = 0;
}
}
}
}
/***函数功能:按键扫描***/
/***函数功能:Timer0溢出服务程序***/
void Timer0_Overflow_SR(void) //1毫秒溢出1次
{
CLRWDT();
/***按键扫描***/
uc8_KeyScanCount++;
if(uc8_KeyScanCount>=10)
{
uc8_KeyScanCount = 0;
Key_Scan();
}
/***按键扫描***/
/***学习模式计***/
if(Flag_LearnMode==1)
{
/***学习模式等待数据到来LED闪烁***/
ui16_WaitIRDataComeCount++;
if(ui16_WaitIRDataComeCount>=800)
{
ui16_WaitIRDataComeCount = 0;
COM_LED = ~COM_LED;
}
/***取消学习模式计时***/
ui16_CancelLearnModeCount++;
if(ui16_CancelLearnModeCount>=8000)
{
ui16_CancelLearnModeCount = 0;
Flag_LearnMode = 0;
COM_LED = 1;
}
/***取消学习模式计时***/
}
/***更新EEPROM数据***/
if(Flag_NeedRefreshEEPROM==1)
{
uc8_RefreshCount++;
if(uc8_RefreshCount>=20)
{
uc8_RefreshCount = 0;
if(Flag_NeedRefreshIndex==0)
{
Write_8bit_Data_Eeprom_Pro(uc8_ReadBuffer[3],uc8_IRDataBuffer[0]);
uc8_ReadBuffer[3]++;
Flag_NeedRefreshIndex = 1;
}
else if(Flag_NeedRefreshIndex==1)
{
Write_8bit_Data_Eeprom_Pro(3,uc8_ReadBuffer[3]);
Flag_LearnOrClearDone = 1;
Flag_NeedRefreshEEPROM = 0;
COM_LED = 0;
}
}
}
/***更新EEPROM数据***/
/***清除EEPROM数据***/
if(Flag_NeedClearEEPROM==1)
{
uc8_ClearCount++;
if(uc8_ClearCount>=20)
{
uc8_ClearCount = 0;
Write_8bit_Data_Eeprom_Pro(uc8_ClearIndex,0);
uc8_ClearIndex++;
if(uc8_ClearIndex>=4)
{
uc8_ClearIndex = 0;
Flag_NeedClearEEPROM = 0;
Flag_LearnOrClearDone = 1;
COM_LED = 0;
}
}
}
/***清除EEPROM数据***/
/***学习或清除完毕LED快闪3次***/
if(Flag_LearnOrClearDone==1)
{
uc8_LearnDoneFlashCount++;
if(uc8_LearnDoneFlashCount>=150)
{
uc8_LearnDoneFlashCount = 0;
COM_LED = ~COM_LED;
uc8_LedFlashCount++;
if(uc8_LedFlashCount>=6)
{
uc8_LedFlashCount = 0;
COM_LED = 1;
Flag_LearnOrClearDone = 0;
}
}
}
/***学习或清除完毕LED快闪3次***/
}
/***函数功能:Timer0溢出服务程序***/
/**函数功能:按键服务程序**/
void Key_SR(void)
{
if(uc8_KeyValue==KEY_VALUE_LEARN)
{
Flag_LearnMode = 1;
COM_LED = 0;
ui16_CancelLearnModeCount = 0;
ui16_WaitIRDataComeCount = 0;
Flag_NeedRefreshEEPROM = 0;
}
else if(uc8_KeyValue==KEY_VALUE_CLEAR)
{
Flag_NeedClearEEPROM = 1;
uc8_ClearIndex = 0;
uc8_ClearCount = 0;
}
}
/**函数功能:按键服务程序**/
/***函数功能:无线接收到数据服务程序***/
void IR_Receive_SR(void)
{
CLRWDT();
if(((uc8_IRDataBuffer[0]&uc8_IRDataBuffer[1])==0)&&((uc8_IRDataBuffer[2]&uc8_IRDataBuffer[3])==0))
{
if(Flag_LearnMode==1)
{
Flag_LearnMode = 0;
Flag_NeedRefreshEEPROM = 1;
Flag_NeedRefreshIndex = 0;
Flag_LearnOrClearDone = 0;
uc8_RefreshCount = 0;
}
else if(Flag_LearnMode==0)
{
if(uc8_IRDataBuffer[0]==uc8_ReadBuffer[0])
{
if(uc8_IRDataBuffer[3]>0) COM_LED = ~COM_LED;
}
else if(uc8_IRDataBuffer[0]==uc8_ReadBuffer[1])
{
if(uc8_IRDataBuffer[3]>0) COM_LED = ~COM_LED;
}
else if(uc8_IRDataBuffer[0]==uc8_ReadBuffer[2])
{
if(uc8_IRDataBuffer[3]>0) COM_LED = ~COM_LED;
}
}
}
}
//=======================MainRoutine======================
void main(void)
{
Device_Initialize_Pro();
for(uc8_ReadEEPROMIndex=0;uc8_ReadEEPROMIndex<4;uc8_ReadEEPROMIndex++)
{
uc8_ReadBuffer[uc8_ReadEEPROMIndex] = Read_8bit_Data_Eeprom_Pro(uc8_ReadEEPROMIndex);
CLRWDT();
__delay_us(100);
CLRWDT();
}
if(uc8_ReadBuffer[3]>=3)
{
uc8_ReadBuffer[3] = 0;
Write_8bit_Data_Eeprom_Pro(3,0);
}
asm("nop");
T0IF = 0;
T0IE = 1;
asm("nop");
INTF = 0;
INTEDG = 0;
INTE = 1;
PEIE = 1;
GIE = 1;
while(1)
{
CLRWDT();
/***Timer0溢出服务程序***/
if(Flag_Timer0Overflow)
{
Timer0_Overflow_SR();
Flag_Timer0Overflow = 0;
}
/***Timer0溢出服务程序***/
/***按键服务程序***/
if(uc8_KeyValue)
{
Key_SR();
uc8_KeyValue = 0;
}
/***按键服务程序***/
/***红外接收服务程序***/
if(Flag_IRReceiveDone==1)
{
IR_Receive_SR();
Flag_IRReceiveDone = 0;
}
/***红外接收服务程序***/
}
}
a.配置位图(PIC的配置位是可以在程序里设置,MS的要自己在编译的时候填配置位表格):
b.原理图:
c.规格书:
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
如果想吃一顿饺子,就得从冰箱里取出肉,剁馅儿,倒面粉、揉面、醒面,擀成皮儿,下锅……
一整个繁琐流程,就是为了出锅时那一嘴滚烫流油的热饺子。
如果这个过程,禁不住饿,零食下肚了,饺子出锅时也就不香了……《非诚勿扰3》
|