咱们聊一聊课程2所要实现的具体的任务:用定时器中断实现数码管数值的递减。课程中我们:学习了hc595数码管的控制芯片74hc595的基本知识以及定时器的配置方法。定时器的使用其实在课程1,咱们去实现任务目标的时候已经配置了,那么咱们接下来就是通过咱们课程2的所学与课程2的目标任务的实现来具体规划一下这个功能。
根据任务的字面意思是实现数码管数值的递减,从10递减到0步长为1。这个递减的变化,咱们是可以从定时器中进行的,间隔时间选择500ms。其实,在本次课程中的学习最主要的还是74 hc 595的驱动控制。
咱们了解一下74hc595驱动的数码管:
本次的数码管属于共阳的方式,74hc595采集联级方式使两个芯片驱动8个数码管,74hc595可以实现锁存,所以单一时间只能显示一个数码管,要想显示多位数就需要进行循环扫描显示(上图为课程中的原理图,与实际模块的接口是不符的)。
我们看一下数码管的连接方式:下面是课程中的连接:
由于我们准备在课程1的基础上继续编写,这三个引脚是RGB的控制引脚,所以我们选取其他引脚进行控制(PA3、PA7、PA12)。
驱动代码如下:
uint8_t Ditigat_num[12] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0x00};//0-9,全灭,全亮 uint8_t Digital_unit[8] = {0};//用于存储多位分解 uint8_t Display_unit;//显示的位数 uint16_t Display_num;//显示的数字 void HC595_WriteData(uint8_t dat) { uint8_t i; for(i = 0;i<8;i++) { if(dat & 0x80) { HC595_DAT_SET; } else { HC595_DAT_RESET; } dat <<= 1; HC595_CLK_SET; delay_cycles(32); HC595_CLK_RESET; delay_cycles(32); } } void Display_Out(uint16_t num) { uint16_t num1 = 0; uint8_t i=0; num1 = num; if(num1 == 0) { HC595_WriteData(Ditigat_num[num1%10]); HC595_WriteData(1 << 0); HC595_PCK_RESET; delay_cycles(32); HC595_PCK_SET; delay_cycles(32); HC595_PCK_RESET; } else { for(i=0;!(num1 == 0);i++) { HC595_WriteData(Ditigat_num[num1%10]); HC595_WriteData(1 << i); HC595_PCK_RESET; delay_cycles(32); HC595_PCK_SET; delay_cycles(32); HC595_PCK_RESET; num1 /= 10; delay_cycles(20000); } } }
直接通过在while中调用Display_Out(Display_num)进行刷新显示,在定时器中和RGB的循环显示周期一致,循环减1,并在开启和关闭时赋予状态,直接修改Display_num的数值就可以了。
效果如下:
是不是看着有点不太习惯,为什么要套上静电袋呢?我遇到了一个我无法解决的问题,就是套上静电袋,这个扫描的数值才能显示,要不就显示不了,正常也应该会锁存一种状态在啊。万用表测了引脚也是有问题的,不止到你们有没有遇到,我的扫描周期也不是特别快。我家的电磁环境有这么大糟糕吗?