课程2属于进阶课程,在这里我们接触到第一个用到的数码管模块,这相当于一个显示单元。话不多或我们开始上课了。
第一部分
74HC595驱动的8位数码管模块的工作原理与驱动设计。
数码管我们可以理解为是8个LED组成的一个显示组合,可以显示一些基本的数字或者字母符号等等,上节课我们了解到LED可以是上拉也可以下拉,只要有电流通过就会发光,数码管根据这种情况分为共阴极或者共阳极两种。原理如下图:
共阴极是所有电流的流向,共阳极则是所有电流的流出。本次模块中用到的是两个共阳极的4位数码管组成,那么如何实现控制的呢?
上图是模块的一个示意图,我们看到其中一个74HC595控制这个8个数码管的共同的位码,而另一个则控制着每一个数码管的段码,由于595是串行转8位并行的锁存芯片,所以两个74HC595正好最多可以控制8个数码管。我们通过给对应段码高,给位码低,就可以点亮对应的数码管。
板卡的串行输入控制需要3个引脚实现,课程中使用了RGB用到的3个引脚进行串行数据的输入,及PA13(PCLK)、PA26(SCLK)、PA27(DIO)。
串行数据的通信基本上都要参考一定的时序要求,HC595需要满足如上的时序要求。
驱动的设计代码如下:
uint8_t Disp_DX[12] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0x00}; void HC595_WriteData(uint8_t data){ uint8_t i; for(i = 0;i<8;i++){ if(data & 0x80){ HC595_DAT_1; } else{ HC595_DAT_0; } data <<= 1; HC595_CLK_0; HC595_CLK_1; } } void Display_Out(void){ HC595_RCK_0; HC595_RCK_1; } void HC595_SEND_DATA(uint8_t dis_num,uint8_t dis_bit){ HC595_WriteData(dis_num); HC595_WriteData(1<<dis_bit); Display_Out(); }为了后续数字的显示,写了一个循环显示的函数:
void Display(uint16_t num) { uint16_t num1 = 0; uint8_t i=0; num1 = num; if(num1 == 0) { HC595_WriteData(Disp_DX[num1%10]); HC595_WriteData(1 << 0); Display_Out(); } else { for(i=0;!(num1 == 0);i++) { HC595_WriteData(Disp_DX[num1%10]); HC595_WriteData(1 << i); Display_Out(); num1 /= 10; delay_cycles(200); } } }
第二部分
这一部分是通过课程1的按键学习与数码管的控制结合的一个展示,通过按键来循环显示数值:
if(DL_GPIO_readPins(GPIO_S2_PORT, GPIO_S2_PIN_14_PIN) == 0){ keytmp++; if(keytmp > 5000){ Dutytmp++; keytmp = 0; } if(Dutytmp > 9) Dutytmp = 0; } Display(Dutytmp);
通过延时采集按键状态然后修改显示的值,实现按键变化,不过这种方式的按键采集有个缺点,长时间按键会不断判断,导致显示的输不断增加,还是使用中断方式比较好。效果可以发现有连键的现象。
第三部分
定时器的使用,定时器可以说是使用非常频繁的一个功能,本次使用的TIMG通用定时器进行定时:
定时器注意的就是时钟预填装值等等,这些我们可以直接在配置文件中进行填写,而且不需要计算,直接添加定时时间就可以自动生成了:
这里需要注意,如果定时比较大,需要通过调整分频器来达到比较理想的数值。
对于定时器中断需要我们自己添加:
void TIMER_0_INST_IRQHandler(void){ switch (DL_TimerG_getPendingInterrupt(TIMER_0_INST)) { case DL_TIMER_IIDX_ZERO: timecnt++; if(timecnt >= 10){ if(Dutytmp>0){ Dutytmp--; } else if(Dutytmp == 0) Dutytmp = 10; timecnt = 0; } break; default: break; } }
本部分的代码实现直接和本节课的课后作业结合实现了,10到0的循环显示,定时器定时为100ms,通过定时器进行1s间隔的实现。
通过本节课的学习主要是对数码管驱动有了全面的了解,以及定时器的使用,不过在使用的过程中发现数码管的模块存在一定的问题,通过论坛大佬们的经验传授,使用静电袋的方式实现了数码管功能的正常显示。