简介188数码管主要用来显示电量另外加一个快充符号主要用于移动电源行业。这里的应用场景是充电电量显示、放电电量显示、小电流模式、过温显示等等显示电量时分为充、放电充状态显示。一、188数码管电路188数码管电路通常由5个I/O口连接到数码管接口I/O口一般为输入/输出模式的普通I/O口即可。二、188数码管点亮原理188数码管本质上是由很多断码组成断码也就是一节一节的显示管比如数字1是由两个断码组成。想要点亮一个断码只需要在断码的两端一端给高电平另一端给低电平即可点亮那么想要点亮很多断码怎么办就需要一个一个点亮把频率设置在50HZ以上也就是不超过20ms扫描一次人眼就看不出来闪烁视觉上看起来是常亮。数码管内部的原理图如下三、代码实现a) 首先断码屏取模把0-9数字的数据放在数组中这里是按共阴极取模。const uint8_t DIG_CODE[] { 0x3f, /* 0 */ 0x06, /* 1 */ 0x5b, /* 2 */ 0x4f, /* 3 */ 0x66, /* 4 */ 0x6d, /* 5 */ 0x7d, /* 6 */ 0x07, /* 7 */ 0x7f, /* 8 */ 0x6f, /* 9 */ 0x01, //小电流模式显示- 0x02, //小电流模式显示 | 0x04, //小电流模式显示 | 0x08, //小电流模式显示_ 0x10, //小电流模式显示| 0x20, //小电流模式显示| };取模的工具可以用下面这种数码管专用的发生器把需要取模的数字点亮对应的断码生成数据即可。b) 获取要显示的数据根据当前电量值获取数据到对应的数组里面。显示的状态可以根据自己的需求去设计比如如果是充电状态闪烁显示电量如果是放电状态则常亮显示电量。if(stuBatDat.m_u16BatSoc 10) { dig1.byte 0; dig2.byte 0; dig3.byte DIG_CODE[stuBatDat.m_u16BatSoc]; } else if(stuBatDat.m_u16BatSoc 100) { dig1.byte 0; dig2.byte DIG_CODE[stuBatDat.m_u16BatSoc / 10]; dig3.byte DIG_CODE[stuBatDat.m_u16BatSoc % 10]; } else { dig1.byte DIG_CODE[1]; dig2.byte DIG_CODE[0]; dig3.byte DIG_CODE[0]; }c) 定时器中定时1ms去刷新数码管的引脚定时扫描的时候根据数码管内部原理图的逻辑轮询去控制5个I/O口的高低电平根据要显示的数据显示对应的数码管。例如第一个是PIN3和PIN4第二个是PIN2和PIN4示例如下if(seg 17) { seg 0; } switch(seg) { case 0: { DIS_T3 DIS_T4 IO_OUT; DIS_L3 dig1.bits.B; DIS_L4 0; break; } case 1: { DIS_T2 DIS_T4 IO_OUT; DIS_L2 dig1.bits.C; DIS_L4 0; break; } ... ... }根据上面示例把原理图上面所有的数码管都写进状态机里面就可以了。那么对于不同工作状态的显示充电电量显示、放电电量显示、小电流模式、过温显示只需要判断出来工作状态在不同的条件下取对应的模数据就可以了。放电是最容易显示的显示出来不需要处理那充电显示如何实现呢一般充电状态需要最后一位数据0.5s闪烁这个显示起来也不难只需要在定时器里面加一个0.5s控制翻转的标志位取模的时候按照这个标志位去控制取模或清除显示就可以了。四、总结188数码管就是在一定频率下去扫描并控制每个断码的状态从而实现点亮。其本质是断码点亮-每个断码按原理图进行高低电平控制获取数据-获取要显示的电量数据并取模扫描断码-按一定频率扫描所有断码即可显示。总结下来整个控制逻辑就是获取数据、取模、扫描。如果大家有更好的实现方式欢迎留言交流。注下面是小可的公众号您的支持是我持续输出优质内容的动力感谢关注。