数码之家

 找回密码
 立即注册
搜索
查看: 2248|回复: 9

[C51] 大神帮增加一下按键和定时的程序

[复制链接]
发表于 2019-6-13 22:43:30 | 显示全部楼层 |阅读模式
500家元
现在程序是上电默认开机并运行了的,但想增加一些功能
增加:上电默认不开机,长按键KEY约2秒再开机,并运行SRL(),短按切换到SR(),只要是短按就来回切换,但任何状态下长按开与关机
          启动后,运行1小时自动关机
  1. #include "stc15w.h"                       
  2. #include <intrins.H>                      //函数运算头文件
  3. #define uint unsigned int                 //宏定义变量0-6553
  4. #define uchar unsigned char               //宏定义变量0-255
  5. #define     MAIN_Fosc       11059200L     //定义主时钟

  6. /*定义ADC参数*/

  7. #define ADC_POWER   0x80                //ADC power control dit (宏定义ADC电源控制位)1000 0000
  8. #define ADC_FLAG    0x10                //ADC complete flag (宏定义ADC完成标志位)    0001 0000
  9. #define ADC_START   0x08                //ADC start control dit (宏定义ADC启动控制位)0000 1000
  10. #define ADC_SPEEDLL 0x00                //420 clocks (宏定义420时钟)速度控制         0000 0000
  11. #define ADC_SPEEDL  0x20                //280 clocks (宏定义280时钟)速度控制         0001 0000
  12. #define ADC_SPEEDH  0x40                //140 clocks (宏定义140时钟)速度控制         0010 0000
  13. #define ADC_SPEEDHH 0x60                //070 clocks (宏定义70时钟)速度控制          0011 0000
  14. /*定义接口*/
  15. sbit out=P1^1;                          //驱动端口定义
  16. sbit key = P2^4;                        //定义KEY接口
  17. sbit ledL = P4^2;                       //定义低档位接口
  18. sbit ledH = P4^3;                       //定义高档位接口
  19. void InitADC();                         //初始化ADC子程序声明
  20. uchar zhADC(uchar ch);                  //ADC 转换子程序声明
  21. void delayms(uint k);                   //1ms延时子程序声明
  22. void SR();                              //执行AD转换结果子程序声明H
  23. void SRL();                             //执行AD转换结果子程序声明L
  24. uchar n = 0;                            //按键初始化

  25. /*接口模式初始化*/
  26. void port_mode()                        
  27. {
  28.    P2M1=0x00; P2M0=0x00;                // P2 P4灯和按键端口模式, 准双向口0x00
  29.    P4M1=0x00; P4M0=0x00;
  30.    P1M1 = 0x01;                         //P1.0高阻 P1.1强推挽:0000 0001 ADC输入高阻、继电器强上拉
  31.    P1M0 = 0x02;                         //P1.0高阻 P1.1强推挽:0000 0010 ADC输入高阻、继电器强上拉
  32.    out=0;                               //驱动初始化0
  33. }

  34. /*void delay()                           //延时函数1
  35. {
  36.   uint  i, j;
  37.   for(i = 0; i < 100; i++)  
  38.   for(j = 0; j < 500; j++);
  39. }
  40. */
  41. void readkey(void)                   //按键读取函数
  42. {
  43.   uchar  i, j;
  44.   if(!key)  
  45.     {
  46.      for(i = 0; i < 10; i++)
  47.      for(j = 0; j < 120; j++);       //延时消抖
  48.   if(!key)  
  49.     {
  50.      while(!key);            //等待按键释放
  51.      n++;
  52.      n %= 2;                //n = 0~2
  53.      }
  54.      }
  55.   }

  56. /*----------------------------
  57.    初始化ADC
  58. -----------------------------*/
  59. void InitADC()
  60. {
  61.     P1ASF=0x01;                            //设置P1.0端口作为模拟输入
  62.     ADC_RES=0;                             //清除以前的结果
  63.     ADC_CONTR=ADC_POWER|ADC_SPEEDLL;       //开启ACD电源、设置转换速度420
  64.     delayms(1);                            //上电延时                                                
  65. }

  66. /*----------------------------
  67.    获取ADC结果
  68. -----------------------------*/
  69. uchar zhADC(uchar ch)                                //zhADC(获取ADC结果)
  70. {
  71.     ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ch|ADC_START;    //启动转换
  72.     _nop_();                                         //4个时钟延时
  73.     _nop_();
  74.     _nop_();
  75.     _nop_();
  76.     while(!(ADC_CONTR & ADC_FLAG));                  //等待完成标志
  77.     ADC_CONTR &=~ADC_FLAG;                           //Close ADC(关闭ADC)
  78.     return ADC_RES;                                  //返回ADC结果
  79. }

  80. /*----------------------------
  81. 1ms延时子程序(12M晶振)
  82. -----------------------------*/
  83. void delayms(uint k)                    

  84. {
  85.     uint i,j;            
  86.     for(i=k;i>0;i--)   
  87.     for(j=747;j>0;j--);   
  88. }
  89. /*----------------------------
  90. 执行ADC转换结果子程序SR_高档 SRL_低档
  91. -----------------------------*/
  92. void SR()
  93. {               
  94.       uchar M;                        
  95.       M=0x22;                         //TEMP=55度

  96.       if (zhADC(0)>=M)                //如果ADC_1通道检测值大于等于M
  97.          out=1;                       //驱动输出1
  98.     else
  99.          out=0;                       //否则驱动输出0
  100. }
  101. /*低温控制*/
  102. void SRL()
  103. {               
  104.       uchar M;                        
  105.       M=0x30;                         //TEMP=45度

  106.       if (zhADC(0)>=M)                //如果ADC_1通道检测值大于等于M
  107.         out=1;                        //驱动输出1
  108.     else
  109.         out=0;                        //否则驱动输出0
  110. }
  111. void main()      //主函数
  112. {
  113.   port_mode();                         //初始化IO口
  114.   InitADC();                           //Init ADC sfr (初始化ADC SFR)

  115.   while(1)      
  116.   {
  117.   switch(n)      //开关选择
  118.   {
  119.   //case 0: ledL = 1;ledH = 1; readkey(); break;    //全熄灭

  120.   case 0: ledL = 0;readkey(); SRL(); break;       //LEDL亮并执行低档控制45度

  121.   case 1: ledH = 0;ledL = 1;readkey();SR(); break;              //LEDH亮并执行高档控制55度
  122.   //case 3: ledL = 1;ledH = 1; readkey();
  123.   }
  124.   }
  125. }
复制代码


发表于 2019-6-14 13:03:22 | 显示全部楼层
STC单片机的掉电模式了解一下,
按键接外部中断0,不仅可以用于唤醒单片机,还可以用于处理长按、短按的事件。
推荐自己写代码,这样可以学习一下单片机的掉电模式和状态机编程。
回复

使用道具 举报

发表于 2019-6-21 10:40:28 | 显示全部楼层
本帖最后由 la45088d1 于 2019-6-21 10:49 编辑

加好了,不过没测试也没法测试。你自己理解和修改吧!
Capture.PNG

TC.zip (12.57 KB, 下载次数: 4)

回复

使用道具 举报

发表于 2019-6-21 14:18:37 | 显示全部楼层
本帖最后由 ploestar 于 2019-6-22 07:25 编辑

3楼很硬核啊
回复

使用道具 举报

发表于 2019-6-22 03:50:06 来自手机浏览器 | 显示全部楼层
最简单的,再加个单片机,8条腿,2块钱,内置晶振。接个三极管配合继电器。你想怎么按怎么停都可以。
回复

使用道具 举报

 楼主| 发表于 2019-6-22 18:34:09 | 显示全部楼层
la45088d1 发表于 2019-6-21 10:40
加好了,不过没测试也没法测试。你自己理解和修改吧!

:cry:刚学C,汇编完全看不懂。不过还是感谢啊。
回复

使用道具 举报

发表于 2019-6-29 12:38:33 | 显示全部楼层


  1. //将原来的主函数删了 换成下面的
  2. //仅做思路参考 并没编译

  3. bit onehour=0;
  4. void Timer0Init(void){        //10毫秒@11.0592MHz
  5.         AUXR &= 0x7F;                //定时器时钟12T模式
  6.         TMOD &= 0xF0;                //设置定时器模式
  7.         TL0 = 0x00;                //设置定时初值
  8.         TH0 = 0xDC;                //设置定时初值
  9.         TF0 = 0;                //清除TF0标志       
  10.         ET0=1;
  11.         EA=1;       
  12.         TR0 = 1;                //定时器0开始计时
  13. }
  14. void wait_on(){                        //等长按
  15.         uchar n=0;       
  16.         while(1){
  17.                 if(!key){
  18.                         if(++n>200)break;
  19.                         delayms(10);
  20.                 }
  21.                 else n=0;               
  22.         }       
  23. }
  24. void shoutdown(){                //关机
  25. }
  26. void SRLorSR(){
  27.         static bit s,n=0;
  28.         if(!key){
  29.                 if(s){s=0;
  30.                         delayms(10);               
  31.                         if(!key)n=!n;                               
  32.                 }               
  33.         }
  34.         else s=1;
  35.         if(onehour){
  36.                 onehour=0;
  37.                 n=2;
  38.         }
  39.         switch(n){
  40.                 case 0:SRL();break;
  41.                 case 1:SR();break;
  42.                 case 2:{                       
  43.                         shoutdown();                       
  44.                         wait_on();
  45.                         TR0=1;
  46.                         n=0;                       
  47.                         break;
  48.                 }               
  49.         }       
  50. }
  51. void main(){      //主函数
  52.         port_mode();                         //初始化IO口
  53.         InitADC();                           //Init ADC sfr (初始化ADC SFR)
  54. //*********************
  55.         Timer0Init();
  56.         wait_on();       
  57.         while(1)SRLorSR();
  58. //*********************               
  59. }
  60. void T0_ISR()  interrupt 1  {//10ms中断
  61.         static uchar ms10=0;
  62.         static uint s=0;       
  63.         if(++ms10>100){ms10=0;
  64.                 if(++s>3600){
  65.                         s=0;
  66.                         onthour=1;
  67.                         TR0=0;
  68.                 }
  69.         }       
  70. }
复制代码
回复

使用道具 举报

 楼主| 发表于 2019-7-8 23:08:12 | 显示全部楼层
  1. #include "stc15w.h"                       
  2. #include <intrins.H>                      //函数运算头文件
  3. #define uint unsigned int                 //宏定义变量0-6553
  4. #define uchar unsigned char               //宏定义变量0-255
  5. #define     MAIN_Fosc       11059200L     //定义主时钟
  6. #define key_S 80                          //宏定义短按(约20ms)
  7. #define key_L key_S*50                    //宏定义长按(约1s)
  8. /*定义ADC参数*/
  9. #define ADC_POWER   0x80                //ADC power control dit (宏定义ADC电源控制位)1000 0000
  10. #define ADC_FLAG    0x10                //ADC complete flag (宏定义ADC完成标志位)    0001 0000
  11. #define ADC_START   0x08                //ADC start control dit (宏定义ADC启动控制位)0000 1000
  12. #define ADC_SPEEDLL 0x00                //420 clocks (宏定义420时钟)速度控制         0000 0000
  13. #define ADC_SPEEDL  0x20                //280 clocks (宏定义280时钟)速度控制         0001 0000
  14. #define ADC_SPEEDH  0x40                //140 clocks (宏定义140时钟)速度控制         0010 0000
  15. #define ADC_SPEEDHH 0x60                //070 clocks (宏定义70时钟)速度控制          0011 0000
  16. /*定义接口*/
  17. sbit out=P1^1;                          //驱动端口定义
  18. sbit key = P2^4;                        //定义KEY接口
  19. sbit ledL = P4^2;                       //定义低档位接口
  20. sbit ledH = P4^3;                       //定义高档位接口
  21. void InitADC();                         //初始化ADC子程序声明
  22. uchar zhADC(uchar ch);                  //ADC 转换子程序声明
  23. void delayms(uint k);                   //1ms延时子程序声明
  24. void SRH();                              //执行AD转换结果子程序声明H
  25. void SRM();                              //执行AD转换结果子程序声明M
  26. void SRL();                             //执行AD转换结果子程序声明L
  27. uint Cnt250us=0,Cnt1s;                  //定时变量
  28. bit  ON=0;                              //开关位变量
  29. bit  HL=0;                              //高低温位变量
  30. /*接口模式初始化*/
  31. void port_mode()                        
  32. {
  33.         P1M1 = 0x01;               //P1.0高阻 P1.1强推挽:0000 0001 ADC输入高阻、继电器强上拉
  34.         P1M0 = 0x02;               //P1.0高阻 P1.1强推挽:0000 0010 ADC输入高阻、继电器强上拉
  35.         P2M0 = 0x00;               //P2 P4灯和按键端口模式, 准双向口0x00
  36.         P2M1 = 0x00;
  37.         P4M0 = 0x00;
  38.         P4M1 = 0x00;
  39.         out=0;                     //驱动初始化0
  40. }

  41. void readkey(void)                                        //按键读取函数
  42. {
  43.         static uint count=0;                                //计数变量
  44.         if(!key)   
  45.         {  
  46.                 count++;  
  47.                 if(count==key_L)                       //长按
  48.                         ON=~ON;                        //开关机选择
  49.                 if(count>key_L)                        //防止count溢出
  50.                         count=key_L+1;           
  51.         }  
  52.         else                                           //按键抬起
  53.         {  
  54.                 if(count>key_S && count<key_L)//短按
  55.                 {
  56.                         if(ON==1)                        //开机状态有效
  57.                           HL=~HL;                        //高低温选择
  58.                 }
  59.                 count=0;                                        //count清0
  60.         }   
  61. }
  62. /*----------------------------
  63.    初始化ADC
  64. -----------------------------*/
  65. void InitADC()
  66. {
  67.     P1ASF=0x01;                            //设置P1.0端口作为模拟输入
  68.     ADC_RES=0;                             //清除以前的结果
  69.     ADC_CONTR=ADC_POWER|ADC_SPEEDHH;       //开启ACD电源、设置转换速度420
  70.     delayms(1);                            //上电延时                                                
  71. }
  72. /*----------------------------
  73.    获取ADC结果
  74. -----------------------------*/
  75. uchar zhADC(uchar ch)                                //zhADC(获取ADC结果)
  76. {
  77.     ADC_CONTR=ADC_POWER|ADC_SPEEDHH|ch|ADC_START;    //启动转换
  78.     _nop_();                                         //4个时钟延时
  79.     _nop_();
  80.     _nop_();
  81.     _nop_();
  82.     while(!(ADC_CONTR & ADC_FLAG));                  //等待完成标志
  83.     ADC_CONTR &=~ADC_FLAG;                           //Close ADC(关闭ADC)
  84.     return ADC_RES;                                  //返回ADC结果
  85. }
  86. /*----------------------------
  87. 1ms延时子程序(12M晶振)
  88. -----------------------------*/
  89. void delayms(uint k)                    
  90. {
  91.     uint i,j;            
  92.     for(i=k;i>0;i--)   
  93.     for(j=747;j>0;j--);   
  94. }
  95. /*----------------------------
  96. 执行ADC转换结果子程序SRH_高档 SRM_中档 SRL_低档
  97. -----------------------------*/
  98. /*高档控制*/
  99. void SRH()
  100. {               
  101.         uchar M;                        
  102.         M=0x22;                        //高
  103.         if(zhADC(0)>=M)                //如果ADC_1通道检测值大于等于M
  104.                 out=1;                 //驱动输出1
  105.         else
  106.                 out=0;                 //否则驱动输出0
  107. }
  108. /*中档控制*/
  109. void SRM()
  110. {               
  111.         uchar M;                        
  112.         M=0x28;                        //中
  113.         if(zhADC(0)>=M)                //如果ADC_1通道检测值大于等于M
  114.                 out=1;                 //驱动输出1
  115.         else
  116.                 out=0;                 //否则驱动输出0
  117. }

  118. /*低档控制*/
  119. void SRL()
  120. {               
  121.         uchar M;                        
  122.         M=0x30;                        //低
  123.         if(zhADC(0)>=M)                //如果ADC_1通道检测值大于等于M
  124.                 out=1;                 //驱动输出1
  125.         else
  126.                 out=0;                 //否则驱动输出0
  127. }
  128. void Timer0Init()                    //250微秒@11.0592MHz
  129. {
  130.         AUXR |= 0x80;                //定时器时钟1T模式
  131.         TMOD &= 0xF0;                //设置定时器模式
  132.         TL0 = 0x33;                  //设置定时初值
  133.         TH0 = 0xF5;                  //设置定时初值
  134.         TF0 = 0;                     //清除TF0标志
  135.         TR0 = 1;                     //定时器0开始计时
  136. }

  137. void main()      //主函数
  138. {
  139.         port_mode(); //初始化IO口
  140.         InitADC();   //初始化ADC SFR
  141.         Timer0Init();//初始化定时器
  142.         while(1)      
  143.         {
  144.                 if(TF0==1)//查询周期250us
  145.                 {
  146.                         TF0=0;
  147.                         readkey();//读按键
  148.                         if(ON==1)
  149.                         {
  150.                                 Cnt250us++;
  151.                                 if(Cnt250us>=4000)
  152.                                 {
  153.                                         Cnt250us=0;
  154.                                         Cnt1s++;
  155.                                         if(Cnt1s>=3600)
  156.                                         {
  157.                                                 Cnt1s =0;
  158.                                                 ON=0;
  159.                                                 ledH = 1;
  160.                                                 ledL = 1;
  161.                                                 out  = 0;
  162.                                         }
  163.                                 }
  164.                                 if(HL==1)
  165.                                 {
  166.                                         ledH = 0;
  167.                                         ledL = 1;
  168.                                         SRH();
  169.                                 }
  170.                                 else
  171.                                 {
  172.                                         ledH = 1;
  173.                                         ledL = 0;
  174.                                         SRL();
  175.                                 }
  176.                         }
  177.                         else
  178.                         {
  179.                                 Cnt250us=0;
  180.                                 Cnt1s= 0;
  181.                                 ledH = 1;
  182.                                 ledL = 1;
  183.                                 out  = 0;
  184.                         }
  185.                 }
  186.         }
  187. }
复制代码
已通过验正,长按开关功能,短按实现高低选择功能,开机状态定时关机。供参考。
回复

使用道具 举报

发表于 2019-7-10 12:24:48 | 显示全部楼层
有逻辑流程图吗?
回复

使用道具 举报

 楼主| 发表于 2019-7-11 21:02:29 | 显示全部楼层
eagler8 发表于 2019-7-10 12:24
有逻辑流程图吗?

没有哦,实现原功能就是:开机运行后1小时自动关闭。一个按键,长按开启和关闭,短按切换三种工作模式。三种模式对应指示灯。功能比较简单
回复

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-4-27 06:08 , Processed in 0.171600 second(s), 13 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

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