特殊数码管使用方式
常用数码管
在嵌入式系统实际应用中,我们会接触到很多的元器件,初学时期,只会以市面最常见的12脚4位数码管进行学习,因为这能使大家以最快的速度了解到数码管点亮逻辑,例如12、9、8、6这几个引脚通常作为位选引脚,修改指定引脚的电平,代表想要点亮或熄灭硬件上的第几位,而剩余引脚分别对应了数码管中的每一个笔画。而对于下图中的数码管,想要点亮某一个位上的某一个段,就必须先使位选引脚的电平为低电平,对应段的引脚为高电平,同时,为了防止其他位上的段被点亮,应该使剩余3个引脚电平拉高,这样,你就可以控制最基本的4位数码管了。
代码示例
/***********七段数码管定义***********/
#define SegA 0x01 // 段A
#define SegB 0x02 // 段B
#define SegC 0x04 // 段C
#define SegD 0x08 // 段D
#define SegE 0x10 // 段E
#define SegF 0x20 // 段F
#define SegG 0x40 // 段G
#define SegH 0x80 // 段H
/***********七段数码管数字及字母显示定义***********/
#define Num0 SegA + SegB + SegC + SegD + SegE + SegF // 数字0
#define Num1 SegB + SegC // 数字1
#define Num2 SegA + SegB + SegD + SegE + SegG // 数字2
#define Num3 SegA + SegB + SegC + SegD + SegG // 数字3
#define Num4 SegB + SegC + SegF + SegG // 数字4
#define Num5 SegA + SegC + SegD + SegF + SegG // 数字5
#define Num6 SegA + SegC + SegD + SegE + SegF + SegG // 数字6
#define Num7 SegA + SegB + SegC // 数字7
#define Num8 SegA + SegB + SegC + SegD + SegE + SegF + SegG // 数字8
#define Num9 SegA + SegB + SegC + SegD + SegF + SegG // 数字9
#define NumA SegA + SegB + SegC + SegE + SegF + SegG // 字母A
#define NumB SegC + SegD + SegE + SegF + SegG // 字母B
#define NumC SegA + SegD + SegE + SegF // 字母C
#define NumD SegB + SegC + SegD + SegE + SegG // 字母D
#define NumE SegA + SegD + SegE + SegF + SegG // 字母E
#define NumF SegA + SegE + SegF + SegG // 字母F
#define NumO SegA + SegB + SegF + SegG // 字母o
///*num1 位选
///*num2 段选
void DisplayDigi(char num1,char num2)
{
switch(num1)
{
case 0:
{
P_Digi1 = 0;break;
}
case 1:
{
P_Digi2 = 0;break;
}
case 2:
{
P_Digi3 = 0;break;
}
case 3:
{
P_Digi4 = 0;break;
}
}
p_DigiA=(num2 >> 0) & 1;
p_DigiB=(num2 >> 1) & 1;
p_DigiC=(num2 >> 2) & 1;
p_DigiD=(num2 >> 3) & 1;
p_DigiE=(num2 >> 4) & 1;
p_DigiF=(num2 >> 5) & 1;
p_DigiG=(num2 >> 6) & 1;
p_DigiH=(num2 >> 7) & 1;
}
8脚4位数码管
这是一种在学习过程中比较少见的4位数码管,而在嵌入式开发实际应用中,这种数码管以节省引脚资源的优点,被众多硬件开发工程师选用,而这种即非共阴极也非共阳极的4位数码管,控制逻辑就比较麻烦。
首先,你必须对芯片引脚的输入输出IO口进行配置,当Com设置为输出时,其余不想选中的IO口设置为输入(高阻态),代表选中了某一位数码管,再对拉高或者拉低该引脚的电平。
其次,想要点亮指定段,除了以上步骤还需要将段选引脚设置为输出,当段选引脚与位选引脚的电平一致时,指定段关闭,不一致时,指定段点亮。譬如:COM1 = COM1PINOUT; pinA = pinAOUT; COM1UP;pinADOWN;表示第一位数码管的A段点亮。COM1 = COM1PINOUT; pinA = pinAOUT; COM1DOWN;pinADOWN;表示第一位数码管的A段熄灭。而想点亮四位数码管,逻辑与普通12脚数码管类似,采用人眼视觉残留效应,以极快速度分别点亮指定段来给人一种同时点亮的效果。注意:下面原理图中COM4有8个段选,其中DP6表示数码管的冒号。
代码示例
//IO口初始化函数,应当在每一个段点亮后调用一次,防止下一段点亮时,上一段仍保持,产生误亮。
void DisInit()
{
P_SegA_IN;
P_SegB_IN;
P_SegC_IN;
P_SegD_IN;
P_SegE_IN;
P_SegF_IN;
P_SegG_IN;
P_SegH_IN;
P_Digi4_IN;
P_Digi3_IN;
P_Digi2_IN;
P_Digi1_IN;
}
void DisplayDigi()
{
static unsigned char seg = 0; // 当前扫描段索引(A=0, B=1...H=7)
static unsigned char dig = 0; // 当前扫描数码管(0-3对应DisBuf[0]-[3])
// 消隐所有数码管
P_Digi1 = P_Digi2 = P_Digi3 = P_Digi4 = 0;
switch(seg)
{
// 处理A-D段(低电平有效)
case 0: case 1: case 2: case 3:
{
if(DisBuf[dig] & (1 << seg))
{
// 检查该段是否需要点亮
// 设置位选
switch(dig)
{
case 0: P_Digi1 = 1; P_Digi1_OUT; break;
case 1: P_Digi2 = 1; P_Digi2_OUT; break;
case 2: P_Digi3 = 1; P_Digi3_OUT; break;
case 3: P_Digi4 = 1; P_Digi4_OUT; break;
}
// 设置段选(低电平)
switch(seg)
{
case 0: p_DigiA = 0; P_SegA_OUT; break;
case 1: p_DigiB = 0; P_SegB_OUT; break;
case 2: p_DigiC = 0; P_SegC_OUT; break;
case 3: p_DigiD = 0; P_SegD_OUT; break;
}
}
break;
}
// 处理E-G段(高电平有效)
case 4: case 5: case 6: case 7:
{
if(DisBuf[dig] & (1 << seg))
{
// 设置位选
switch(dig)
{
case 0: P_Digi1 = 0; P_Digi1_OUT; break;
case 1: P_Digi2 = 0; P_Digi2_OUT; break;
case 2: P_Digi3 = 0; P_Digi3_OUT; break;
case 3: P_Digi4 = 0; P_Digi4_OUT; break;
}
// 设置段选(高电平)
switch(seg)
{
case 4: p_DigiE = 1; P_SegE_OUT; break;
case 5: p_DigiF = 1; P_SegF_OUT; break;
case 6: p_DigiG = 1; P_SegG_OUT; break;
case 7: p_DigiH = 1; P_SegH_OUT; break;
}
}
break;
}
}
// 更新扫描索引
seg = (seg < 8) ? (unsigned char)(seg + 1) : 0u;
if(seg == 0)
{
dig = (dig < 3) ? (unsigned char)(dig + 1) : 0u;
}
}
更新2025-02-27
4位8针数码管显示
以下显示方法可以一次点亮1位数码管的4个段,相比上一版本,效率提升更多,上一版本每次显示1个段,全部显示完需要刷新至少29次,下面的方法仅需刷新8次即可。
void Dealdisbuf()
{
switch(seg)
{
case 0:
{
switch(dig)
{
case 0:
p_Digi1OUT;
p_Digi1 = 1;break;
case 1:
p_Digi2OUT;
p_Digi2 = 1;break;
case 2:
p_Digi3OUT;
p_Digi3 = 1;break;
case 3:
p_Digi4OUT;
p_Digi4 = 1;break;
}
if(DisBuf[dig]&(1<<0))
{
p_DigiAOUT;
p_DigiA = 0;
}
if(DisBuf[dig]&(1<<1))
{
p_DigiBOUT;
p_DigiB = 0;
}
if(DisBuf[dig]&(1<<2))
{
p_DigiCOUT;
p_DigiC = 0;
}
if(DisBuf[dig]&(1<<3))
{
p_DigiDOUT;
p_DigiD = 0;
}
break;
}
case 1:
{
switch(dig)
{
case 0:
p_Digi1OUT;
p_Digi1 = 0;break;
case 1:
p_Digi2OUT;
p_Digi2 = 0;break;
case 2:
p_Digi3OUT;
p_Digi3 = 0;break;
case 3:
p_Digi4OUT;
p_Digi4 = 0;break;
}
if(DisBuf[dig]&(1<<4))
{
p_DigiEOUT;
p_DigiE = 1;
}
if(DisBuf[dig]&(1<<5))
{
p_DigiFOUT;
p_DigiF = 1;
}
if(DisBuf[dig]&(1<<6))
{
p_DigiGOUT;
p_DigiG = 1;
}
if(DisBuf[dig]&(1<<7))
{
p_DigiHOUT;
p_DigiH = 1;
}
break;
}
}
seg = seg==0?1u:0u;
if(dig>3)
dig = 0;
else
{
if(~seg)
dig++;
}
}
以下数码管控制方式后续补充
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架