一、功能需求
使用定时器中断,实现数码管显示数值的从10到0的递减,递减步长为1s
二、数码管驱动原理
数码管按段数分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元(多一个小数点显示);
按发光二极管单元连接方式分为共阳极数码管和共阴极数码管。
共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管。
共阳数码管在应用时应将公共极COM接到+5V,当某一字段发光二极管的阴极为低电平时,相应字段就点亮。当某一字段的阴极为高电平时,相应字段就不亮。
共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管。
共阴数码管在应用时应将公共极COM接到地线GND上,当某一字段发光二极管的阳极为高电平时,相应字段就点亮。当某一字段的阳极为低电平时,相应字段就不亮。
单位数码管有十个管脚,其中有8根是用来点亮a,b,c,d,e,f,dp 共8个发光二极管(原理中有介绍),3,8两个管脚为公共COM脚,它们相连通且作用相同,可接任意一根。
共阴, 共阳:
接线图:
三、软件原理
硬件连接上使用3个GPIO口作为输出,1个数据位输出,2个为时钟输出(因为时钟和锁存输出时钟)。供电使用开发板上的3v3,共5根线其接法如下图
由于要求定时从10减到0,这里我采用定时器去更新数码管的显示内容,定时1s,num自减,定时器配置如下:
驱动显示函数:
uint8_t LED_0F[] =
{// 0 1 2 3 4 5 6 7 8 9 A b C d E F -
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x8C,0xBF,0xC6,0xA1,0x86,0xFF,0xbf,0xff
};
// 全局变量
uint8_t LED[8]={0,1,17,17,17,17,17,17}; //用于LED的8位显示缓存
void LED8_Display (void)
{
uint8_t *led_table; // 查表指针
uint8_t i;
//显示第1位
led_table = LED_0F + LED[0];
i = *led_table;
LED_OUT(i);
LED_OUT(0x01);
RCLK_RESET;
RCLK_SET;
//显示第2位
led_table = LED_0F + LED[1];
i = *led_table;
LED_OUT(i);
LED_OUT(0x02);
RCLK_RESET;
RCLK_SET;
//显示第3位
led_table = LED_0F + LED[2];
i = *led_table;
LED_OUT(i);
LED_OUT(0x04);
RCLK_RESET;
RCLK_SET;
//显示第4位
led_table = LED_0F + LED[3];
i = *led_table;
LED_OUT(i);
LED_OUT(0x08);
RCLK_RESET;
RCLK_SET;
//显示第5位
led_table = LED_0F + LED[4];
i = *led_table;
LED_OUT(i);
LED_OUT(0x10);
RCLK_RESET;
RCLK_SET;
//显示第6位
led_table = LED_0F + LED[5];
i = *led_table;
LED_OUT(i);
LED_OUT(0x20);
RCLK_RESET;
RCLK_SET;
//显示第7位
led_table = LED_0F + LED[6];
i = *led_table;
LED_OUT(i);
LED_OUT(0x40);
RCLK_RESET;
RCLK_SET;
//显示第8位
led_table = LED_0F + LED[7];
i = *led_table;
LED_OUT(i);
LED_OUT(0x80);
RCLK_RESET;
RCLK_SET;
}
void LED_OUT(uint8_t X)
{
uint8_t i;
for(i=8;i>=1;i--)
{
if (X&0x80)
{
DIO_SET;
}
else
{
DIO_RESET;
}
X<<=1;
SCLK_RESET;
SCLK_SET;
}
}
主函数:
#include "ti_msp_dl_config.h"
#include "HC595.h"
#include "Delay.h"
int8_t num=10;
int main(void)
{
SYSCFG_DL_init();
NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN);
DL_TimerG_startCounter(TIMER_0_INST);
while (1) {
LED8_Display ();
}
}
//定时实现10到0递减
void TIMER_0_INST_IRQHandler(void)
{
num--;
if(num<0)num=10;
LED[1]=num/10;
LED[0]=num%10;
if(LED[1]==0)LED[1]=17;
DL_GPIO_togglePins(GPIO_LED_PORT,GPIO_LED_LED1_PIN);
}
效果