1. 什么是数码管?
一位LED数码管的实物外形如图所示,它将a、b、c、d、e、f、g、dp共8个LED排成图示的 “8.” 字形,通过让a、b、c、d、e、f、g不同的段发光来显示数字0~9。
8个LED共有16个引脚,为了减少数码管的引脚数,在数码管内部将8个LED的正极或负极引脚连接起来,接成一个公共端(COM 端),根据公共端是LED的正极还是负极,可分为共阳极接法(正极相连)和共阴极接法(负极相连)。
对于共阳极接法的数码管,需要给段极加低电平才能使其发光;而对于共阴极接法的数码管,需要给段极加高电平才能使其发光。
如果你的数码管是一个共阴极接法的数码管,如果让它显示一个数字“5”,那么需要给a、c、d、f、g引脚加高电平(即这些引脚为1),给b、e引脚加低电平(即这些引脚为0),这样a、c、d、f、g段的LED有电流通过而发光,b、e段的LED不发光,数码管就会显示出数字“5”。
1.1多位LED数码管
4位LED数码管,它有两排共12个引脚,其内部LED有共阳极和共阴极两种连接方式,如图⑫、⑨、⑧、⑥脚分别为各位数码管的公共极,⑪、⑦、④、②、①、⑩、⑤、③脚同时接各位数码管的相应段,称为段极。
1.2 显示原理
多位LED数码管的显示既可采用直接控制各段发光的静态显示方式,也可采用动态驱动方式,又称扫描显示。
4位LED数码管内部LED的连接方式:
先给数码管的脚加一个低电平(⑨、⑧、⑥脚为高电平),再给⑦、④脚加高电平(⑪、②、①、⑩、⑤脚均为低电平),结果第1位的B、C段LED点亮,第1位显示“1”,由于⑨、⑧、⑥脚均为高电平,故第2、3、4位中的所有LED均无法导通而不显示;然后给⑨脚加一个低电平(⑫、⑧、⑥脚为高电平),给⑪、⑦、②、①、⑤脚加高电平(④、⑩脚为低电平),第2位的A、B、D、E、G段LED点亮,第2位显示“2”,同样原理,在第3位和第4位分别显示数字“7”、“8”。
多位数码管的数字虽然是一位一位地显示出来的,但人眼具有视觉暂留特性(所谓视觉暂留特性是指当人眼看见一个物体后,如果物体消失,人眼还会觉得物体仍在原位置,这种感觉保留约0.04s的时间),所以当数码管显示到最后一位数字“8”时,人眼会感觉前面3位数字还在显示,故看起来好像是一下子显示“1278”4位数。
2. 什么是TM1624?
TM1624 是一款 3 线串口共阴极 11 段 7 位
或 14 段 4 位
的 LED 驱动控制专用电路LED(发光二极管显示)驱动控制专用电路,内部集成有MCU 数字接口、数据锁存器、LED 高压驱动等电路。本产品性能优良,质量可靠。主要应用于VCR、VCD、DVD 及家庭影院等产品的显示屏驱动。采用SOP24、SDIP24的封装形式。
- 品 牌: TM(天微)
- 厂家型号: TM1624
- 封装: SOIC-24-300mil
2.1 管脚定义
2.2 管脚功能定义
2.3 驱动共阴极数码管
2.4 程序设计流程图
采用地址自动加1的程序设计流程图
3. 电路原理图
3.1 单片机最小系统
DIN — PC3
CLK — PC4
STB — PC5
还可以用多位(C5、C6)配置后,单独控制显示LED灯,用作特殊效果,电路如下所示。
3.2 数码管驱动电路
0.32英寸4位草绿色数码管led七段显示器翠绿光四位CS3241AGG共阴
1、字位数:4位
2、屏幕尺寸:0.32英寸
3、发光颜色:红色;黄色;黄绿色;橙色;蓝色;翠绿色;白色
4、8字高度: 0.36
5、外形尺寸:28.0mm×11.0mm×5.0mm
6、公共脚: 12 9 8 6
7、总PIN数:12pins
4. 程序实现
tm1624.c
tm1624.c
#include "hk32f030m.h"
//亮灯个数ledsw[0/1/6/7/8/9] 亮5颗灯:ledsw[9]=0x1F=0001 1111
const unsigned char ledsw[11] = {0x00,0x01,0x02,0x06,0x0E,0x1E,0x03,0x07,0x0F,0x1F};
const unsigned char CODE[25]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0xBF,0X86,0XDB,0XCF,0XE6,0XED,0XFD,0X87,0XFF,0XEF,
0x71, //20 -- 'F' CODE[20]=0X71
0x77, //21 -- 'A'
0x3E, //22 -- 'U'
0X40, //23 -- ‘-’ CODE[23]=0X40=0100 0000 (dp-'G'-F-E-D-C-B-A)
0X00, //24 -- 不显示
};
//共阴数码管0~9 FHU字型码,不带小数点
//{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}
//共阴数码管0~9 FHU字型码,带小数点
//{0xBF,0X86,0XDB,0XCF,0XE6,0XED,0XFD,0X87,0XFF,0XEF}
/*
s[0] = 11 即CODE[11] -> 0X86 -> 带小数点dp的‘1’
s[1] = 12
s[2] = 13
s[3] = 14
CODE[s[0]]
CODE[s[1]]
CODE[s[2]]
CODE[s[3]]
*/
static void delay(unsigned int j)
{
unsigned int i;
for(i=0;i<j;i++)
{
}
}
//1624初始化函数
void TM1624_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); //使能GPIOC时钟
//输出配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_1;
//PC3-4-5输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5; // DIN PC3 CLK PC4 STB PC5
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
//发送8bit数据,从低位开始
//参数 dat对应数据
static void send_8bit(unsigned char dat) //发送8bit数据,从低位开始
{
unsigned char i;
for(i=0;i<8;i++)
{
GPIOC->ODR=0<<4; // PC4 CLK 低
if(dat&0x01)
GPIOC->ODR=1<<3; // PC3 DIN 高
else
GPIOC->ODR=0<<3; // PC3 DIN 低
delay(10);
GPIOC->ODR=1<<4; // PC4 CLK 高 1bit数据在时钟的上升沿操作
dat >>= 1;
}
GPIOC->ODR=0<<4; // PC4 CLK 低
GPIOC->ODR=0<<3; // PC3 DIN 低
}
static void send_command(unsigned char cmd) //发送命令字节
{
GPIOC->ODR=1<<5; //STB置高 PC5
delay(10);
GPIOC->ODR=0<<5; //STB置低
send_8bit(cmd); //发送8bit数据
}
//1624刷新函数
//功能 设置数码管显示的数字和led显示个数
//参数 *s 四位数码管要显示的数字 *led 要显示的led 个数(此实验没用到)
//返回 void
//调度周期 5ms
void digital_display_update(unsigned char *s,unsigned char *led) //????,1~4??????0~9
{
send_command(0x02); //显示模式设置(00):6位12段模式(10) (即:00 ---- 10)
send_command(0x40); //数据命令设置(01):测试模式设置为普通模式(0)--地址模式设置为地址自加(0)--读写模式(00) (即:01 -- 0 0 00)
send_command(0xC0); //地址设定(11):设置显示模式,从00H开始(0000) (即:11 -- 0000)
send_8bit(CODE[s[0]]); //第1个数码管grid1 低字节 seg1-seg8 digital_tmp[0] = 22 / 20 / 21 /24 即CODE[23]=0X40=0100 0000 (dp-'G'-F-E-D-C-B-A)
send_8bit(0x00); //grid1 高字节 seg9-seg14
send_8bit(CODE[s[1]]); //第2个数码管grid2 低八位(左):seg1-seg8
send_8bit(0x00); //第2个数码管grid2 高八位(右): seg9-seg14
send_8bit(CODE[s[2]]); //第3个数码管grid3
send_8bit(0x00); //grid3 高字节 seg9-seg14
send_8bit(CODE[s[3]]); //第4个数码管grid4
send_8bit(0x00); //grid3 高字节 seg9-seg14
send_8bit(ledsw[led[0]]); // YG1-YG5 左侧功率显示LED led_tmp[0] = 0 / 1 / 6 / 7 / 8 / 9 例亮5颗灯:ledsw[9]=0x1F=0001 1111
send_8bit(0x00); // grid3 高字节 seg9-seg14
send_8bit(ledsw[led[1]]); // YG6-YG10 右侧燃油显示LED
send_8bit(0x00); // grid3 seg9-seg14
// 清空显示RAM(对所有RAM写0)
send_command(0x8A); //显示控制指令设置(10),打开显示(1)并设置占空比4/16 (010) (即:10 -- 1 010)
GPIOC->ODR=1<<5;
}
tm1624.h
#ifndef __tm1624_h
#define __tm1624_h
void TM1624_Init(void);
void digital_display_update(unsigned char *s,unsigned char *led);
#endif
main.c
#include "main.h"
#include "hk32f030m.h"
#include "hk32f030m_gpio.h"
#include <stdio.h>
#include "stdarg.h"
#include "tm1624.h"
unsigned char digital_tmp[4],led_tmp[2];
static void softWareDelay(unsigned int delayTime);
int main(void)
/* Infinite loop */
{
static uint32_t counter = 0;
TM1624_Init();
// digital_tmp[0] = 1; // 四位数码管第1位显示的内容(左->右)
// digital_tmp[1] = 2; // 四位数码管第2位显示的内容
// digital_tmp[2] = 3; // 四位数码管第3位显示的内容
// digital_tmp[3] = 4; // 四位数码管第4位显示的内容
led_tmp[0] = 0;// 无关数码管,其他作用
while (1)
{
digital_tmp[0] = counter/1000%10; // 千位:四位数码管第1位显示的内容(左->右)
digital_tmp[1] = counter/100%10; // 百位:四位数码管第2位显示的内容
digital_tmp[2] = counter/10%10; // 十位:四位数码管第3位显示的内容
digital_tmp[3] = counter%10; // 个位:四位数码管第4位显示的内容
if(counter >= 10000){counter = 0;}
// for(int i=0; i<3; i++)
// {if(digital_tmp[i]<=0){digital_tmp[i]=24;}}
//设置四位数码管前面千/百/十位不要显示0
if(digital_tmp[0] <= 0 && counter < 1000){digital_tmp[0]=24;} // CODE[24] 是 0X00 不显示
if(digital_tmp[1] <= 0 && counter < 100){digital_tmp[1]=24;}
if(digital_tmp[2] <= 0 && counter < 10){digital_tmp[2]=24;}
digital_display_update(digital_tmp,led_tmp);//显示函数
counter++;
softWareDelay(500);
}
}
/*****************系统上电延时函数************************/
static void softWareDelay(unsigned int delayTime)
{
unsigned int i;
unsigned int j;
for(i=0;i<delayTime;i++)
{
for(j=0;j<1000;j++)
{
__NOP();
}
}
}
显示小数
// 显示小数
void CountData_FDeal(float counter)
{
uint32_t num = 0;
unsigned char digital_tmp[4],led_tmp[2];
num = (uint32_t)(counter * 10);// 扩大十倍,将小数位的第一位设置为个位,数码管显示范围0.0~999.9
digital_tmp[0] = num/1000%10; // 百位:四位数码管第1位显示的内容(左->右)
digital_tmp[1] = num/100%10; // 十位:四位数码管第2位显示的内容
digital_tmp[2] = num/10%10+10; // 个位:四位数码管第3位显示的内容 加小数点
digital_tmp[3] = num%10; // 小数位:四位数码管第4位显示的内容
//设置四位数码管前面千/百/十位不要显示0
if(digital_tmp[0] <= 0 && num < 1000){digital_tmp[0]=24;} // CODE[24] 是 0X00 不显示
if(digital_tmp[1] <= 0 && num < 100){digital_tmp[1]=24;}
if(digital_tmp[2] <= 0 && num < 10){digital_tmp[2]=24;}
digital_display_update(digital_tmp,led_tmp);//显示函数
}
5. 实现效果
0.32英寸翠绿光四位CS3241AGG共阴数码管
HK32F030MF4P6 驱动四位数码管显示