一、使用proteus绘制简单的电路图,用于后续仿真
二、编写程序
/********************************************************************************************************************
---- @Project: Independent-KEY
---- @File: main.c
---- @Edit: ZHQ
---- @Version: V1.0
---- @CreationTime: 20200507
---- @ModifiedTime: 20200507
---- @Description: 两个独立按键S1和S2,S1键作为加键。S2键做为减键。每按一次S1键则被设置参数uiSetNumber自加1。如果按住S1键不松手超过1秒钟,被设置参数uiSetNumber以每0.25秒的时间间隔往上自加1,一直加到20为止。每按一次S5键则被设置参数uiSetNumber自减1。如果按住S2键不松手超过1秒钟,被设置参数uiSetNumber以每0.25秒的时间间隔往下自减1,一直减到0为止。当被设置参数uiSetNumber小于10的时候,LED灯灭;当大于或者等于10的时候,LED灯亮。
---- 单片机:AT89C52
********************************************************************************************************************/
#include "reg52.h"
/*——————宏定义——————*/
#define FOSC 11059200L
#define T1MS (65536-FOSC/12/1000) /*1ms timer calculation method in 12Tmode*/
#define const_voice_short 80 /*蜂鸣器短叫的持续时间*/
#define const_key_time1 60 /*按键去抖动延时的时间*/
#define const_key_time2 60 /*按键去抖动延时的时间*/
#define const_time_0_25s 200 /*0.25秒钟的时间需要的定时中断次数*/
#define const_time_1s 800 /*1秒钟的时间需要的定时中断次数*/
/*——————变量函数定义及声明——————*/
/*定义按键S1*/
sbit Key_S1 = P0^0;
/*定义按键S2*/
sbit Key_S2 = P0^1;
/*定义蜂鸣器*/
sbit BUZZER = P2^7;
/*定义LED*/
sbit LED = P3^5;
unsigned char ucKeySec = 0; /*被触发的按键编号*/
unsigned int uiKeyTimeCnt1 = 0; /*按键去抖动延时计数器*/
unsigned char ucKeyLock1 = 0; /*按键触发后自锁的变量标志*/
unsigned char uiKeyCtntyCnt1=0; /*按键连续触发的间隔延时计数器*/
unsigned int uiKeyTimeCnt2 = 0; /*按键去抖动延时计数器*/
unsigned char ucKeyLock2 = 0; /*按键触发后自锁的变量标志*/
unsigned char uiKeyCtntyCnt2=0; /*按键连续触发的间隔延时计数器*/
unsigned int uiVoiceCnt = 0; /*蜂鸣器鸣叫的持续时间计数器*/
unsigned int uiSetNumber=0; /*设置的数据*/
/**
* @brief 定时器0初始化函数
* @param 无
* @retval 初始化T0
**/
void Init_T0(void)
{
TMOD = 0x01; /*set timer0 as mode1 (16-bit)*/
TL0 = T1MS; /*initial timer0 low byte*/
TH0 = T1MS >> 8; /*initial timer0 high byte*/
}
/**
* @brief 外围初始化函数
* @param 无
* @retval 初始化外围
**/
void Init_Peripheral(void)
{
ET0 = 1;/*允许定时中断*/
TR0 = 1;/*启动定时中断*/
EA = 1;/*开总中断*/
}
/**
* @brief 初始化函数
* @param 无
* @retval 初始化单片机
**/
void Init(void)
{
Init_T0();
BUZZER = 1;
}
/**
* @brief 扫描按键函数
* @param 无
* @retval 独立按键扫描的详细过程:
* 第一步:平时没有按键被触发时,按键的自锁标志,去抖动延时计数器,以及时间间隔延时计数器一直被清零。
* 第二步:一旦有按键被按下,去抖动延时计数器开始在定时中断函数里累加,在还没累加到
* 阀值const_key_time1时,如果在这期间由于受外界干扰或者按键抖动,而使
* IO口突然瞬间触发成高电平,这个时候马上把延时计数器uiKeyTimeCnt1
* 清零了,这个过程非常巧妙,非常有效地去除瞬间的杂波干扰。
* 以后凡是用到开关感应器的时候,都可以用类似这样的方法去干扰。
* 第三步:如果按键按下的时间超过了阀值const_key_time1,则触发按键,把编号ucKeySec赋值。
* 同时,马上把自锁标志ucKeyLock1置位,防止按住按键不松手后一直触发。
* 第四步:如果此时触发了一次按键后,一直不松手,去抖动延时计时器继续累加,直到超过了1秒钟。进入连续触发模式的程序
* 第五步:在连续触发模式的程序中,连续累加延时计数器开始累加,每0.25秒就触发一次。
* 第六步:等按键松开后,自锁标志ucKeyLock1和两个延时计时器及时清零,为下一次自锁做准备。
**/
void Key_Scan(void)
{
/*扫描S1*/
if(Key_S1 == 1) /*如果按键没有被按下(高电平),将一些标志位及时清零*/
{
ucKeyLock1 = 0;/*自锁标志位清0*/
uiKeyTimeCnt1 = 0;/*按键去抖动延时计数器清零*/
uiKeyCtntyCnt1 = 0; /*连续累加的时间间隔延时计数器清零*/
}
else if(ucKeyLock1 == 0) /*如果有按键按下,且是第一次按下*/
{
uiKeyTimeCnt1 ++;
if(uiKeyTimeCnt1 > const_key_time1)/*判定按下*/
{
uiKeyTimeCnt1 = 0;
ucKeyLock1 = 1;
ucKeySec = 1; /*触发S1*/
}
}
else if(uiKeyTimeCnt1 < const_time_1s)/*按键已按下,按键去抖动延时计数器自增到1s*/
{
uiKeyTimeCnt1 ++;
}
else/*按住累加到1秒后仍然不放手,这个时候进入有节奏的连续触发*/
{
uiKeyCtntyCnt1 ++;/*连续触发延时计数器累加*/
if(uiKeyCtntyCnt1 > const_time_0_25s)/*按住没松手,每0.25秒就触发一次*/
{
uiKeyCtntyCnt1 = 0;
ucKeySec = 1; /*触发S1*/
}
}
/*扫描S2*/
if(Key_S2 == 1) /*如果按键没有被按下(高电平),将一些标志位及时清零*/
{
ucKeyLock2 = 0;/*自锁标志位清0*/
uiKeyTimeCnt2 = 0;/*按键去抖动延时计数器清零*/
uiKeyCtntyCnt2 = 0; /*连续累加的时间间隔延时计数器清零*/
}
else if(ucKeyLock2 == 0) /*如果有按键按下,且是第一次按下*/
{
uiKeyTimeCnt2 ++;
if(uiKeyTimeCnt2 > const_key_time2)/*判定按下*/
{
uiKeyTimeCnt2 = 0;
ucKeyLock2 = 1;
ucKeySec = 2; /*触发S2*/
}
}
else if(uiKeyTimeCnt2 < const_time_1s)/*按键已按下,按键去抖动延时计数器自增到1s*/
{
uiKeyTimeCnt2 ++;
}
else/*按住累加到1秒后仍然不放手,这个时候进入有节奏的连续触发*/
{
uiKeyCtntyCnt2 ++;/*连续触发延时计数器累加*/
if(uiKeyCtntyCnt2 > const_time_0_25s)/*按住没松手,每0.25秒就触发一次*/
{
uiKeyCtntyCnt2 = 0;
ucKeySec = 2; /*触发S2*/
}
}
}
/**
* @brief 按键服务函数
* @param 无
* @retval 根据扫描得到的值,进行数据处理
**/
void key_Service(void)
{
switch(ucKeySec)
{
case 1: /*S1,连续加*/
uiSetNumber ++;/*被设置的参数连续往上加*/
if(uiSetNumber > 20)/*最大20*/
{
uiSetNumber = 20;
}
uiVoiceCnt = const_voice_short; /*蜂鸣器短叫*/
ucKeySec = 0; /*响应按键服务处理程序后,按键编号清零,避免一致触发*/
break;
case 2: /*S2,连续减*/
uiSetNumber --;/*被设置的参数连续往下减*/
if(uiSetNumber > 20)/*最小0,0 - 1 = 0xff > 20*/
{
uiSetNumber = 0;
}
uiVoiceCnt = const_voice_short; /*蜂鸣器短叫*/
ucKeySec = 0; /*响应按键服务处理程序后,按键编号清零,避免一致触发*/
break;
}
}
/**
* @brief LED函数
* @param 无
* @retval 控制LED亮灭
**/
void Led_Run(void) /*led灯的应用程序*/
{
if(uiSetNumber < 10) /*如果被设置的参数uiSetNumber小于10,LED灯则灭。否则亮。*/
{
LED = 0; /*灭*/
}
else
{
LED = 1; /*亮*/
}
}
/**
* @brief 定时器0中断函数
* @param 无
* @retval 无
**/
void ISR_T0(void) interrupt 1
{
TF0 = 0; /*清除中断标志*/
TR0 = 0; /*关中断*/
/*扫描按键*/
Key_Scan();
if(0 != uiVoiceCnt)
{
uiVoiceCnt --;
BUZZER = 0;
}
else
{
BUZZER = 1;
}
TL0 = T1MS; /*initial timer0 low byte*/
TH0 = T1MS >> 8; /*initial timer0 high byte*/
TR0 = 1; /*开中断*/
}
/**
* @brief 延时函数
* @param 无
* @retval 无
**/
void Delay_Long(unsigned int uiDelayLong)
{
unsigned int i;
unsigned int j;
for(i=0;i for(j=0;j<500;j++) /*内嵌循环的空指令数量*/ { ; /*一个分号相当于执行一条空语句*/ } } } /*——————主函数——————*/ /** * @brief 主函数 * @param 无 * @retval 实现LED灯闪烁 **/ void main() { /*单片机初始化*/ Init(); /*延时,延时时间一般是0.3秒到2秒之间,等待外围芯片和模块上电稳定*/ Delay_Long(100); /*单片机外围初始化*/ Init_Peripheral(); while(1) { /*按键服务函数*/ key_Service(); /*LED函数*/ Led_Run(); } } 三、仿真实现
上一篇:51单片机实现按住一个独立按键不松手的加速匀速触发
下一篇:最后一页
推荐阅读
史海拾趣
随着电子行业的不断变革,Able Systems公司也面临着新的挑战。例如,新技术的出现、市场需求的变化等都对公司的发展提出了新的要求。然而,Able Systems始终保持着敏锐的市场洞察力,不断调整战略,积极应对挑战。通过不断创新和改进,公司成功克服了各种困难,保持了稳健的发展态势。
面对日益复杂的军事需求和快速发展的技术环境,DLA积极推进技术创新和数字化转型。通过引入云计算、大数据、人工智能等先进技术,DLA实现了对全球供应链的实时监控和智能调度,大大提高了后勤保障的效率和准确性。同时,DLA还加强了对新型军事装备的研发和保障能力,确保美军在现代化战争中保持领先地位。
随着智能手机和IoT市场的快速发展,AGM敏锐地捕捉到这一机遇。公司不失时机地推出了一款专用于智能手机和IoT的FPGA芯片,并通过了三星严格的供应商测试认证。这款芯片成为三星Galaxy手机里除Lattice之外的唯一备选FPGA器件,实现了国内FPGA公司出口零的突破,具有特殊的战略意义。这一成功不仅展示了AGM在可编程逻辑技术领域的实力,也为公司进一步拓展智能手机和IoT市场打下了坚实基础。
请大家看下下面打问号几行代码,抛开其功能不说,真的是奇怪了,我都看了又看,头都大了,就是不知道为什么,请朋友们指点下 #include<reg52.h> &nbs ...… 查看全部问答∨ |
|
STM32的驱动库好用吗?效率高吗?优化的吗?准备上STM32 N多年没买过开发板了,也没用过仿真器了。都是用软件编译调试好,直接ISP,然后通过串口命令开启调试信息的输出。 昨天买了块STM32F103全功能型开发板,他们的办事效率真低(深圳到广州通常当 ...… 查看全部问答∨ |
请问用哪款TI的DSP板做图像处理比较好,要可以和Matlab连接使用,且可通过Real Time Work Shop工具箱自动生成代码,要是版本新一些就更好了 最近需要买一块板子,请大家多多给建议啊 谢谢… 查看全部问答∨ |
求IAR Embedded Workbench for MCS-51 完整版 各位高手,小弟求IAR Embedded Workbench for MCS-51完整版,有哪位高人有,能否分享一下。我的邮箱jinghongchen@126.com… 查看全部问答∨ |