ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

【嵌入式成长7】STC89C51数码管|共阴/共阳原理,74HC245、74HC595级联、动态扫描、定时器中断刷新实战

2026/8/25 14:26:51 拓冰建站 浏览量
【嵌入式成长7】STC89C51数码管|共阴/共阳原理,74HC245、74HC595级联、动态扫描、定时器中断刷新实战 一、数码管基础简介数码管可以理解为8个LED封装在一起7段笔画a‑g加上小数点dp。点亮对应段LED就可以显示数字、部分字母。数码管分两大类共阴极、共阳极。类型公共端接法点亮逻辑共阴极全部LED阴极接GND段引脚输出高电平点亮笔画共阳极全部LED阳极接VCC段引脚输出低电平点亮笔画本教程实验硬件使用共阴极数码管。共阴极段码表十六进制显示字符二进制点亮段0x3F000111111abcdef0x06100000110bc0x5B201011011abdeg0x4F301001111abcdg0x66401100110bcfg0x6D501101101acdfg0x7D601111101acdefg0x07700000111abc0x7F801111111abcdefg0x6F901101111abcdfg0x77A01110111abcefg0x7CB01111100cdefg0x39C00111001adef0x5ED01011110bcdeg0x79E01111001adefg0x71F01110001aefg0x00熄灭00000000全部熄灭二、单片机驱动数码管两大问题问题1IO口驱动电流不足51单片机IO拉电流能力弱约1mA直接驱动数码管亮度很低。解决方案三极管放大多路数码管会需要大量分立元件布线繁琐。使用74HC245双向缓冲芯片增强输出驱动电流最高可达7.8mA。74HC245简要说明DIR方向引脚接VCCA输入→B输出。OE#输出使能低电平有效直接接GND一直使能。A0‑A7接单片机IOB0‑B7接数码管a‑dp段脚。简单单数码管代码P2口经过74HC245驱动共阴极数码管#include reg52.h void main(void) { P2 0x06; //输出段码显示数字1 while(1); }循环0‑9静态显示示例#include reg52.h unsigned char seg_table[]{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; void delay_ms(unsigned int xms) //12MHz { unsigned int i, j; for(ixms;i0;i--) { for(j124;j0;j--); } } void main(void) { unsigned char num; while(1) { for(num0;num10;num) { P2 seg_table[num]; delay_ms(500); } } }问题2IO引脚数量不够直接并行驱动多位数码管每增加一位就要占用8根IOIO资源消耗巨大。解决方案74HC595串行转并行移位寄存器。只用3根IO就可以输出8路并行信号芯片支持级联驱动多位数码管。三、74HC595芯片详解关键引脚引脚名称功能14DS串行数据输入11SHCP移位寄存器时钟上升沿移位12STCP锁存寄存器时钟上升沿锁存输出13OE#输出使能低电平有效硬件直接拉低10MR#主复位硬件拉高禁止复位1‑7、15Q0‑Q7并行输出9Q7S串行级联输出接到下一片595的DS工作流程SHCP上升沿把DS引脚数据移入移位寄存器全部8bit移位完成STCP上升沿把移位寄存器数据锁存输出到Q0‑Q7。单块74HC595基础代码引脚定义DS → P0^3STCP → P0^4SHCP → P0^5#include reg52.h sbit ds_pin P0^3; sbit stcp_pin P0^4; sbit shcp_pin P0^5; //共阴极段码表 unsigned char seg_table[]{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //向74HC595发送1字节 void hc595_send_byte(unsigned char byte) { unsigned char i; for(i0;i8;i) { if(byte 0x80) ds_pin 1; else ds_pin 0; shcp_pin 0; shcp_pin 1; //移位时钟上升沿 byte 1; } stcp_pin 0; stcp_pin 1; //锁存上升沿 } void main(void) { while(1) { hc595_send_byte(seg_table[0]); //显示数字0 } }四、74HC595级联驱动两位数码管动态扫描硬件方案两片74HC595级联第一片输出段选数据a‑dp笔画第二片输出位选选择哪一个数码管点亮Q7S级联输出接到后一片DS引脚先发段码再发位选码。人眼视觉暂留原理快速轮流点亮每一位数码管肉眼看上去多位同时亮。注意简单while循环里面用delay做动态扫描一旦主循环有耗时任务数码管就会严重频闪。轮询动态扫描代码阻塞版#include reg52.h sbit ds_pin P0^3; sbit stcp_pin P0^4; sbit shcp_pin P0^5; unsigned char seg_table[]{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; void hc595_send_byte(unsigned char byte) { unsigned char i; for(i0;i8;i) { if(byte 0x80) ds_pin 1; else ds_pin 0; shcp_pin 0; shcp_pin 1; byte 1; } } //seg段码addr位号0/1 void hc595_display(unsigned char seg,unsigned char addr) { hc595_send_byte(seg); if(addr 0) hc595_send_byte(0xFE); //选中第0位 else if(addr 1) hc595_send_byte(0xFD); //选中第1位 stcp_pin 0; stcp_pin 1; } void delay_ms(unsigned int xms) { unsigned int i,j; for(ixms;i0;i--) for(j124;j0;j--); } void main(void) { while(1) { hc595_display(seg_table[0],0); //第一位显示0 delay_ms(1); hc595_display(seg_table[3],1); //第二位显示3 delay_ms(1); } }五、进阶定时器中断实现数码管动态扫描推荐工程写法问题上面阻塞版动态扫描依赖delay延时如果主循环执行按键、传感器读取等耗时业务数码管就会频闪。✅解决把数码管扫描放到定时器中断里面执行定时自动刷新不受主循环业务代码影响。逻辑定时器每隔1‑2ms进一次中断每次只点亮1位数码管中断内部切换扫描下标。#include reg52.h sbit ds_pin P0^3; sbit stcp_pin P0^4; sbit shcp_pin P0^5; //共阴极段码 unsigned char seg_table[]{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; unsigned char disp_buf[2] {0,3}; //显示缓存两位数码管显示数字0、3 unsigned char scan_idx 0; //扫描下标 void hc595_send_byte(unsigned char byte) { unsigned char i; for(i0;i8;i) { if(byte 0x80) ds_pin 1; else ds_pin 0; shcp_pin 0; shcp_pin 1; byte 1; } } //定时器0初始化1ms中断 11.0592M #define TIM_1MS (65536-922) void Timer0_Init(void) { TMOD | 0x01; TH0 TIM_1MS 8; TL0 TIM_1MS; ET0 1; EA 1; TR0 1; } //定时器中断执行数码管动态扫描 void Timer0_ISR(void) interrupt 1 { TH0 TIM_1MS 8; TL0 TIM_1MS; if(scan_idx 0) { hc595_send_byte(seg_table[disp_buf[0]]); hc595_send_byte(0xFE); stcp_pin 0; stcp_pin 1; scan_idx 1; } else { hc595_send_byte(seg_table[disp_buf[1]]); hc595_send_byte(0xFD); stcp_pin 0; stcp_pin 1; scan_idx 0; } } void main(void) { Timer0_Init(); while(1) { //此处可以自由写其他业务按键、传感器读取不会干扰数码管显示 } }六、开发踩坑总结区分共阴极、共阳极两者段码表完全不一样段码写反数码管乱码。51单片机IO拉电流弱直接驱动数码管亮度不足需要74HC245或者三极管驱动。74HC595级联先发段选数据再发位选数据Q7S接到下一级DS引脚。简单whiledelay动态扫描主循环有耗时任务会出现频闪产品项目优先定时器中断刷新数码管。动态扫描刷新频率建议50‑100Hz人眼无明显闪烁中断间隔1‑2ms比较合适。MR#复位引脚、OE#使能引脚硬件电平要正确否则595无输出。七、本章小结数码管本质多个LED组合分清共阴极、共阳极掌握段码表。74HC245用来增强IO驱动电流解决51拉电流不足。74HC595串行转并行少量IO扩展多路输出支持级联节省单片机IO资源。动态扫描利用人眼视觉暂留快速轮询点亮每一位数码管。工程推荐定时器中断做数码管刷新主循环不受阻塞兼容按键、传感器等其他业务。