51单片机学习(五)数码管显示
如有大佬发现我文章里的错误,希望多多指出,或者有缺少的也欢迎告诉我,我会尽快补充上去的,感谢各位的支持,要互三的d我哦!
一.数码管
数码管显示屏和U4 74HC245
U574H138译码器
一位数码管引脚定义
一个数码管由八个LED组成
连接方式:共阴:阴角都连在一起
共阳:阳极都接在一起
就近原则
如何显示数字
假设需要显示6
共阴极:
则需要将AFEDGC点亮
首先公共端接地
10111110为段码
共阳极
公共端选中,位选段给相应数字
四位一体数码管
每一位的公共端分别引出来
所有相同的位选段连在一起
在第三位上显示数字1,如何驱动
共阴:
首先确定位码,共阴接1不通,接0导通
再给段码,要点亮一,就是点亮BC段
共用引脚(静态数码管显示)的缺点:节省了引脚,但是在同一时刻,只有位数码管被点亮,就算点亮多个,显示的也是相同的数字
这边就是数电的知识
C51数组
超过范围有可能不会报错,但是结果不对
C51子函数
二.程序编写
数码管显示任意数字
让第三个数码管显示6
注意顺序从下往上读
#include <REGX52.H> void main() { //第三个是LED6接在Y5上 P2_4=1; P2_3=0; P2_2=1; //5的二进制为101 P0=0x7D;//acdefg亮则对应0111 1101转为十六进制就是0x7D while(1) { } }如果要换成第四位显示6,改成P2_2=0即可
运用子函数
数组大括号后面的分号别忘了(我就是因为忘了,报了一堆错,找了半天原因)
#include <REGX52.H> unsigned char SgnTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F}; void Sgn(unsigned char Location,unsigned char Number) { switch(Location) { case 1:P2_4=1;P2_3=1;P2_2=1;break; case 2:P2_4=1;P2_3=1;P2_2=0;break; case 3:P2_4=1;P2_3=0;P2_2=1;break; case 4:P2_4=1;P2_3=0;P2_2=0;break; case 5:P2_4=0;P2_3=1;P2_2=1;break; case 6:P2_4=0;P2_3=1;P2_2=0;break; case 7:P2_4=0;P2_3=0;P2_2=1;break; case 8:P2_4=0;P2_3=0;P2_2=0;break; } P0=SgnTable[Number]; } void main() { Sgn(7,2); while(1) { } }结果就是第7个数码管显示2
动态数码管显示
需要加消影
因为数码管在工作时是先位选再段选之后就是循环,先选位置,但是位置还残留着上一个函数的数字,上一个段选通过新的段选数据改变,但在改变之前先进行了位选
所以需要在段选之后加一个清零步骤,对下一位就没有影响了
#include <REGX52.H> unsigned char SgnTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F}; typedef unsigned int u16; void delay(u16 i) { while(i--); } void Sgn(unsigned char Location,unsigned char Number) { switch(Location) { case 1:P2_4=1;P2_3=1;P2_2=1;break; case 2:P2_4=1;P2_3=1;P2_2=0;break; case 3:P2_4=1;P2_3=0;P2_2=1;break; case 4:P2_4=1;P2_3=0;P2_2=0;break; case 5:P2_4=0;P2_3=1;P2_2=1;break; case 6:P2_4=0;P2_3=1;P2_2=0;break; case 7:P2_4=0;P2_3=0;P2_2=1;break; case 8:P2_4=0;P2_3=0;P2_2=0;break; } P0=SgnTable[Number]; delay(1000); P0=0x00; //清0 } void main() { while(1) { Sgn(1,1); delay(20000); Sgn(2,2); delay(20000); Sgn(3,3); delay(20000); } }右下角74h595
