GPIO输出应用:数码管
1.前言与基础知识2.GPIO通用输入输出端口3.GPIO输出应用:流水灯
4.GPIO输出应用:数码管
5.GPIO输入应用:按键6.中断7.外部中断应用:按键8.时钟源9.基本计时器TIM4:STM8的定时器/计数器资源综述10.单片机线反转法实现矩阵键盘11.高级计时器TIM1:概述与外部时钟模式实现外部脉冲计数12.高级计时器TIM1:输入捕获功能功能实现信号周期与占空比测量13.高级计时器TIM1:STM8的PWM输出功能实现呼吸灯14.STM8的ADC模数转换器15.嵌入式串行通信导论16.UART异步串行通信协议17.SPI同步串行通信协议18.I2C同步串行通信协议19.STM8的看门狗20.单片机的系统功耗控制/电源模式管理/AWU自动唤醒21.STM8的储存器数码管原理
共阴/共阳结构
- 一位8段数码管集成了8个发光二极管(包括一个方形数字8与一个小数点)若是按一个二极管两个引脚的传统方式进行设计,将会使制造与控制变得很繁琐
- 为了化繁为简,数码管使用共阳极/共阴极结构,一个数码管的8个二极管的阳极/阴极被接在公共端
- 以共阳极结构为例,8个发光二极管的阳极被接在一起,并连接到一个正电源;若某个发光二极管的负极被置为低电平,该发光二极管就会被点亮,共阴结构原理一致,配置相反
段选码
-
由上文可知,通过配置连接数码管中各个二极管的GPIO端口输出高低电平,即可操控数码管中对应二极管亮灭,组成数码字符
-
为保证显示同一数码的引脚电平取值相同,数码管有统一的排列规则:
最上方为a,按顺时针方向排列至f,中间的横杠为g,下方的小数点为dp
-
以共阳结构为例,当与数码管连接的GPIO端口组某一位被配置为0(输出低电平)时,对应二极管亮起:
比如需要显示数字1,即需要b、c段亮起,对应的段选码是0xF9(1111 1001)
为免去重复写入各种配置用十六进制数的麻烦,往往将各个情况对应的位选码、段选码写入数组中,使用时直接选择
unsigned char num[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xa0,0x83,0xc6,0xa1,0x86,0x8e}; //与数字0-9相对应的段选码
显示多位数码管
-
位选码
对于有多位数码管的情况,借助位选信号,开启指定的那一位数码管
例如PE0至PE3连接至数码管的0至3位,想要在第一位显示数字,应该配置PE组输出寄存器位选码为0xFE(1111 1110),使能第一位数码管
与段选码同理,也写成数组,方便选用:
unsigned char bit[] = {0xFE,0xFD,0xFB,0xF7}; //位选码,分别对应1111 1110等数,用以控制数码管不同位,例如OxFE就打开了第0位数码管
-
刷新数码管
位选信号一次只能使能一位数码管,为了显示多位数字,使用刷新数码管的方式:
在主程序中让各位数字轮流循环显示,而切换位的时间得极短,让人难以察觉
代码实现
-
初始化函数
具体的配置取决于电路结构:哪些引脚连接数码管的段选端(一般用字母A-F标记),哪些连接至位选端
void Digit_GPIO_Init() { //位选初始化 PE_DDR = 0x0F;//配置为输出 PE_CR1 = 0x0F;//推挽输出 PE_ODR = 0x0F;//先关闭 //段选初始化 PB_DDR = 0xFF; PB_CR1 = 0xFF; PB_ODR = 0xFF; }
-
刷新数码管
void Display(unsigned char xbit,unsigned char xnum) { PE_ODR |= 0X0F; PE_ODR &= bit[xbit]; PB_ODR = num[xnum]; //传入数字以选择对应要进行显示的位与要显示的数 delay(2); //切换位的时间设定得极短,让人难以察觉,在视觉上认为各个数码管是一齐显示的 PB_ODR = 0xFF;//在显示完成后清除以防残影 }
-
使用方法
//在写好函数后,可以在主程序中直接调用,比如希望显示从第3位到第0位数码管显示2333 unsigned char bit[] = {0xFE,0xFD,0xFB,0xF7}; //位选码,分别对应1111 1110等数,用以控制数码管不同位,例如OxFE就打开了第0位数码管 unsigned char num[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xa0,0x83,0xc6,0xa1,0x86,0x8e}; //与数字0-9相对应的段选码 void Display(unsigned char xbit,unsigned char xnum); main() { //省略具体代码 Display(3,2); Display(2,3); Display(1,3); Display(0,3); while(1); }
本文来自博客园,作者:无术师,转载请注明原文链接:https://www.cnblogs.com/untit1ed/p/18560241
本文使用知识共享4.0协议许可 CC BY-NC-SA 4.0
请注意: 特别说明版权归属的文章以及不归属于本人的转载内容(如引用的文章与图片)除外
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?