第九届省赛之彩灯控制器~

Everything will be ok!!!!


刷了第二套题,马上要比赛了,不知道自己还能不能再刷几套题呀,还要把底层好好写写呐,最近遇到了一些好的事情,也有一些糟心的事情,但是我相信一切都会好起来的!!!加油!!!


代码参考:<我的GitHub>第九届省赛之彩灯模拟器


题目呀:

  1. 基本功能描述
    通过单片机控制 8 个 LED 指示灯按照特定的顺序(工作模式)亮灭;指示灯的流转间隔可通过按键调整,亮度可由电位器 RB2 进行控制;各工作模式的流转间隔时间需在 E2PROM 中保存,并可在硬件重新上电后,自动载入。
  2. 设计说明
    1) 关闭蜂鸣器、继电器等与本试题程序设计无关的外设资源;
    2) 设备上电后默认数码管、LED 指示灯均为熄灭状态;
    3) 流转间隔可调整范围为 400ms-1200ms;
    4) 设备固定按照模式 1、模式 2、模式 3、模式 4 的次序循环往复运行。
  3. LED 指示灯工作模式
    1)模式 1:按照 L1、L2…L8 的顺序,从左到右单循环点亮。
    2)模式 2:按照 L8、L7…L1 的顺序,从右到左单循环点亮。
    3)模式 3:
    第九届省赛之彩灯控制器~
  4. 亮度等级控制
    检测电位器RB2的输出电压,控制8个LED指示灯的亮度,要求在0V-5V的可调区间内,实现 4 个均匀分布的 LED 指示灯亮度等级
  5. 按键功能
    1)按键 S7 定义为“启动/停止”按键,按下后启动或停止 LED 的流转。
    2)按键 S6 定义为“设置”按键,按键按下后数码管进入“流转间隔”
    设置界面,如下图所示:
    第九届省赛之彩灯控制器~
    3)按键 S5 定义为“加”按键,在设置界面下,按下该键,若当前选择的是运行模式,则运行模式编号加 1,若当前选择的是流转间隔,则流转间隔增加 100ms。
    4)按键 S4 定义为“减”按键,在设置界面下,按下该键,若当前选择的是运行模式,则运行模式编号减 1,若当前选择的是流转间隔,则流转间隔减少 100ms。
    5)按键功能说明:
    a) 按键 S4、S5 的“加”、“减”功能只在“设置状态”下有效,数值的调整应注意边界属性。
    b)在非“设置状态”下,按下 S4 按键可显示指示灯当前的亮度等级,4 个亮度等级从暗到亮,依次用数字 1、2、3、4 表示;松开S4 按键,数码管显示关闭,亮度等级的显示格式如下图所示:
    第九届省赛之彩灯控制器~

    做几点说明

    1. 关于shift这个中间变量:为什么要定义一个中间变量呢们知道51上的LED是低电平点亮的,要实现流水灯的效果,我们需要让8个LED循环点亮,这就需要通过移位来实现,但是移0肯定是不行的,(以右移为例)移位后高位是补0的,那么我们实现的效果最后就是全亮的状态,所以(移1设置一个中间变量,P0口的状态只要再取反就可以了;
    2. 关于PWMSTA这个变量:是用来存储P0口的状态的,调LED亮度的时候会用到,是一个全局变量,LED模式这部分比较简单,主要还是在后面。
      二. 按键功能:
      关于“启动/停止”功能,这个功能很好实现,只要设置一个标志量,然后在按键按下的时候改变标志量的值就可以了;

    流转间隔设置,以及数码管闪烁,这个功能也比较好实现,数码管闪烁的思想和第八届的电子钟是一样的思想,需要注意的一点是:看清题目要求,题目中说 “各工作模式的流转间隔时间需在 E2PROM 中保存,并可在硬件重新上电后,自动载入”,说明是4个不同的模式分别对应四个不同的流转间隔,那么我们需要定义一个数组,用来存储4个模式下的流转间隔,并实现分别设置时间,看代码:

    三. 加减时间功能:(以加为例,减法类似)

    模式1对应runtime[0],模式2对应runtime[1],模式3对应runtime[2],模式4对应runtime[3]
    四. 设置模式(这里我写的不是很简便,有很多重复部分,读者可以自己优化一下)numBlinkSta这个标志量是在中断里每隔0.8秒改变一次状态的,这样就实现了数码管每隔0.8秒亮灭了,第八届的题里我有详细写;

    五. 重头戏!!!关于调整亮度!!!用到的也是PWM波的思想,先明确一点:我们是如何实现亮度调节的呢白了,就是在极短的一段时间里让小灯灭一段时间,然后再亮一段时间,这样在视觉上看起来灯的亮度就是发生变化的,看代码,有详细注释:

    emmm,读者可以好好看看注释,还有一点我觉得特别重要的地方!!!就是什么时候读取E2PROM的问题:读取E2PROM里面的数据必须要放在总中断打开之前,主函数里读取一次就可以了,为什么呢为我们是一次读取四个字节的数据的,而我们的定时器1是一个10us定时器,时间太快了,会影响到E2PROM读取数据,比如说我们正在读第一个字节的数据,这时候中断来了,我们需要进入中断,那么就会扰乱E2PROM读取数据;

    另外还要注意!!!刚下载程序的时候,要先向E2PROM里面写入数据,不能先读取,也就是说下第一遍程序的时候要先把E2Read这个函数屏蔽,看一下代码:

    六. 按下S4显示亮度等级:
    这个功能和第八届省赛试题里,按下按键显示温度差不多,我们在AdjustDC这个函数里面改变的亮度等级,只要在按下S4的时候显示出来就可以了,需要注意的是一直按着S4才会显示,一旦松开就不显示了,所以我们需要一直扫描S4的状态,那么我们就在KeyScan这个按键扫描函数里处理不就可以了吗,看代码:

    具体功能就是这样实现的,注意一下细节,打好底层,基本上就可以写出来了,我会再写一遍程序,遇到问题的话还会再更新~


    第一遍遇到的问题:
    1. nice的操作:到8归零,两种方法:index &= 7(是2的整数次方才能用这个方法)或者!!!!!!index %= 8;(通用!!!!!)
    2. 每调试一个地方就要下载验证一下,再次强调一下E2PROM的操作:E2Read(runtimebuff, 0x00, 4);//一个字节是1个u8,E2Prom的地址范围是0x00到0xFF(数组的名字就是地址,不需要再取地址符)
    3. 要先往E2PROM里面写入你想写入的数据,然后再读,否则你从E2PROM里面读到的是E2PROM里原有的值!!!!!
    4. 另外!!!要特别注意数据溢出的问题!!!!!
    5. 关于软件生成的10us定时器,有几点需要注意的问题:

    第九届省赛之彩灯控制器~

    第二遍遇到的问题:

    1. 尽量不要使用ShowNumber这个函数,直接操作LedBuff[]比较好 ,我第二遍做的时候想把SetTime这个函数写得简单一点,然后就用到了ShowNumber这个函数,但是出现了问题,一个是数码管显示不稳定,还有一个就是亮度显示部分也出现了问题;
    2. 对寄存器执行操作时,哪里用到就在哪里使用,用完就关闭:
      第九届省赛之彩灯控制器~

    来源:ReRrain

    声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2019年2月10日
下一篇 2019年2月10日

相关推荐