专栏名称: CW32生态社区
以开放、共享、互助为理念,致力于构建武汉芯源半导体CW32系列MCU生态社区。无论是嵌入式MCU小白还是想要攻破技术难题的工程师,亦或是需求解决方案的产品经理,都可在CW32生态社区汲取营养、共同成长。
目录
相关文章推荐
51好读  ›  专栏  ›  CW32生态社区

CW32数字电压电流表软件教程-实验三:数码管显示数字

CW32生态社区  · 公众号  ·  · 2024-04-24 18:45

正文

请到「今天看啥」查看全文


4.1.数码管显示原理

(来源:CSDN,原文链接:https://blog.csdn.net/qq_42189951/article/details/133347707)

数码管的显示原理是由多个发光的二极管共阴极或者共阳极组成的成“8”字形的显示器件。数码管通过不同的组合可用来显示数字0~9、字符A ~ F及小数点“.”。数码管的工作原理是通过控制外部的I/O端口进行驱动数码管的各个段码,使用不同的段码从而形成字符显示出我们要的数字。数码管实际上是由七个发光管组成8字形构成的,加上小数点就是8个。这些段分别由字母A、B、C、D、E、F、G、DP来表示。

当数码管特定的引脚加上高电平后,这些特定的发光二极管就会发亮,以形成我们眼睛看到的字样了。如:在一个共阴极数码管上显示一个“8”字,那么就对A、B、C、D、E、F、G对应的引脚置高电平。发光二极管的阳极共同连接至电源的正极称为共阳极数码管,这种类型的数码管点亮需要对引脚置低电平;发光二极管的阴极共同连接到电源的负极称为共阴极数码管,点亮共阴极数码管需要对相应的引脚置高电平。常用LED数码管显示的数字和字符是0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F。

图4-1 数码管模型图

共阳极数码管的8个发光二极管的阳极(二极管正端)连接在一起。通常,公共阳极接高电平(一般接电源),其它管脚接段驱动电路输出端。当某段驱动电路的输出端为低电平时,则该端所连接的字段导通并点亮。根据发光字段的不同组合可显示出各种数字或字符。此时,要求段驱动电路能吸收额定的段导通电流,还需根据外接电源及额定段导通电流来确定相应的限流电阻。

共阴极数码管的8个发光二极管的阴极(二极管负端)连接在一起。通常,公共阴极接低电平(一般接地),其它管脚接段驱动电路输出端。当某段驱动电路的输出端为高电平时,则该端所连接的字段导通并点亮,根据发光字段的不同组合可显示出各种数字或字符。此时,要求段驱动电路能提供额定的段导通电流,还需根据外接电源及额定段导通电流来确定相应的限流电阻。

4.2.数码管原理图与实物图

如果数码管可以显示多位数字,如我们的电压电流表所示。那么除了控制段码来选择要显示的内容,还要选择位码来控制某一个数码管的亮灭。

图4-2 电压电流表三位数码管

数码管的原理图如下,可以看出除了上述的段码引脚之外,还有COM1、COM2、COM3的位码引脚,三个位码引脚分别控制三个数码管的亮灭情况,且低电平有效。

图4-3 三位数码管原理图

4.3.数码管驱动显示

驱动显示数码管的思路是:先将A、B、C、D、E、F、G所代表的引脚从低到高编号,列出数码要显示数字的段码值。比如要显示数字5,则段码值为0x6d,二进制表示为01101101,这说明G置1,F置1,E置0,D置1,C置1,B置0,A置1,最高位则是DP的值。将要显示的数字以段码值的方式储存在数组里以供调用,可以简化程序。接着以循环的方式结合switch语句对A、B、C、D、E、F、G的亮灭情况进行单独计算,先将段码值确定后再进行位码的选择,可以避免因单片机执行程序的时间而造成显示效果的不足。

具体程序如下,将所有与数码管显示相关的函数保存在新建的 Seg_Reg.c 文件

/*  共阴数码管编码表: 0x3f   0x06   0x5b  0x4f  0x66  0x6d  0x7d  0x07  0x7f  0x6f   0      1      2     3     4     5     6     7     8     9  0xbf   0x86   0xdb  0xcf  0xe6  0xed  0xfd  0x87  0xff  0xef             0.     1.     2.    3.    4.    5.    6.    7.    8.    9. */              uint8_t Seg_Table[20] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f,                         0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd, 0x87, 0xff, 0xef};/*对段码值进行存储*/
void Seg_Init(void) //查找原理图对数码管相关引脚进行初始化{ __RCC_GPIOA_CLK_ENABLE();//打开GPIOA的时钟 __RCC_GPIOB_CLK_ENABLE();//打开GPIOB的时钟 __RCC_GPIOC_CLK_ENABLE();//打开GPIOC的时钟 GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pins = GPIO_PIN_0 | GPIO_PIN_4; //PA00,E;PA04,G GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.IT = GPIO_IT_NONE; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_Init(CW_GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pins = GPIO_PIN_6 | GPIO_PIN_4 | GPIO_PIN_2 | GPIO_PIN_0 | GPIO_PIN_3 | GPIO_PIN_7; //PB06,B;PB04,C;PB02,D;PB00,F;PB03,DP //PB07,COM1 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.IT = GPIO_IT_NONE; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_Init(CW_GPIOB, &GPIO_InitStruct); GPIO_InitStruct.Pins = GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2; //PC04,A; //PC03,COM2;PC02,COM3 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.IT = GPIO_IT_NONE; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_Init(CW_GPIOC, &GPIO_InitStruct);}
void Seg_Dis(uint8_t Pos,uint8_t Num)   //Pos表示指定哪一个数码管亮,Num表示要显示的数字{  int i;  uint8_t Dis_Value,Location;  Location = Pos;  Dis_Value = Seg_Table[Num];          for(i = 0; i < 8; i++)      //通过循环确定每一个段码引脚的亮灭情况  {    switch(i)      {/*将Dis_Value右移i位,再和0x01(00000001)相与消除其他位的影响,可以确定该位的写入值,  学员可以自己用一个实例比如0x6d(01101101)进行分析*/        case 0:          GPIO_WritePin(CW_GPIOC,GPIO_PIN_4,(Dis_Value >> i) & 0x01);    //PC04,A          break;        case 1:          GPIO_WritePin(CW_GPIOB,GPIO_PIN_6,(Dis_Value >> i) & 0x01);    //PB06,B          break;        case 2:          GPIO_WritePin(CW_GPIOB,GPIO_PIN_4,(Dis_Value >> i) & 0x01);    //PB04,C          break;        case 3:          GPIO_WritePin(CW_GPIOB,GPIO_PIN_2,(Dis_Value >> i) & 0x01);    //PB02,D          break;        case 4:          GPIO_WritePin(CW_GPIOA,GPIO_PIN_0,(Dis_Value >> i) & 0x01);    //PA00,E          break;        case 5:          GPIO_WritePin(CW_GPIOB,GPIO_PIN_0,(Dis_Value >> i) & 0x01);    //PB00,F          break;        case 6:          GPIO_WritePin(CW_GPIOA,GPIO_PIN_4,(Dis_Value >> i) & 0x01);    //PA04,G          break;        case 7:          GPIO_WritePin(CW_GPIOB,GPIO_PIN_3,(Dis_Value >> i) & 0x01);    //PB03,DP          break;        default:          break;      }  }          switch(Location)    //确定段码后再选择位码  {    case 0:      GPIO_WritePin(CW_GPIOB,GPIO_PIN_7,GPIO_Pin_RESET);  //PB07,COM1      GPIO_WritePin(CW_GPIOC,GPIO_PIN_3,GPIO_Pin_SET);    //PC03,COM2      GPIO_WritePin(CW_GPIOC,GPIO_PIN_2,GPIO_Pin_SET);    //PC02,COM3      break;    case 1:      GPIO_WritePin(CW_GPIOB,GPIO_PIN_7,GPIO_Pin_SET);    //PB07,COM1




    
      GPIO_WritePin(CW_GPIOC,GPIO_PIN_3,GPIO_Pin_RESET);  //PC03,COM2      GPIO_WritePin(CW_GPIOC,GPIO_PIN_2,GPIO_Pin_SET);    //PC02,COM3      break;    case 2:      GPIO_WritePin(CW_GPIOB,GPIO_PIN_7,GPIO_Pin_SET);    //PB07,COM1      GPIO_WritePin(CW_GPIOC,GPIO_PIN_3,GPIO_Pin_SET);    //PC03,COM2      GPIO_WritePin(CW_GPIOC,GPIO_PIN_2,GPIO_Pin_RESET);  //PC02,COM3      break;    default:      break;  }}
在主函数里调用Seg_Dis函数即可在对应位置显示相应数字(别忘了初始化),各位学员熟练之后可以通过define定义每个引脚的写入,使代码更加简洁美观。
程序下载接线如图4-4所示:

图4-4 电压电流表程序下载接线
4.4.实验效果
最终的实验效果如下图所示:

图4-5 数码管显示实验效果

END


往期回顾

REVIEW

【产品应用】CW32电动工具产品开源

【产品应用】基于CW32的智能充电宝(方案开源)

【产品应用】CW-W88水泵通用控制板设计方案(已开源)

【产品应用】基于CW32的角磨机控制器产品方案

【产品方案】基于CW32F030C8的低压无刷风机无感控制器

【产品方案】基于CW32的无刷直流空心杯电机有感控制驱动方案

【产品方案】基于CW32的无刷直流空心杯电机无感方波控制驱动方案

从0到1,开启产品级智能硬件设计之路!

CW32生态社区(WX)群



扫码加入QQ群

3群| 610403240

获取资料及 “开发者扶持计划” 第一手资讯









请到「今天看啥」查看全文