当前位置: 首页 > news >正文

单片机-STM32部分:17、数码管

飞书文档https://x509p6c8to.feishu.cn/wiki/TOQqweKHWinugokUyqzcwb0fnTd

原理:

一个二极管等于八个LED组合在一起,想要显示什么形状,就点亮对应LED即可。

数码管根据其公共端所接的阳极和阴极的不同,分为了共阴极数码管和共阳极数码管。

共阳极接法:几个二极管的阳极接在一起,接到VCC(高电平),我们要想点亮,只要在在对应的二极管的阴极接上低电平即可。

共阴极接法:几个二极管的阴极接在一起,接到GND(低电平),我们要想点亮,只要在在对应的二极管的阳极接上高电平即可。

这节课,我们将使用共阴极数码管,这也就意味着我们要点亮数码管,要在对应的IO设置输出为高电平。

对于共阴极数码管,8个IO控制如下,就可以点亮对应的数字或字母。

16进制表示显示的数字点亮的位置二进制表示
0x3f0abcdef亮00111111
0x061bc亮00000110
0x5b2abdeg亮01011011
0x4f3abcdg亮01001111
0x664abcdg亮01100110
0x6d5acdfg亮01101101
0x7d6acdefg亮01111101
0x077abc亮00000111
0x7f8abcdefg亮01111111
0x6f9abcdfg亮01101111
0x77Aabcefg亮01110111
0x7cBcdefg亮01111100
0x39Cadef亮00111001
0x5eDbcdeg亮01011110
0x79Eadefg亮01111001
0x71Faefg亮01110001
0x00熄灭全灭00000000

但是这里我们遇到一个问题,点亮一个数码管,需要8个IO,两个数码管则需要16个IO,很多时候,单片机没有这么多IO分配到给这个模块使用,所以我们用两颗74HC595芯片来扩展驱动数码管。

74HC595芯片

该芯片是一个8位串行输入、并行输出的位移缓存器,可以简单理解为用一个IO进行数据输入,可以控制8个IO输出。

SHCP:移位寄存器时钟输入
STCP:存储寄存器时钟输入
DS:串行数据输入
OE:使能,低电平使能
MR: 复位,低电平复位

Q0~Q7:并行输出
Q7S:串行输出

  1. SHCP是上升沿的时候,写入DS的数据,上升沿时移位寄存器中的数据依次移动一位,即 Q0 中的数据移到 Q1 中,Q1 中的数据移到 Q2 中,依次类推
  2. STCP是上升沿的时候,把数据从移位寄存器转存带存储寄存器,应用时通常将 STCP置为低点平,移位结束后再在 ST_CP 端产生一个正脉冲更新显示数据。
  3. 有数据操作的过程中MR必须是高电平,OE必须是低电平,595才能工作。

由74HC595的芯片手册可以知道:74HC595芯片的发送顺序是由Q0,一直到Q7。

本设计使用了一个2位的数码管,为共阴型,为了节省单片机的IO口,使用了两片74HC595作为数码管的驱动芯片,共占用3个IO口。

第一片74HC595芯片的Q7S口,可以向下一片的74HC595芯片的串行输入口输入数据。

第一片74HC595芯片只使用了Q0、Q0两个管脚来管理数码管地址信息。
第二片74HC595芯片是用于控制数码管输出显示。

重要的一点是,先串行输入显示的数据,再串行输入地址。

与单片机相连接的三个脚分别为: DS,STCP,SHCP。

/* USER CODE BEGIN 0 */
void hc595_send_byte(unsigned char byte)
{unsigned int i;for(i = 0; i < 8; i++){//串行输入引脚,所谓串行就是使数据在一根信号线上按顺序一位一位地传输if(byte & 0x80)HAL_GPIO_WritePin(GPIOC,DS_Pin,GPIO_PIN_SET);elseHAL_GPIO_WritePin(GPIOC,DS_Pin,GPIO_PIN_RESET);//SHCP发生一次上升沿的时候,74HC595才会从DS引脚上取得当前的数据HAL_GPIO_WritePin(GPIOC,SHCP_Pin,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOC,SHCP_Pin,GPIO_PIN_SET);byte <<= 1;}
}void hc595_send_data(unsigned char num, unsigned char addr)
{hc595_send_byte(num); //先发需要显示的数字hc595_send_byte(1 << addr);   //再发需要点亮的数码管,这时候数字会被移位到第二个595中点亮//当移位寄存器的8位数据全部传输完毕后,制造一次锁存器时钟引脚的上升沿(先拉低电平再拉高电平)HAL_GPIO_WritePin(GPIOC, STCP_Pin, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOC, STCP_Pin, GPIO_PIN_SET);
}//共阳 数码管数组:0-9
//unsigned char num[]={0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,0x80 ,0x90};
//共阴 数码管数组:0-9
unsigned char num[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};void display()
{hc595_send_data(num[1], 0);hc595_send_data(num[0], 1);
}
/* USER CODE END 0 */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */display();}/* USER CODE END 3 */

参考工程:

参考飞书文档

看完上面的原理讲解,可见数码管的显示实际上不就是每一位数码管在肉眼不可见的频率下不间断地轮流刷新,那直接放在主程序的while(1)循环里不就好了。

对于主函数有耗时任务执行的场景,也可以使用定时器来刷新数码管 。定时器刷新数码管,其一,我们可以不用过多地考虑数码管刷新的频率,因为它的刷新频率在一开始就已经设置了;其二,我们不用担心会有其他的东西干扰数码管刷新,因为我们是将数码管放在定时器中断里刷新的,只要配置的中断优先级足够高,就一定不会有其他的进程干扰数码管刷新!

相关文章:

  • Elasticsearch 分片机制高频面试题(含参考答案)
  • 乡村农家游乐小程序源码介绍
  • 【测试工具】selenium和playwright如何选择去构建自动化平台
  • duxapp 2025-01-13 更新 支持小程序配置文件
  • STC8H系列单片机STC8H_H头文件功能注释
  • 【hot100-动态规划-300.最长递增子序列】
  • Vue3 本地环境 Vite 与生产环境 Nginx 反向代理配置方法汇总【反向代理篇】
  • Python多线程
  • 微信小程序医院挂号系统+SSM开发详解
  • conda更换清华源
  • 音频/AI/BLE/WIFI/玩具/商业等方向的论坛网站总结
  • 【愚公系列】《Manus极简入门》040-科技与组织升级顾问:“项目掌舵人”
  • Flutter——数据库Drift开发详细教程(六)
  • 讯联云库项目开发日志(二)AOP参数拦截
  • Profinet转Ethernet/IP网关模块通信协议适配配置
  • Ubuntu使用Docker搭建SonarQube企业版(含破解方法)
  • 奇妙协同效应,EtherNet IP与PROFINET网关优化半导体生产线
  • [原创](现代Delphi 12指南):[macOS 64bit App开发]: 注意“回车换行“的跨平台使用.
  • 【C++】Module CPP:模块化编程 Demo
  • uniapp,小程序中实现文本“展开/收起“功能的最佳实践
  • 钕铁硼永磁材料龙头瞄准人形机器人,正海磁材:已向下游客户完成小批量供货
  • 时隔3年俄乌直接谈判今日有望重启:谁参加,谈什么
  • 车载抬头显示爆发在即?业内:凭借市场和产业链优势,国内供应商实现反超
  • 男子不满和睦家医院手术效果还遇到了“冒牌医生”?院方回应
  • 吉林:消纳绿电,“氢”装上阵
  • 工人日报评规范隐藏式车门把手:科技美学须将安全置顶