目录
1 项目功能
2 电路原理
3 动态显示原理
4 示例代码
6 扩展功能
7 参考资源
4位数码管动态显示
一位八段式数码管内部有8个LED,习惯上称为a,b,c,d,e,f,g,dp,排列顺序如上图所示。根据公共端的接法不同,分为共阳极数码管和共阴极数码管两类。如果要显示3,就要点亮对应的a,b,c,d,g等5个LED。
数码管的8个LED刚好对应一个字节。为了编程方便,我们把显示的字形对应的字形码列表如下,表中h对应dp。
如果需要多位数码管,有两种形式,一种是采用4个单独的数码管,每个数码管需要8根IO线来控制,4个数码管共需要32个IO口线。这种方式每个数码管都是独立控制,称为静态显示电路。优点是编程比较方便,但缺点也很明显,需要占用比较多的口线。另外一种方式是把4个数码管的字形控制引脚并联连接,比如掌上实验室V8采用4位共阳数码管的内部电路如下图所示。
这种电路优点是所需IO口线少,4根位控线+8根段控线,总共只需12根IO口线;由于4个数码管共用8根段控线,所以不能同时显示4个不同的内容。这时候需动态扫描显示。
例如我们想显示1234,由于不能同时显示,就采用扫描的办法。先在第1位显示1,然后在第2位上显示2,接着在第3位上显示3,最后在第4位上显示4。然后就动画一样循环显示。
由于人眼视觉暂留效应,当循环速度很快时,实际人眼看到的是如下图所示,亮度变成了平均亮度,会感觉变暗。
这种显示方式需要一直刷新,所以程序设计和静态显示比会稍微复杂一些。
刷新流程如下:
#include "at32f403a_407_conf.h"
//端口初始化
void gpio_pins_init(void)
{
//打开GPIO时钟
crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE);
//配置PD2~PD5, PE0~PE7为输出
gpio_init_type gpio_init_struct;
gpio_init_struct.gpio_pins = GPIO_PINS_0 | GPIO_PINS_1 | GPIO_PINS_2 | GPIO_PINS_3 | GPIO_PINS_4 | GPIO_PINS_5 | GPIO_PINS_6 | GPIO_PINS_7;
gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init(GPIOE, &gpio_init_struct);
gpio_init_struct.gpio_pins = GPIO_PINS_2 | GPIO_PINS_3 | GPIO_PINS_4 | GPIO_PINS_5;
gpio_init(GPIOD, &gpio_init_struct);
}
//显示缓冲区定义
uint8_t disp_buf[4];
//显示整数
void display_dec_int(int num)
{
static uint8_t tab[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
disp_buf[0] = tab[num/1000%10];
disp_buf[1] = tab[num/100%10];
disp_buf[2] = tab[num/10%10];
disp_buf[3] = tab[num%10];
}
//扫描刷新
void display_scan()
{
static int cur_digit = 0;
//全关
gpio_bits_set(GPIOD, GPIO_PINS_2 | GPIO_PINS_3 | GPIO_PINS_4 | GPIO_PINS_5);
//输出字形码
gpio_bits_reset(GPIOE, 0xff); //PE0~PE7 = 0
gpio_bits_set(GPIOE, disp_buf[cur_digit]);
//打开对应位开关
gpio_bits_reset(GPIOD, GPIO_PINS_2 << cur_digit);
//更新cur_digit, 准备下一次扫描
cur_digit = (cur_digit + 1) % 4;
}
int main(void)
{
gpio_pins_init();
display_dec_int(1234);
for(;;){
display_scan();
}
}
我们根据上述原理,增加一个16进制显示的函数和关闭显示的函数
void display_hex_int(int num)
{
static uint8_t tab[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
disp_buf[0] = tab[num/0x1000%16];
disp_buf[1] = tab[num/0x100%16];
disp_buf[2] = tab[num/0x10%16];
disp_buf[3] = tab[num%16];
}
void display_off(void)
{
disp_buf[0] = 0xff;
disp_buf[1] = 0xff;
disp_buf[2] = 0xff;
disp_buf[3] = 0xff;
}
《掌上实验室V8》 原理图
AT32F403A AT32F407 固件库2.0.2 应用说明