数码管工作原理:
数码管是一种半导体发光器件,其基本单元是发光二极管。能显示4位数字的叫四位数码管,当然也有多位和只有一位的数码管,他们的电气原理相同。
数码管按段数分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元(多一个小数点显示);
按发光二极管单元连接方式分为共阳极数码管和共阴极数码管。
共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管。
共阳数码管在应用时应将公共极COM接到+5V,当某一字段发光二极管的阴极为低电平时,相应字段就点亮。当某一字段的阴极为高电平时,相应字段就不亮。
共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管。
共阴数码管在应用时应将公共极COM接到地线GND上,当某一字段发光二极管的阳极为高电平时,相应字段就点亮。当某一字段的阳极为低电平时,相应字段就不亮。
单位数码管有十个管脚,其中有8根是用来点亮a,b,c,d,e,f,dp 共8个发光二极管(原理中有介绍),3,8两个管脚为公共COM脚,它们相连通且作用相同,可接任意一根。
共阴, 共阳:
码表:
驱动方式
1、静态驱动也称直流驱动。静态驱动是指每个数码管的每一个段码都由一个单片机的I/O端口进行驱动,或者使用如BCD码二-十进制译码器译码进行驱动。静态驱动的优点是编程简单,显示亮度高,缺点是占用I/O端口多,如驱动5个数码管静态显示则需要5×8=40根I/O端口来驱动,要知道一个89S51单片机可用的I/O端口才32个呢:),实际应用时必须增加译码驱动器进行驱动,增加了硬件电路的复杂性。
2、数码管动态显示接口是单片机中应用最为广泛的一种显示方式之一,动态驱动是将所有数码管的8个显示笔划"a,b,c,d,e,f,g,dp"的同名端连在一起,另外为每个数码管的公共极COM增加位选通控制电路,位选通由各自独立的I/O线控制,当单片机输出字形码时,所有数码管都接收到相同的字形码,但究竟是那个数码管会显示出字形,取决于单片机对位选通COM端电路的控制,所以我们只要将需要显示的数码管的选通控制打开,该位就显示出字形,没有选通的数码管就不会亮。通过分时轮流控制各个数码管的的COM端,就使各个数码管轮流受控显示,这就是动态驱动。在轮流显示过程中,每位数码管的点亮时间为1~2ms,由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O端口,而且功耗更低。
我们这里采用共阳的一个74HC595驱动数码管模块,
8位数码管由两片HC595芯片驱动,一片HC595芯片负责接收串行数据输入,作为位选数据用于驱动单个数码管进行显示。高八位数据串行输入到另一片HC595芯片,作为片选数据。当数据传输完毕后,在RCLK引脚上给予不小于2us的上升沿,按照数据的内容点亮某一位数码管。
原理图:
输出使能不用控制,只需要控制串行数据输入,移位寄存器时钟输入,锁存器时钟输入。
时序图:
接线图:
2. 关键软件代码
GPIO 配置:
配置定时器:直接可以设置定时多长时间,还是很方便的。
代码:
//dat -- PA27 : 串行数据输入
//SCLK-- PA26 :移位时钟
//RCLK-- PA13 :并行寄存器锁存时钟
#define HC595_PORT (GPIOA)
#define HC595_DIO_PIN (DL_GPIO_PIN_27)
#define HC595_SCLK_PIN (DL_GPIO_PIN_26)
#define HC595_RCLK_PIN (DL_GPIO_PIN_13)
#define HC595_TEST_PIN (DL_GPIO_PIN_0)
// 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}; //片选
#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,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)
{
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);
}
void TIMER_0_INST_IRQHandler(void)
{
switch(DL_Timer_getPendingInterrupt(TIMER_0_INST)){
case DL_TIMER_IIDX_ZERO:
TimerCnt ++;
if(TimerCnt >= 100)
{
TimerCnt = 0;
TmpVal --;
if(TmpVal == 0)
{
TmpVal = 10;
}
}
break;
default:
break;
}
}
int main(void)
{
SYSCFG_DL_init();
TmpVal = 10;
NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN);
while (1) {
/*
DL_GPIO_setPins(LED_RED_PORT_PORT, LED_RED_PORT_LED_RED_PIN_PIN); //PA0= 1;
DL_GPIO_clearPins(LED_RED_PORT_PORT, LED_GREEN_PORT_LED_GREEN_PIN_PIN | LED_BLUE_PORT_LED_BLUE_PIN_PIN); //PA0= 0;
delay_cycles(48000000);
DL_GPIO_setPins(LED_RED_PORT_PORT, LED_GREEN_PORT_LED_GREEN_PIN_PIN); //PA0= 1;
DL_GPIO_clearPins(LED_RED_PORT_PORT, LED_RED_PORT_LED_RED_PIN_PIN | LED_BLUE_PORT_LED_BLUE_PIN_PIN); //PA0= 0;
delay_cycles(48000000);
DL_GPIO_setPins(LED_RED_PORT_PORT, LED_BLUE_PORT_LED_BLUE_PIN_PIN); //PA0= 1;
DL_GPIO_clearPins(LED_RED_PORT_PORT, LED_RED_PORT_LED_RED_PIN_PIN | LED_GREEN_PORT_LED_GREEN_PIN_PIN); //PA0= 0;
delay_cycles(48000000);
*/
//LED(0);
//Disp_Data(1234,5678);
Disp_Data(0, TmpVal);
// LED(1);
// delay_cycles(32000000);
}
}
3. 实现效果
4.课程地址
http://v.eepw.com.cn/video/playlist/id/6312
5. 注意事项
74HC595 模块13引脚 需要重新接地。