找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1182|回复: 5
打印 上一主题 下一主题
收起左侧

如何增加这个按键和定时的程序的功能?求帮助

[复制链接]
跳转到指定楼层
楼主
ID:562338 发表于 2019-6-15 19:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
现在程序是上电默认开机并运行了的,但想增加一些功能
增加:上电默认不开机,长按键KEY约2秒再开机,并运行SRL(),短按切换到SR(),只要是短按就来回切换,但任何状态下长按开与关机
          启动后,运行1小时自动关机
#include "stc15w.h"                       
#include <intrins.H>                      //函数运算头文件
#define uint unsigned int                 //宏定义变量0-6553
#define uchar unsigned char               //宏定义变量0-255
#define     MAIN_Fosc       11059200L     //定义主时钟


/*定义ADC参数*/


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


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


/*void delay()                           //延时函数1
{
  uint  i, j;
  for(i = 0; i < 100; i++)  
  for(j = 0; j < 500; j++);
}
*/
void readkey(void)                   //按键读取函数
{
  uchar  i, j;
  if(!key)  
    {
     for(i = 0; i < 10; i++)
     for(j = 0; j < 120; j++);       //延时消抖
  if(!key)  
    {
     while(!key);            //等待按键释放
     n++;
     n %= 2;                //n = 0~2
     }
     }
  }


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


/*----------------------------
   获取ADC结果
-----------------------------*/
uchar zhADC(uchar ch)                                //zhADC(获取ADC结果)
{
    ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ch|ADC_START;    //启动转换
    _nop_();                                         //4个时钟延时
    _nop_();
    _nop_();
    _nop_();
    while(!(ADC_CONTR & ADC_FLAG));                  //等待完成标志
    ADC_CONTR &=~ADC_FLAG;                           //Close ADC(关闭ADC)
    return ADC_RES;                                  //返回ADC结果
}


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


{
    uint i,j;            
    for(i=k;i>0;i--)   
    for(j=747;j>0;j--);   
}
/*----------------------------
执行ADC转换结果子程序SR_高档 SRL_低档
-----------------------------*/
void SR()
{               
      uchar M;                        
      M=0x22;                         //TEMP=55度


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


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


  while(1)      
  {
  switch(n)      //开关选择
  {
  case 0: ledL = 0;readkey(); SRL(); break;       //LEDL亮并执行低档控制45度


  case 1: ledH = 0;ledL = 1;readkey();SR(); break;              //LEDH亮并执行高档控制55度


  }
  }
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:563165 发表于 2019-6-15 22:08 | 只看该作者
可以根据记录按键按下的次数,以及按下的时间来做区别。具体功能我没有看的太明白的,希望能补充说明!
回复

使用道具 举报

板凳
ID:213173 发表于 2019-6-16 09:11 | 只看该作者
给你增加了加电等待,长短按键控制开关和高低温,运行1小时自动关机。如果楼主没有使用ADC硬件滤波必须再增加软件滤波,否则继电器在温度临界点会抖动。
  1. #include <STC15F2K60S2.H>
  2. //#include "stc15w.h"                       
  3. #include <intrins.H>                      //函数运算头文件
  4. #define uint unsigned int                 //宏定义变量0-6553
  5. #define uchar unsigned char               //宏定义变量0-255
  6. #define     MAIN_Fosc       11059200L     //定义主时钟
  7. #define key_S 80                                                                        //宏定义短按(约20ms)
  8. #define key_L key_S*50                                                        //宏定义长按(约1s)
  9. /*定义ADC参数*/
  10. #define ADC_POWER   0x80                //ADC power control dit (宏定义ADC电源控制位)1000 0000
  11. #define ADC_FLAG    0x10                //ADC complete flag (宏定义ADC完成标志位)    0001 0000
  12. #define ADC_START   0x08                //ADC start control dit (宏定义ADC启动控制位)0000 1000
  13. #define ADC_SPEEDLL 0x00                //420 clocks (宏定义420时钟)速度控制         0000 0000
  14. #define ADC_SPEEDL  0x20                //280 clocks (宏定义280时钟)速度控制         0001 0000
  15. #define ADC_SPEEDH  0x40                //140 clocks (宏定义140时钟)速度控制         0010 0000
  16. #define ADC_SPEEDHH 0x60                //070 clocks (宏定义70时钟)速度控制          0011 0000
  17. /*定义接口*/
  18. sbit out=P1^1;                          //驱动端口定义
  19. sbit key = P2^4;                        //定义KEY接口
  20. sbit ledL = P4^2;                       //定义低档位接口
  21. sbit ledH = P4^3;                       //定义高档位接口
  22. void InitADC();                         //初始化ADC子程序声明
  23. uchar zhADC(uchar ch);                  //ADC 转换子程序声明
  24. void delayms(uint k);                   //1ms延时子程序声明
  25. void SR();                              //执行AD转换结果子程序声明H
  26. void SRL();                             //执行AD转换结果子程序声明L
  27. //uchar n=0;                            //按键初始化
  28. uint Cnt250us=0,Cnt1s;//定时变量
  29. bit  ON_OFF=0; //开关位变量
  30. bit  H_L=0;                //高低温位变量
  31. /*接口模式初始化*/
  32. void port_mode()                        
  33. {
  34.    P1M1 = 0x01;               //P1.0高阻 P1.1强推挽:0000 0001 ADC输入高阻、继电器强上拉
  35.    P1M0 = 0x02;               //P1.0高阻 P1.1强推挽:0000 0010 ADC输入高阻、继电器强上拉
  36.         P2M0 = 0x00;               //P2 P4灯和按键端口模式, 准双向口0x00
  37.         P2M1 = 0x00;
  38.         P4M0 = 0x00;
  39.         P4M1 = 0x00;
  40.    out=0;                         //驱动初始化0
  41. }

  42. void readkey(void)                                        //按键读取函数
  43. {
  44.         static uint count=0;                                //计数变量
  45.         if(!key)   
  46.         {  
  47.                 count++;  
  48.                 if(count==key_L)                                //长按
  49.                         ON_OFF=~ON_OFF;                        //开关机选择
  50.                 if(count>key_L)                                //防止count溢出
  51.                         count=key_L+1;          
  52.         }  
  53.         else                                                                        //按键抬起
  54.         {  
  55.                 if(count>key_S && count<key_L)//短按
  56.                 {
  57.                         if(ON_OFF==1)                        //开机状态有效
  58.                                 H_L=~H_L;                        //高低温选择
  59.                 }
  60.                 count=0;                                        //count清0
  61.         }   
  62. }
  63. /*----------------------------
  64.    初始化ADC
  65. -----------------------------*/
  66. void InitADC()
  67. {
  68.     P1ASF=0x01;                            //设置P1.0端口作为模拟输入
  69.     ADC_RES=0;                             //清除以前的结果
  70.     ADC_CONTR=ADC_POWER|ADC_SPEEDLL;       //开启ACD电源、设置转换速度420
  71.     delayms(1);                            //上电延时                                                
  72. }
  73. /*----------------------------
  74.    获取ADC结果
  75. -----------------------------*/
  76. uchar zhADC(uchar ch)                                //zhADC(获取ADC结果)
  77. {
  78.     ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ch|ADC_START;    //启动转换
  79.     _nop_();                                         //4个时钟延时
  80.     _nop_();
  81.     _nop_();
  82.     _nop_();
  83.     while(!(ADC_CONTR & ADC_FLAG));                  //等待完成标志
  84.     ADC_CONTR &=~ADC_FLAG;                           //Close ADC(关闭ADC)
  85.     return ADC_RES;                                  //返回ADC结果
  86. }


  87. /*----------------------------
  88. 1ms延时子程序(12M晶振)
  89. -----------------------------*/
  90. void delayms(uint k)                    
  91. {
  92.     uint i,j;            
  93.     for(i=k;i>0;i--)   
  94.             for(j=747;j>0;j--);   
  95. }
  96. /*----------------------------
  97. 执行ADC转换结果子程序SR_高档 SRL_低档
  98. -----------------------------*/
  99. void SR()
  100. {               
  101.         uchar M;                        
  102.         M=0x22;                         //TEMP=55度
  103.         if(zhADC(0)>=M)                //如果ADC_1通道检测值大于等于M
  104.                 out=1;                       //驱动输出1
  105.         else
  106.                 out=0;                       //否则驱动输出0
  107. }
  108. /*低温控制*/
  109. void SRL()
  110. {               
  111.         uchar M;                        
  112.         M=0x30;                         //TEMP=45度
  113.         if(zhADC(0)>=M)                //如果ADC_1通道检测值大于等于M
  114.                 out=1;                        //驱动输出1
  115.         else
  116.                 out=0;                        //否则驱动输出0
  117. }
  118. void Timer0Init()                //250微秒@11.0592MHz
  119. {
  120.         AUXR |= 0x80;                //定时器时钟1T模式
  121.         TMOD &= 0xF0;                //设置定时器模式
  122.         TL0 = 0x33;                        //设置定时初值
  123.         TH0 = 0xF5;                        //设置定时初值
  124.         TF0 = 0;                                //清除TF0标志
  125.         TR0 = 1;                                //定时器0开始计时
  126. }

  127. void main()      //主函数
  128. {
  129.         port_mode(); //初始化IO口
  130.         InitADC();   //Init ADC sfr (初始化ADC SFR)
  131.         Timer0Init();//初始化定时器
  132.         while(1)      
  133.         {
  134.                 if(TF0==1)//查询周期250us
  135.                 {
  136.                         TF0=0;
  137.                         readkey();//读按键
  138.                         if(ON_OFF==1)
  139.                         {
  140.                                 Cnt250us++;
  141.                                 if(Cnt250us>=4000)
  142.                                 {
  143.                                         Cnt250us=0;
  144.                                         Cnt1s++;
  145.                                         if(Cnt1s>=3600)
  146.                                         {
  147.                                                 Cnt1s =0;
  148.                                                 ON_OFF=0;
  149.                                                 ledH = 1;
  150.                                                 ledL = 1;
  151.                                                 out  = 0;
  152.                                         }
  153.                                 }
  154.                                 if(H_L==1)
  155.                                 {
  156.                                         ledH = 0;
  157.                                         ledL = 1;
  158.                                         SR();
  159.                                 }
  160.                                 else
  161.                                 {
  162.                                         ledH = 1;
  163.                                         ledL = 0;
  164.                                         SRL();
  165.                                 }
  166.                         }
  167.                         else
  168.                         {
  169.                                 Cnt250us=0;
  170.                                 Cnt1s= 0;
  171.                                 ledH = 1;
  172.                                 ledL = 1;
  173.                                 out  = 0;
  174.                         }
  175.                 }
  176.         }
  177. }
复制代码
回复

使用道具 举报

地板
ID:562338 发表于 2019-6-16 10:58 | 只看该作者
wulin 发表于 2019-6-16 09:11
给你增加了加电等待,长短按键控制开关和高低温,运行1小时自动关机。如果楼主没有使用ADC硬件滤波必须再增 ...

感谢大师啊!下载运行正常。我学习学习一下先,你写的控制效果比我的好很多啊,控温反馈很及时。我驱动的是MOS管,所以应不用担心反复的问题。我要的就是这种效果,控温才能准一些。不知道什么时候才能学到PID技术那一步
回复

使用道具 举报

5#
ID:562338 发表于 2019-6-17 23:56 | 只看该作者
wulin 发表于 2019-6-16 09:11
给你增加了加电等待,长短按键控制开关和高低温,运行1小时自动关机。如果楼主没有使用ADC硬件滤波必须再增 ...

大师,谢谢你的帮助。你的是充分利用if  else。但和我原来想的用的switch区别还是满大的。现在想自己增加多一道M档,增加不进去了。能再帮我增加多一道SRM();  吗。麻烦你了。
回复

使用道具 举报

6#
ID:562338 发表于 2019-7-8 11:01 | 只看该作者
经过大半个月的抽空学习和偿试,已实现想要的功能。
思路就是短按时,增加n++,通过switch(n),短按就可以选择几种模式了。终于实现长按开关,短按换子程序了。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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