找回密码
 立即注册
查看: 386|回复: 0

学习笔记|电磁炉LED实战|STC32G单片机视频开发教程(冲哥)|第八集(下):课后练习

[复制链接]

该用户从未签到

12

主题

7

回帖

82

积分

注册会员

积分
82
发表于 2023-8-22 16:37:37 | 显示全部楼层 |阅读模式
本帖最后由 打酱油的工程师 于 2023-8-22 16:39 编辑

课后练习解答
增加按键3,按下后表示启动,选择的对应的功能的LED持续闪烁,表示正在工作,且在工作的时候无法切换功能。




需求分解
  • 1 增加按键3
[backcolor=inherit !important]#[backcolor=inherit !important]define[backcolor=inherit !important] KEY3 P34  [backcolor=inherit !important]//增加按键3
  • 2 按下后表示启动 电平控制
  • 3 工作状态锁定 表示正在工作,且在工作的时候无法切换功能。 该功能需要检测的标志位,且工作的时候无法进行切换。 增加:bit  Run_Now = 0; //0停止工作 1 开始工作。
增加KEY3控制代码如下:
  1. /*=======================按下按键3,执行本段代码=====================*/
  2.                 if (KEY3 == 0)    //必须是按键按下才会执行以下代码,key3被点击,灯在一闪一闪的时候,KEY3非按下模式
  3.                 {
  4.                         delay_ms(10);  //防抖
  5.                         if (KEY3 == 0)
  6.                         {
  7.                                 while(KEY3 == 0);        //等待按键松开,将要执行按下蜂鸣
  8.                                 if(Run_Mode > 0)   //表示有模式,已经选择了模式,Run_Mode=0时,未选择模式,不执行
  9.                                 {
  10.                                         BEEP = 0;                //打开蜂鸣
  11.                                         delay_ms(10);   //延迟10ms
  12.                                         BEEP = 1;                //关闭蜂鸣
  13.                                         Run_Now = !Run_Now; //运行和停止之间的切换
  14.                                 }
  15.                         }
  16.                 }
  17.                 if( Run_Now = 1)   //正在运行
  18.                 {
  19.                         P2 = 0XFF;         //全部熄灭
  20.                         delay_ms(200);   //延迟200ms
  21.                         P2 = ~(1<< (Run_Mode - 1));        //点亮这个灯
  22.                         delay_ms(200);   //延迟200ms
  23.                 }
  24.                 else                          //停止运行时,没有工作,灯和上面的一样
  25.                 {
  26.                         P2 = ~(1<< (Run_Mode - 1));
  27.                 }
复制代码

按动KEY2后,0位LED持续闪烁,不能实现既定功能。

第一版代码问题分析
与编译提示的“ warning C137: constant in condition expression”有关,这里应该是判断,不是赋值。修改。 调整后,可以控制状态等闪动,但是接着按KEY2,移动不受影响,有逻辑错误,继续排查。 即工作的时候,功能无法切换没有实现。工作状态,变量Run_Now为1,而KEY2能切换的前提是Run_Now状态为0,所以增加条件限制:“if(Run_Now == 0)   //Run_Now状态为0(未工作)时才能切换”。 另外,代码KEY2松开后才能执行,实际运行中,按下后有没有松开不太确定,改成按下就执行,等到它松开,调整while循环的位置到最后:while(KEY3 == 0); //等待按键松开,将要执行按下蜂鸣 KEY1,KEY2也可根据调整。 注意:if ...else可看做是一个整体,中间不能加入其他保留字,如while等。 编译,写入开发板,下载成功,功能正常。

Tips:STC-ISP的设置
可保存,方便调用:







按键需要按的稍微久一点,原因后期课程会分析,讲定时器的时候优化。

Tips:定时器
参考链接:单片机定时器工作原理是什么单片机定时器工作方式有哪些




使用单片机时经常用到一个元件,那就是单片机定时器,单片机定时器的作用主要是在发生软件故障时,通过使器件复位(如果软件未将器件清零)将单片机复位,也可以用于将器件从休眠或空闲模式唤醒,还能用做精确延时处理,常被应用于时间控制、程序延时、对外部时间计数和检测等工作范围内。那么单片机定时器原理是什么呢? 单片机定时器,其实质是一个计数器,脉冲每一次下降沿,计数寄存器数值将加1,如果计数的脉冲是来源于单片机内部的晶振,由于其周期极为准确,则称为定时器;如果计数的脉冲来源于单片机外部的引脚,由于其周期一般不准确,则称为计数器。 单片机定时器工作方式有哪些 单片机定时器的工作方式有很多,大致可分为以下几种:1、方式0 方式0为13位计数,由TLO的低5位(高3位未用)和THO的8位组成TLO的低5位溢出时向THO进位,THO溢出时,置位TCON中的TFO标志,向CPU发出中断请求。 2、方式1 方式1的计数位数是16位,由TLO(TL1)作为低8位、THO(TH1 )作为高8位,组成了16位加1计数器。3、方式2 方式2为自动重装初值的8位计数方式。在方式2下,当定时器计满255( FFH)溢出时,CPU自动把TH的值装入TL中,不需用户干预,比较适合于用作较精确的脉冲信号发生器。 4、方式3 方式3只适用于定时器/计数器TO,定时器T1方式3时相当于TR1=0,停止计数。方式3将TO分成为两个独立的8位计数器TLO和THO。

实现完整电磁炉显示功能的代码
  1. void Test(void)   //电磁炉的功能
  2. {
  3.                 if (KEY1 == 0)   //开关机键
  4.                 {
  5.                         delay_ms(1000);  //长按1s开机
  6.                         if (KEY1 == 0)
  7.                         {
  8. /*=======================还没有开机的情况下,执行本段代码=====================*/
  9.                                 if (Run_Flag == 0)  //表示还没有开机
  10.                                 {
  11.                                         Run_Flag = 1;   //开机变量改为1,表示已经开机
  12.                                         BEEP = 0;                //打开蜂鸣
  13.                                         delay_ms(10);   //延迟10ms
  14.                                         BEEP = 1;                //关闭蜂鸣
  15.                                         P40 = 0;                //打开了LED总电源
  16.                                         P2 = 0X00;                //全部点亮
  17.                                         delay_ms(300);   //延迟200ms
  18.                                         P2 = 0XFF;                 //全部关闭
  19.                                 }
  20.                                 else
  21.                                 {
  22.                                         Run_Flag = 0;   //标记已关机
  23.                                         BEEP = 0;                //打开蜂鸣(提醒)
  24.                                         delay_ms(10);   //延迟10ms
  25.                                         BEEP = 1;                //关闭蜂鸣
  26.                                         P2 = 0XFF;                //状态指示全部关闭
  27.                                         P40 = 1;                //关闭总电源LED
  28.                                         Run_Mode = 0;   //模式清零
  29.                                         Run_Now = 0;        //运行状态清零(改成停止)
  30.                                 }
  31.                                 while(KEY1 == 0);        //按钮按下,先执行并等待按钮松开
  32.                         }
  33.                 }
  34. /*=======================按下按键2,执行本段代码=====================*/
  35.                 if (KEY2 == 0 && Run_Flag == 1 )   //切换模式,且处于开机状态,状态选择键有效
  36.                 {
  37.                         delay_ms(10);  //防抖
  38.                         if (KEY2 == 0)
  39.                         {
  40.                                         if (Run_Now == 0)        //Run_Now状态为0(未工作)时才能切换
  41.                                         {
  42.                                                 BEEP = 0;                //打开蜂鸣
  43.                                                 delay_ms(10);   //延迟10ms
  44.                                                 BEEP = 1;                //关闭蜂鸣
  45.                                                 Run_Mode++;                //每次按下,模式+1(移至下一个led)
  46.                                                 if (Run_Mode > 8)  //如果模式大于8,回到模式1
  47.                                                         Run_Mode = 1;  //Run_Mode超过8后清零,回到第一个灯
  48.                                                 //错误写法,执行结果是8个灯中仅1个不亮
  49.                                                                                                         //灯是低电平点亮,1<< Run_Mode,即1<<1,左移以后为0000 0010,仅1个LED灭,继续左移,尾部补0,还是只有1个LED灭
  50.                                                                                                         //解决方法:RunMode先减1,再左移,最后全部取反。这里用~为全取反。而!是位取反。
  51.                                                                                                                         //P2 = 0XFX;  P6<< 1 + 1;  也可以实现
  52.                                                 P2 = ~(1<< (Run_Mode - 1));
  53.                                         }
  54.                                         while(KEY2 == 0);        //按钮按下,并等待按钮松开
  55.                         }
  56.                 }
  57. /*=======================按下按键3,执行本段代码=====================*/
  58.                 if (KEY3 == 0)   //必须是按键按下才会执行以下代码,key3被点击,灯在一闪一闪的时候,KEY3非按下模式
  59.                 {
  60.                         delay_ms(10);  //防抖
  61.                         if (KEY3 == 0)
  62.                         {
  63.                                 if(Run_Mode > 0 )   //表示有模式,已经选择了模式且处在开机状态下,Run_Mode=0时,未选择模式,不执行
  64.                                 {
  65.                                         BEEP = 0;                //打开蜂鸣
  66.                                         delay_ms(10);   //延迟10ms
  67.                                         BEEP = 1;                //关闭蜂鸣
  68.                                         Run_Now = !Run_Now; //运行和停止之间的切换
  69.                                 }
  70.                                 while(KEY3 == 0);        //等待按键松开,先执行
  71.                         }
  72.                 }
  73.                 if( Run_Now == 1)   //正在运行
  74.                 {
  75.                         P2 = 0XFF;         //全部熄灭
  76.                         delay_ms(200);   //延迟200ms
  77.                         P2 = ~(1<< (Run_Mode - 1));        //点亮这个灯
  78.                         delay_ms(200);   //延迟200ms
  79.                 }
  80.                 else                          //停止运行时,没有工作,灯和上面的一样
  81.                 {
  82.                         P2 = ~(1<< (Run_Mode - 1));
  83.                 }
  84. }
复制代码

测试流程
先KEY1开机蜂鸣一声LED点亮 切换模式KEY2(需处于开机状态下) 按一下KEY3,当前LED闪(在当前模式下运行),运行状态下,切换模式短按长按都失效 再按一下KEY3,LED停闪(运行停止),可以切换模式。 后期学完定时器的章节,再解决按键反应迟钝的问题。或者学完数码管以后,既可以修理一下。

总结
厘清正常、简单的逻辑。疯狂的在用if和else做一个判断。


欢迎大家访问我的CSDN:打酱油的工程师
回复 送花

使用道具 举报

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2024-5-21 23:16 , Processed in 0.057185 second(s), 29 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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