(一)任务概述
本次主要是以自我提升的态度来参加本次TI的活动,自己在学校上课也在学习MSPM0系列单片机,感谢EEPW提供的这次机会,让我能够巩固拓展自己的知识。这次作业的主要内容是使用定时器中断,实现数码管显示数值的递减。时间范围:10~0递减步长:1000ms。使用的开发板是MSPM0系列的L1306
(二)数码管原理介绍
数码管是指能够显示数字的一种电子元件,通常用于显示数字或字母。数码管通常是由多个LED(发光二极管)组成,每个LED代表一个数字或字母的一部分。数码管根据所需显示的数字或字母,通过控制其中的LED点亮或熄灭来显示相应的符号。
数码管通常分为共阳极和共阴极两种类型。共阳极数码管的所有LED的阳极都连接在一起并提供电源,而每个LED的阴极分开独立连接到控制电路,通过向特定的LED的阴极输入信号来点亮所需的数字或字母。共阴极数码管则相反,所有LED的阴极连接在一起,而每个LED的阳极连接到控制电路。
()
2
从原理分析可知,数码管简单来说就是多个LED灯,要实现数字的显示,就是要让数字对应的LED灯进行闪烁,假如每个引脚对应一个LED灯的话,不免有些占用资源,因而数码管通过并行数据输出,使得单片机能够大大地节省硬件资源。
(三)syscfg配置介绍
syscfg是一个系统配置工具,用于配置和管理嵌入式系统的各种参数和设置。syscfg工具可以帮助开发人员在CCS中轻松地配置系统的各种参数,包括时钟设置、引脚配置、外设功能等。通过syscfg工具,开发人员可以直观地查看和调整系统的配置信息,以满足不同的应用需求。这次我使用的软件是CCS THEIA系列,接下来我将来简单介绍引脚的配置教程与工作。
GPIO配置
配置相应引脚,如下图所示,注意配置时要配成输出模式
2.定时器配置
因为要实现数码管从10到1依次递减,每秒减1。可以想到用delay函数实现,不过更优的解决方法应该是配置定时器,利用定时中断来更改数码管上显示的值。配置如下,注意要选择周期性,向下递减,归零中断,别忘了使能中断。
(四)代码编写
1.引脚配置宏定义展示
/* Defines for TIMER_0 */ #define TIMER_0_INST (TIMG0) #define TIMER_0_INST_IRQHandler TIMG0_IRQHandler #define TIMER_0_INST_INT_IRQN (TIMG0_INT_IRQn) #define TIMER_0_INST_LOAD_VALUE (39999U) /* Port definition for Pin Group HC595 */ #define HC595_PORT (GPIOA) /* Defines for DIO: GPIOA.27 with pinCMx 28 on package pin 31 */ #define HC595_DIO_PIN (DL_GPIO_PIN_27) #define HC595_DIO_IOMUX (IOMUX_PINCM28) /* Defines for SCLK: GPIOA.26 with pinCMx 27 on package pin 30 */ #define HC595_SCLK_PIN (DL_GPIO_PIN_26) #define HC595_SCLK_IOMUX (IOMUX_PINCM27) /* Defines for RCLK: GPIOA.13 with pinCMx 14 on package pin 17 */ #define HC595_RCLK_PIN (DL_GPIO_PIN_13) #define HC595_RCLK_IOMUX (IOMUX_PINCM14) /* Defines for TEST: GPIOA.0 with pinCMx 1 on package pin 1 */ #define HC595_TEST_PIN (DL_GPIO_PIN_0) #define HC595_TEST_IOMUX (IOMUX_PINCM1)
2.核心代码展示
#include "ti_msp_dl_config.h" //dat -- PA27 : 串行数据输入 //SCLK-- PA26 :移位时钟 //RCLK-- PA13 :并行寄存器锁存时钟 // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, b, C, d, E, F uint8_t Disp_DX[ 16 ]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //段显 uint8_t Disp_PX[ 8 ]={1,2,3,4,5,6,7,8}; //片选 //uint8_t Disp_DX[] = { 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x77, 0x83, 0xC6, 0xA1, 0x86, 0x8E, 0xFF, 0xBF } #define HC595_DAT(x) ((x)?(DL_GPIO_setPins(HC595_PORT, HC595_DIO_PIN)) : (DL_GPIO_clearPins(HC595_PORT, HC595_DIO_PIN))) #define HC595_CLK(x) ((x)?(DL_GPIO_setPins(HC595_PORT, HC595_SCLK_PIN)) : (DL_GPIO_clearPins(HC595_PORT, HC595_SCLK_PIN))) #define HC595_RCK(x) ((x)?(DL_GPIO_setPins(HC595_PORT, HC595_RCLK_PIN)) : (DL_GPIO_clearPins(HC595_PORT, HC595_RCLK_PIN))) #define LED(x) ((x)?(DL_GPIO_setPins(HC595_PORT, HC595_TEST_PIN)) : (DL_GPIO_clearPins(HC595_PORT, HC595_TEST_PIN))) uint8_t TimerCnt=0,TmpVal; void Display_Out() { HC595_RCK(0); delay_cycles(100); HC595_RCK(1); delay_cycles(100); } void HC595_WriteData(uint8_t data) { uint8_t i; for(i = 0; i < 8; i++) { if((data & 0x80)>0){ HC595_DAT(1); } else { HC595_DAT(0); } data <<= 1; delay_cycles(100); HC595_CLK(0); delay_cycles(100); HC595_CLK(1); delay_cycles(100); } } //发送一个数字(0-9)到指定位的数码管 //dis_num 发送的数字(0-9) //dis_bit 发送到第几个数码管,即:片选(0-7) void HC595_SEND_DATA(uint8_t disp_num, uint8_t disp_bit) { HC595_WriteData(disp_num); HC595_WriteData(1<<disp_bit); Display_Out(); } //数码管同时显示8位数字 void Disp_Data(uint16_t dataH, uint16_t dataL) { uint16_t tempH,tempL; uint8_t num_q, num_b,num_s,num_g; tempL = dataL; num_q = tempL/1000; num_b = tempL/100%10; num_s = tempL/10%10; num_g = tempL%10; HC595_SEND_DATA(Disp_DX[num_q],3); HC595_SEND_DATA(Disp_DX[num_b],2); HC595_SEND_DATA(Disp_DX[num_s],1); HC595_SEND_DATA(Disp_DX[num_g],0); tempH = dataH; num_q = tempH/1000; num_b = tempH/100%10; num_s = tempH/10%10; num_g = tempH%10; HC595_SEND_DATA(Disp_DX[num_q],7); HC595_SEND_DATA(Disp_DX[num_b],6); HC595_SEND_DATA(Disp_DX[num_s],5); HC595_SEND_DATA(Disp_DX[num_g],4); } /* This results in apprximately 0.5s of delay assuming 32MHz CPU_CLK */ #define DELAY (16000000) int main(void) { TmpVal = 10; SYSCFG_DL_init(); NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN); while (1) { LED(0); Disp_Data(0000,TmpVal); } } void TIMER_0_INST_IRQHandler(void) //1s进一次中断 { switch(DL_Timer_getPendingInterrupt(TIMER_0_INST)){ case DL_TIMER_IIDX_ZERO: TimerCnt ++; if(TimerCnt == 1) { TimerCnt = 0; TmpVal --; if(TmpVal == 0) { TmpVal = 10; } } break; default: break; } }
(五)总结
学习利用MSPM0单片机让数码管从10到0依次递减显示,我觉得这个过程非常有趣。在这个过程中,我学会了如何使用单片机来控制数码管的显示,在编写程序的过程中,我也深入了解了单片机的工作原理和编程语言。
通过这个实践项目,我不仅提升了自己的编程能力,还加深了对数字电路和单片机原理的理解。在实现从10到0递减显示的过程中,我收获了不少乐趣,同时也更加熟练掌握了单片机的应用技能。这种实践性的学习方式让我更加深入地了解了硬件编程的技术。
总的来说,通过这个项目的学习,我觉得学到了很多知识和技能,也找到了更多的兴趣点。希望能够继续探索硬件编程领域,不断提升自己的技能水平。