找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9260|回复: 3
收起左侧

51单片机一个按键 长、按控制程序演示

[复制链接]
ID:99600 发表于 2015-12-25 22:17 | 显示全部楼层 |阅读模式
  1. /*-----------------------------------------------
  2.   名称:单个独立按键控制
  3.   编写:shifang
  4.   日期:2009.5
  5.   修改:无
  6.   内容:按键加减数字,多个数码管显示,使用定时器做数码管动态扫描 并区别长按短按效果,完全可以应用的实际生产中
  7. ------------------------------------------------*/
  8. #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义

  9. sbit KEY_ADD=P3^3;  //定义按键输入端口
  10. sbit KEY_DEC=P3^4;

  11. #define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换
  12. sbit LATCH1=P2^2;//定义锁存使能端口 段锁存
  13. sbit LATCH2=P2^3;//                 位锁存

  14. unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9
  15. unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
  16. unsigned char TempData[8]; //存储显示值的全局变量

  17. void DelayUs2x(unsigned char t);//函数声明
  18. void DelayMs(unsigned char t);
  19. void Display(unsigned char FirstBit,unsigned char Num);
  20. void Init_Timer0(void);
  21. /*------------------------------------------------
  22.                     主函数
  23. ------------------------------------------------*/
  24. void main (void)
  25. {
  26. unsigned char num=0,key_press_num;               
  27. KEY_ADD=1; //按键输入端口电平置高
  28. KEY_DEC=1;
  29. Init_Timer0();

  30. while (1)         //主循环
  31.   {

  32.   if(!KEY_ADD)  //如果检测到低电平,说明按键按下
  33.     {
  34.          DelayMs(10); //延时去抖,一般10-20ms
  35.      if(!KEY_ADD)     //再次确认按键是否按下,没有按下则退出
  36.            {
  37.            while(!KEY_ADD)
  38.             {
  39.                 key_press_num++;
  40.         DelayMs(10);           //10x200=2000ms=2s
  41.                 if(key_press_num==200) //大约2s
  42.                   {
  43.                    key_press_num=0;    //如果达到长按键标准
  44.                                //则进入长按键动作
  45.            while(!KEY_ADD)     //这里用于识别是否按
  46.                                                            //键还在按下,如果按
  47.                                              //下执行相关动作,否则退出
  48.                        {
  49.                                if(num<99)    //加操作
  50.                       num++;
  51.                                 //即时把显示数据处理,如果去掉下面2
  52.                 //句处理信息,实际上看不到渐变效果,
  53.                 //而是看到跳变效果
  54.                                 //用户可以自行屏蔽测试
  55.      //分解显示信息,如要显示68,则68/10=6  68%10=8
  56.                                 TempData[0]=dofly_DuanMa[num/10];  
  57.                     TempData[1]=dofly_DuanMa[num%10];
  58.                 DelayMs(50);//用于调节长按循环操作
  59.      //的速度,可以自行调整此值以便达到最佳效果
  60.                                 }
  61.                     }
  62.                 }
  63.       key_press_num=0;//防止累加造成错误识别
  64.                    if(num<99)    //加操作
  65.                   num++;
  66.            }
  67.         }

  68. if(!KEY_DEC)  //如果检测到低电平,说明按键按下
  69.     {
  70.          DelayMs(10); //延时去抖,一般10-20ms
  71.      if(!KEY_DEC) //再次确认按键是否按下,没有
  72.                   //按下则退出
  73.            {
  74.            while(!KEY_DEC)
  75.             {
  76.                 key_press_num++;
  77.         DelayMs(10);
  78.                 if(key_press_num==200) //大约2s
  79.                   {
  80.                    key_press_num=0;
  81.            while(!KEY_DEC)
  82.                        {
  83.                                if(num>0)  //减操作
  84.                        num--;
  85. //分解显示信息,如要显示68,则68/10=6  68%10=8
  86.                                 TempData[0]=dofly_DuanMa[num/10];  
  87.                     TempData[1]=dofly_DuanMa[num%10];
  88.                 DelayMs(50);
  89. //用于调节长按循环操作的速度
  90.                                 }
  91.                     }
  92.                 }
  93.       key_press_num=0;//防止累加造成错误识别
  94.                if(num>0)  //减操作
  95.                   num--;
  96.                  
  97.            }
  98.         }
  99. //分解显示信息,如要显示68,则68/10=6  68%10=8  
  100.            TempData[0]=dofly_DuanMa[num/10];
  101.            TempData[1]=dofly_DuanMa[num%10];
  102.           // Display(0,8); //显示全部8位
  103.      //主循环中添加其他需要一直工作的程序
  104.         
  105.   }
  106. }
  107. /*------------------------------------------------
  108. uS延时函数,含有输入参数 unsigned char t,无返回值
  109. unsigned char 是定义无符号字符变量,其值的范围是
  110. 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
  111. 长度如下 T=tx2+5 uS
  112. ------------------------------------------------*/
  113. void DelayUs2x(unsigned char t)
  114. {   
  115. while(--t);
  116. }
  117. /*------------------------------------------------
  118. mS延时函数,含有输入参数 unsigned char t,无返回值
  119. unsigned char 是定义无符号字符变量,其值的范围是
  120. 0~255 这里使用晶振12M,精确延时请使用汇编
  121. ------------------------------------------------*/
  122. void DelayMs(unsigned char t)
  123. {
  124.      
  125. while(t--)
  126. {
  127.      //大致延时1mS
  128.      DelayUs2x(245);
  129.          DelayUs2x(245);
  130. }
  131. }
  132. /*------------------------------------------------
  133. 显示函数,用于动态扫描数码管
  134. 输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示
  135. 如输入0表示从第一个显示。
  136. Num表示需要显示的位数,如需要显示99两位数值则该值输入2
  137. ------------------------------------------------*/
  138. void Display(unsigned char FirstBit,unsigned char Num)
  139. {
  140.       static unsigned char i=0;
  141.          

  142.            DataPort=0;   //清空数据,防止有交替重影
  143.        LATCH1=1;     //段锁存
  144.        LATCH1=0;

  145.        DataPort=dofly_WeiMa[i+FirstBit]; //取位码
  146.        LATCH2=1;     //位锁存
  147.        LATCH2=0;

  148.        DataPort=TempData[i]; //取显示数据,段码
  149.        LATCH1=1;     //段锁存
  150.        LATCH1=0;
  151.       
  152.            i++;
  153.        if(i==Num)
  154.               i=0;


  155. }
  156. /*------------------------------------------------
  157.                     定时器初始化子程序
  158. ------------------------------------------------*/
  159. void Init_Timer0(void)
  160. {
  161. TMOD |= 0x01;          //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响                     
  162. //TH0=0x00;              //给定初值
  163. //TL0=0x00;
  164. EA=1;            //总中断打开
  165. ET0=1;           //定时器中断打开
  166. TR0=1;           //定时器开关打开
  167. }
  168. /*------------------------------------------------
  169.                  定时器中断子程序
  170. ------------------------------------------------*/
  171. void Timer0_isr(void) interrupt 1
  172. {
  173. TH0=(65536-2000)/256;                  //重新赋值 2ms
  174. TL0=(65536-2000)%256;

  175. Display(0,8);

  176. }
复制代码


57-按键长按短按效果.zip

17.26 KB, 下载次数: 32, 下载积分: 黑币 -5

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的积分奖励!

查看全部评分

回复

使用道具 举报

ID:79544 发表于 2015-12-26 17:17 | 显示全部楼层
好贴学习啦谢谢分享
回复

使用道具 举报

ID:59300 发表于 2023-8-22 16:45 | 显示全部楼层
比较全面的代码,值得收藏
回复

使用道具 举报

ID:375055 发表于 2023-9-12 14:33 | 显示全部楼层
比较全面的代码,值得好好学习
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表