论坛» 高校专区» 坤创E-Geek/天科大新电社

04. 单片机IO口的操作2-数码管篇

高工
2019-01-23 23:46 1楼

在上一帖中,我们进行了LED点灯的练习,当然由于蓝桥板采用了通过74HC573、74HC02、74HC138这三个数字芯片作为LED灯的前置驱动电路的特殊电路结构,导致使用蓝桥板点亮LED灯的程序要稍微多了几行。同学们只需要搞明白,如何使用这些数字芯片级联控制就行了,耐心一点,在蓝桥板的资料包中,有这些芯片的说明文档。耐心点,根据代码,就很容易搞明白啦~

对于LED点灯来说,同学们会觉得很不屑,这么简单的操作,怎么可能出竞赛题呢?有这样的想法,你就错了。2018年第九届蓝桥杯省赛的试题,就是让你点灯,让你点出不同亮度的灯,让你变着法儿各种点灯,于是死伤无数。。。当然做这个题需要配合PWM脉宽调制的概念进行操作,对于历年试题的解答,在本系列贴的第二部分,会逐步为大家奉上。敬请期待哦~!

好了,言归正传,今天我们要进行数码管的操作,数码管是非常重要的一个部分,可以说历年考题必考数码管,因为它是蓝桥板上唯一一个能够进行显示的器件,当然,有同学问道今后可能不可能考到点阵和液晶,我可以告诉大家,可能性不大,今年一定还是数码管!那么既然数码管这么重要,接下来我就把相关的练习题和代码发出来,供大家参考学习。

题1、在数码管上显示字符8,每1秒移动一位

题2、在数码管上稳定显示字符12345678

题3、在数码管上稳定显示给定字符0000-1023或者000H-3FFH

下面依旧按照惯例分别奉上相关代码,并在文末给出所有代码压缩包的下载链接,欢迎大家下载查看。如有任何问题,请大家回帖告知,谢谢~!

-----------------------蓝桥板代码---------------------

蓝桥板题1代码:

/********************************************** 1、在数码管上显示字符8,每1秒移动一位 **********************************************/ #include #include"intrins.h" #define uchar unsigned char #define uint unsigned int uchar code smgwei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; void delayms(uint z); void init(); void main() { uchar i; init(); while(1) { // for(i=0;i<8;i++) //循环右移 //{ //P2=0xc0; //P0=smgwei[i]; //P2=0xff; //P0=0x80;; //delayms(1000); // if(i==8)i=0; //} for(i=7;i>=0;i--) //循环左移 { P2=0xc0; P0=smgwei[i]; P2=0xff; P0=0x80;; delayms(1000); if(i==0)i=8; } } } void delayms(uint z) { uint x,y; for(x=z;x>0;x--) for(y=845;y>0;y--); } void init() { P2=0xa0; P0=0x00; P2=0x80; P0=0xff; P2=0xc0; P0=0xff; P2=0xff; P0=0xff; }

蓝桥板题2代码:

/***************************************************** 2、在数码管上稳定显示字符12345678 ******************************************************/ #include #include"intrins.h" #define uchar unsigned char #define uint unsigned int uchar code smgtab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF,}; uchar yi,er,san,si,wu,liu,qi,ba; void display1(uchar yi,uchar er); void display2(uchar san,uchar si); void display3(uchar wu,uchar liu ); void display4(uchar qi,uchar ba); void delayms(uint z); void init(); void main() { init(); while(1) { yi=1;er=2;san=3;si=4;wu=5;liu=6;qi=7;ba=8; display1(yi,er); display2(san,si); display3(wu,liu); display4(qi,ba); } } void delayms(uint z) { uint x,y; for(x=z;x>0;x--) for(y=845;y>0;y--); } void init() { P2=0xa0; P0=0x00; P2=0x80; P0=0xff; P2=0xc0; P0=0xff; P2=0xff; P0=0xff; } void display1(uchar yi,uchar er) { P2=0xc0; P0=0x01; P2=0xff; P0=smgtab[yi]; delayms(1); P2=0xc0; P0=0x02; P2=0xff; P0=smgtab[er]; delayms(1); } void display2(uchar san,uchar si) { P2=0xc0; P0=0x04; P2=0xff; P0=smgtab[san]; delayms(1); P2=0xc0; P0=0x08; P2=0xff; P0=smgtab[si]; delayms(1); } void display3(uchar wu,uchar liu ) { P2=0xc0; P0=0x10; P2=0xff; P0=smgtab[wu]; delayms(1); P2=0xc0; P0=0x20; P2=0xff; P0=smgtab[liu]; delayms(1); } void display4(uchar qi,uchar ba) { P2=0xc0; P0=0x40; P2=0xff; P0=smgtab[qi]; delayms(1); P2=0xc0; P0=0x80; P2=0xff; P0=smgtab[ba]; delayms(1); }

蓝桥板题3代码:

/***************************************************** 3、在数码管上稳定显示给定字符0000-1023或者000H-3FFH ******************************************************/ #include #include"intrins.h" #define uchar unsigned char #define uint unsigned int uchar code smgtab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF, 0x8E,0x89,0XFF,}; uchar yi,er,san,si,wu,liu,qi,ba; void display1(uchar yi,uchar er); void display2(uchar san,uchar si); void display3(uchar wu,uchar liu ); void display4(uchar qi,uchar ba); void delayms(uint z); void init(); void main() { init(); while(1) { // yi=0;er=0;san=0;si=0;wu=1;liu=0;qi=2;ba=3; yi=0;er=0;san=0;si=12;wu=3;liu=11;qi=11;ba=12; display1(yi,er); display2(san,si); display3(wu,liu); display4(qi,ba); } } void delayms(uint z) { uint x,y; for(x=z;x>0;x--) for(y=845;y>0;y--); } void init() { P2=0xa0; P0=0x00; P2=0x80; P0=0xff; P2=0xc0; P0=0xff; P2=0xff; P0=0xff; } void display1(uchar yi,uchar er) { P2=0xc0; P0=0x01; P2=0xff; P0=smgtab[yi]; delayms(1); P2=0xc0; P0=0x02; P2=0xff; P0=smgtab[er]; delayms(1); } void display2(uchar san,uchar si) { P2=0xc0; P0=0x04; P2=0xff; P0=smgtab[san]; delayms(1); P2=0xc0; P0=0x08; P2=0xff; P0=smgtab[si]; delayms(1); } void display3(uchar wu,uchar liu ) { P2=0xc0; P0=0x10; P2=0xff; P0=smgtab[wu]; delayms(1); P2=0xc0; P0=0x20; P2=0xff; P0=smgtab[liu]; delayms(1); } void display4(uchar qi,uchar ba) { P2=0xc0; P0=0x40; P2=0xff; P0=smgtab[qi]; delayms(1); P2=0xc0; P0=0x80; P2=0xff; P0=smgtab[ba]; delayms(1); }


-----------------------小红板代码----------------------

小红板题1代码:

/************************************************************* 1、在数码管上显示字符8,每1秒移动一位 *************************************************************/ #include"reg52.h" #define uchar unsigned char #define uint unsigned int sbitP_HC595_SER = P2^7;//pin 14SERdata input sbitP_HC595_RCLK = P2^5;//pin 12RCLkstore (latch) clock sbitP_HC595_SRCLK = P2^6;//pin 11SRCLKShift data clock //uchar code smgtab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00};//共阴数码管段值 uchar code smgwei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; uchar yi,er,san,si,wu,liu,qi,ba; void SMG_Init(); void Send_595(unsigned char dat); void delayms(uint z); void main() { uchar i; SMG_Init(); while(1) { //for(i=0;i<8;i++) //循环右移 //{ //Send_595(smgwei[i]); // Send_595(0x7f); // P_HC595_RCLK = 0; // P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 // delayms(1000); //} for(i=7;i>=0;i--) //循环左移 { Send_595(smgwei[i]); Send_595(0x7f); P_HC595_RCLK = 0; P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 delayms(1000); if(i==0)i=8; } } } void delayms(uint z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void SMG_Init() { Send_595(0x00); //同时选择8个数码管 Send_595(0x00); //让8个数码管同时显示消隐字符 P_HC595_RCLK = 0; P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 } void Send_595(unsigned char dat)//发送一个字节 { unsigned chari; for(i=0; i<8; i++) { if(dat & 0x80) //判断dat的最高位是否为1 P_HC595_SER = 1; //最高位如果为1,则令P2.7 = 1 else P_HC595_SER = 0; //最高位如果为0,则令P2.7 = 0 P_HC595_SRCLK = 0; P_HC595_SRCLK = 1; P_HC595_SRCLK = 0; //使用P2.6制造一个上升沿将这一位数据送到74HC595的QA输出端 dat = dat << 1; //将dat左移一位,取次高位 } }

小红板题2代码:

/****************************************** 2、在数码管上稳定显示字符12345678 *******************************************/ /*#include"reg52.h" #define uchar unsigned char #define uint unsigned int sbitP_HC595_SER = P2^7;//pin 14SERdata input sbitP_HC595_RCLK = P2^5;//pin 12RCLkstore (latch) clock sbitP_HC595_SRCLK = P2^6;//pin 11SRCLKShift data clock uchar code smgtab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00};//共阴数码管段值 uchar yi,er,san,si,wu,liu,qi,ba; void display1(uchar yi,uchar er); void display2(uchar san,uchar si); void display3(uchar wu,uchar liu); void display4(uchar qi,uchar ba); void SMG_Init(); void Send_595(unsigned char dat); void delayms(uint z); void main() { SMG_Init(); while(1) { yi=1;er=2;san=3;si=4;wu=5;liu=6;qi=7;ba=8; display1(yi,er); display2(san,si); display3(wu,liu); display4(qi,ba); } } void delayms(uint z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void SMG_Init() { Send_595(0x00); //同时选择8个数码管 Send_595(0x00); //让8个数码管同时显示消隐字符 P_HC595_RCLK = 0; P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 } void Send_595(unsigned char dat)//发送一个字节 { unsigned char i; for(i=0; i<8; i++) { if(dat & 0x80) //判断dat的最高位是否为1 P_HC595_SER = 1; //最高位如果为1,则令P2.7 = 1 else P_HC595_SER = 0; //最高位如果为0,则令P2.7 = 0 P_HC595_SRCLK = 0; P_HC595_SRCLK = 1; P_HC595_SRCLK = 0; //使用P2.6制造一个上升沿将这一位数据送到74HC595的QA输出端 dat = dat << 1; //将dat左移一位,取次高位 } } void display1(uchar yi,uchar er) { Send_595(0xfe); //位选 Send_595(smgtab[yi]); //段选 P_HC595_RCLK = 0; P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 delayms(1); Send_595(0xfd); Send_595(smgtab[er]); P_HC595_RCLK = 0; P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 delayms(1); } void display2(uchar san,uchar si) { Send_595(0xfb); Send_595(smgtab[san]); P_HC595_RCLK = 0; P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 delayms(1); Send_595(0xf7); Send_595(smgtab[si]); P_HC595_RCLK = 0; P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 delayms(1); } void display3(uchar wu,uchar liu) { Send_595(0xef); Send_595(smgtab[wu]); P_HC595_RCLK = 0; P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 delayms(1); Send_595(0xdf); Send_595(smgtab[liu]); P_HC595_RCLK = 0; P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 delayms(1); } void display4(uchar qi,uchar ba) { Send_595(0xbf); Send_595(smgtab[qi]); P_HC595_RCLK = 0; P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 delayms(1); Send_595(0x7f); Send_595(smgtab[ba]); P_HC595_RCLK = 0; P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 delayms(1); }

小红板题3代码:

/************************************************* 3、在数码管上稳定显示给定字符0000-1023或者000H-3FFH **************************************************/ #include"reg52.h" #define uchar unsigned char #define uint unsigned int sbitP_HC595_SER = P2^7;//pin 14SERdata input sbitP_HC595_RCLK = P2^5;//pin 12RCLkstore (latch) clock sbitP_HC595_SRCLK = P2^6;//pin 11SRCLKShift data clock uchar code smgtab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x76,0x00}; uchar yi,er,san,si,wu,liu,qi,ba; void display1(uchar yi,uchar er); void display2(uchar san,uchar si); void display3(uchar wu,uchar liu); void display4(uchar qi,uchar ba); void SMG_Init(); void Send_595(unsigned char dat); void delayms(uint z); void main() { SMG_Init(); while(1) { // yi=0;er=0;san=0;si=0;wu=1;liu=0;qi=2;ba=3; 字符0000-1023 yi=0;er=0;san=0;si=0;wu=3;liu=15;qi=15;ba=16; display1(yi,er); display2(san,si); display3(wu,liu); display4(qi,ba); } } void delayms(uint z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void SMG_Init() { Send_595(0x00); //同时选择8个数码管 Send_595(0x00); //让8个数码管同时显示消隐字符 P_HC595_RCLK = 0; P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 } void Send_595(unsigned char dat)//发送一个字节 { unsigned char i; for(i=0; i<8; i++) { if(dat & 0x80) //判断dat的最高位是否为1 P_HC595_SER = 1; //最高位如果为1,则令P2.7 = 1 else P_HC595_SER = 0; //最高位如果为0,则令P2.7 = 0 P_HC595_SRCLK = 0; P_HC595_SRCLK = 1; P_HC595_SRCLK = 0; //使用P2.6制造一个上升沿将这一位数据送到74HC595的QA输出端 dat = dat << 1; //将dat左移一位,取次高位 } } void display1(uchar yi,uchar er) { Send_595(0xfe); Send_595(smgtab[yi]); P_HC595_RCLK = 0; P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 delayms(1); Send_595(0xfd); Send_595(smgtab[er]); P_HC595_RCLK = 0; P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 delayms(1); } void display2(uchar san,uchar si) { Send_595(0xfb); Send_595(smgtab[san]); P_HC595_RCLK = 0; P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 delayms(1); Send_595(0xf7); Send_595(smgtab[si]); P_HC595_RCLK = 0; P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 delayms(1); } void display3(uchar wu,uchar liu) { Send_595(0xef); Send_595(smgtab[wu]); P_HC595_RCLK = 0; P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 delayms(1); Send_595(0xdf); Send_595(smgtab[liu]); P_HC595_RCLK = 0; P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 delayms(1); } void display4(uchar qi,uchar ba) { Send_595(0xbf); Send_595(smgtab[qi]); P_HC595_RCLK = 0; P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 delayms(1); Send_595(0x7f); Send_595(smgtab[ba]); P_HC595_RCLK = 0; P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选 delayms(1); }


----------------所有代码打包下载链接------------------

04. 单片机IO口的操作2-数码管篇_全部代码打包.zip


同学们,可以接着往下进行05. 单片机I/O口的操作3-机械按键篇的题目练习哦~~对代码有任何问题,欢迎回帖指出来哦~积极参与的小可耐们,可是有U盘拿的哦~!!

学习,就像攀登珠峰,一步一步都要走扎实,才能顺利登顶!Come on!!


高工
2019-01-24 08:37 2楼

谢谢楼主分享

院士
2019-01-24 11:21 3楼

提个建议,还是少用display1这样的命名,来一个实际意义的单词呗。

displayAlpha;

displayBravo;

菜鸟
2019-01-24 13:47 4楼

感谢楼主的分享,楼主辛苦了,如果蓝桥板的代码能多加一点注释就好了

菜鸟
2019-01-24 20:32 5楼

果然,数码管是单片机学习过程中的重中之重!

菜鸟
2019-01-25 23:14 6楼

为什么要把数字显示分成两个数字两个数字显示?这种思路有什么优点?

菜鸟
2019-01-27 18:57 7楼

帖子值得永久收藏,力挺楼主

院士
2019-02-15 08:47 8楼

帖子值得永久收藏,挺楼主

菜鸟
2019-03-24 07:12 9楼
可见
菜鸟
2020-03-27 23:12 10楼
[N~}0L~B]VPI(CJNB]L$GQM.png楼主,,,蓝板代码二出现这情况是怎么回事啊
共11条 1/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册]