高性价比两路开关设计兼容PIC10F202单片机程序
[复制链接]
两路开关设计可以采用PIC10F202单片机设计,英锐恩分享的是采用完全兼容PIC10F202单片机的EN8F202,打造高性价比的两路开关程序设计,EN8F202采用精简指令架构,仅有36 条单字/ 单周期指令。除程序跳转指令为两个周期外的所有其他指令都是单周期的。
兼容PIC10F202的EN8F202的程序通过检测GP0管脚的有效按键长短,循环翻转GP2和GP1管脚的输出电平高低。 每检测到一个短按键,则对GP2管脚输出电平进行一次翻转,每检测到一个长按键, 则对GP1管脚输出电平进行一次翻转。
PIC_200_202.c
(6.8 KB, 下载次数: 1)
//=======================================用户配置区,供用户修改===========================================
#define TIME2 1000 //长按键时间设置,单位ms ,1000 = 1s 范围:1~10s
//=========================================================================================================
//************************************ 以下为代码区,请勿改动! ***************************************** //************************************ 以下为代码区,请勿改动! ***************************************** //************************************ 以下为代码区,请勿改动! ***************************************** //************************************ 以下为代码区,请勿改动! ***************************************** //************************************ 以下为代码区,请勿改动! ***************************************** //************************************ 以下为代码区,请勿改动! ***************************************** //************************************ 以下为代码区,请勿改动! *****************************************
//=============================================硬件连接示意=============================================== // // ___短 _ 长 _______ // |_| |_________| PIC10F200/202 // +---------+ // KEY 长/短按键 ---|GP0 GP3|--- // | | // |GND VDD| // | | __ ___ // 长按键翻转输出 ---|GP1 GP2|---短按键翻转输出 _| |____| |____ // +---------+ // __________ _____________ // _| |___________| |____ // //-------------------------------------------------------------------------------------------------------- /*
长/短按键IO口电平翻转程序
说明:1.该程序通过检测GP0管脚的有效按键长短,循环翻转GP2和GP1管脚的输出电平高低。 每检测到一个短按键,则对GP2管脚输出电平进行一次翻转,每检测到一个长按键, 则对GP1管脚输出电平进行一次翻转。
2.按键是带有状态机的键盘扫描程序,可有效对按键消抖,抗干扰能力极强。 3.长按键的时间可通过程序顶端的参数进行方便的设置,以满足现场需求。
4.GP1、GP2在单片机默认状态和复位后输出电平为低。
5.待机功耗为400uA(@5V),长按键功耗为500uA(@5V)。
6.已启用内部弱上拉,按键可以不加上拉电阻,如果要保证信号可靠,可以加上拉电阻, 建议选择>=100K的电阻,以降低长时间按下按键在电阻上的功耗。 */ //========================================================================================================= #include //本代码可支持单片机型号:PIC10F200/202(可使用兼容芯片EN8F202,无需修改程序完全兼容)#define Key_Read_T 25 //等间隔读取键值,单位ms #define KEY_IO GP0 //按键信号输入 #define Short_Out GP1 //短按按键响应数出口 bit short_out; //记录Short_Out当前状态 bit short_IF; //短按响应标志 #define Long_Out GP2 //长按按键响应数出口 bit long_out; //记录Long_Out当前状态 bit long_IF; //长按响应标志 unsigned char KEY_State=0; /*按键的状态变量*/ #define NOKEY 0 #define PUSH_KEY 1 #define LONG_PUSH 2 #define INITIAL_25MS 161 //相对于本系统与定时器时钟,本数据为固定值。定时器增计数,计数周期为256us,计97个数约为25mS。256-97+2=161 /**************************************************************************** * 名 称:Key_ScanIO() * 功 能:扫描键盘IO口并判断按键事件 * 入口参数:Ticklong:长按键有效时长,单位ms * 出口参数:无 * 说 明: 该函数需要每隔25(Key_Read_T)ms,调用一次。最好放在定时中断内执行。 如果中断间隔太长,可能丢键;间隔太短不能消除抖动。 ****************************************************************************/ void Key_ScanIO(int Ticklong) { static unsigned int KeyTimerS; //===============================按键======================================== if(KEY_State==PUSH_KEY) KeyTimerS++; /*定时器,时间间隔25ms*/ else KeyTimerS=0; switch(KEY_State) //根据按键的状态决定程序分支 { case NOKEY: //------------------在未按键状态下-------------------------- { //若键被按下,按键状态变为"短按状态"。 if(KEY_IO==0) KEY_State=PUSH_KEY; break; } case PUSH_KEY: //-------------按键处于"短按状态"时------------------------ { if(KEY_IO!=0) //若键被释放,认为是一次短按键 { KEY_State=NOKEY; //并回到"未按下状态" short_IF = 0; long_IF = 0; } else if(KeyTimerS>Ticklong) //若按键时间超过Ticks毫秒,认为是一次长按键, { KEY_State=LONG_PUSH; // 按键状态变为"长按状态" } break;
} case LONG_PUSH: //------------按键处于"长按状态"时-------------------- { if(KEY_IO!=0) //若键被释放,回到未按键状态 { KEY_State=NOKEY; short_IF = 0; long_IF = 0; } break; } } }
/**************************************************************************** * 名 称:Key_Answer() * 功 能:根据按键状态作出响应,控制IO管脚输出电平翻转 * 入口参数:Ticklong:长按键有效时长,单位ms * 出口参数:无 ****************************************************************************/ void Key_Answer(void)
{ if((KEY_State==PUSH_KEY)&&(short_IF == 0)) { short_out = ~short_out; Short_Out = short_out; short_IF = 1; } if((KEY_State==LONG_PUSH)&&(long_IF == 0)) { long_out = ~long_out; Long_Out = long_out; long_IF = 1; } }
/************************************************************************************** 名 称:main() 功 能:主程序 入口参数:无 出口参数:无 ***************************************************************************************/
void main() {
//设置时钟周期Fosc = 4MHz,系统时钟,无法设置 OPTION = 0x97; //复位值0xFF。TIMER0的时钟源是Fosc/4,1us。TIMER0 256预分频,256us // CMCON0 = 0xE1;
TRISGPIO = 0x09; //GP1、GP2配置为输出。0为输出,1为输入 short_out = 0; Short_Out = short_out; long_out = 0; Long_Out = long_out; //为输出赋初值
TMR0 = INITIAL_25MS; //增计数,计数周期为256us,计97个数约为25mS。256-125+2=97
while(1) { #asm CLRWDT #endasm
if(TMR0 < INITIAL_25MS) //1ms 进入1次 { TMR0 = INITIAL_25MS; //增计数,计数周期为256us,计97个数约为25mS。256-125+2=97 Key_ScanIO(TIME2/Key_Read_T);//判断按键值 Key_Answer(); //根据键值控制输出IO电平翻转 }
}
}
//====================================================代码结束!=================================================
|