【STC15单片机】动态数码管

简介: 【STC15单片机】动态数码管

点亮一位数码管

段选:选中哪一位数码管

位选:选中的数码管要显示的内容

这是我对段选位选的理解,就是选中某个位置,赋值字形码,显示想要的图形

aa84ef3b7f331b58520db94f0be445d2_d5f4051cfe6747b1a1683d4d40772abb.png

如果只想让第一个数码管显示,就只需要让com1 = 1即可,其他comx都=0

如果想让8个数码管都亮,就让com1~com8都赋值1,此时对数码管赋值,8个数码管都会显示一致的内容

如果想让不同数码管显示不同的内容且互不干扰,就需要不断的段选、位选,段选、位选,段选、位选。

a869110b581dd7091b3d488614809c3b_52cb8a93b98b4e1c968230e036ef03f9.png

先打开段选的锁存器(U8),用来选择哪个数码管亮,U8的Y6C = 1来控制

a55f99d68ffda949a88de7aaa0586081_ab8d6dd58947460a9280adbf11147ad3.png

往前推导就是Y6 = 0;WR = 0(跳线帽链接)

Y6又由138译码器控制

P27 = 1; P26 = 1; P25 = 0;        //段选

选中第一个数码管 P00 = 1;

P27 = 1; P26 = 1; P25 = 1;        //位选

第一个LED显示个0  P0 = 0xC0;

代码如下:

1. #include <STC15F2K60S2.H>
2. #include "smg.h"
3. 
4. void main()
5. {
6.  P2 = 0xA0;  P0 = 0x00;  //初始化,关闭蜂鸣器继电器
7. // P2 = 0x80;  P0 = 0xFF;  //Y4=0;选中LED,使其灭
8. 
9.  //数码管段选
10.   P27 = 1; P26 = 1; P25 = 0;  //Y6=0;Y6C=1; 使能锁存器U8
11.   P00 = 1;          //选中第一个数码管
12.   //数码管位选
13.   P27 = 1; P26 = 1; P25 = 1;  //Y7=0;Y7C=1; 使能锁存器U7
14.   P0 = 0xC0;          //显示0
15. 
16.   while(1)
17.   { }
18. }

如果想让第5个数码管也显示相同的内容,就在段选的第二行代码,将P04也选中

1. #include <STC15F2K60S2.H>
2. #include "smg.h"
3. 
4. void main()
5. {
6.  P2 = 0xA0;  P0 = 0x00;  //初始化,关闭蜂鸣器继电器
7. // P2 = 0x80;  P0 = 0xFF;  //Y4=0;选中LED,使其灭
8. 
9.  //数码管段选
10.   P27 = 1; P26 = 1; P25 = 0;  //Y6=0;Y6C=1; 使能锁存器U8
11.   P00 = 1; P04 = 1;     //选中第一个数码管
12.   //数码管位选
13.   P27 = 1; P26 = 1; P25 = 1;  //Y7=0;Y7C=1; 使能锁存器U7
14.   P0 = 0xC0;          //显示0
15. 
16.   while(1)
17.   { }
18. }

动态数码管

动态数码管的工作原理及使用

动态显示的特点是将所有位数码管的段选线并联在一起,由位选线控制是哪一个数码管有效。这样一来,就没有必要每一位数码管分配一个锁存器,从而大大简化硬件电路。选亮数码管采用动态扫描显示。所谓动态扫描显示即轮流向各位数码挂送出字形码和相应的位选,利用发光二极管的余晖和人眼视觉暂留作用,使人肉眼感觉各位数码管同时都在显示。动态显示的两幅比静态显示要差一些,所以在选择限流电阻时应略小于静态显示电路中的电阻。

明白了一位数码管是怎么显示的,就可以操作8个数码管了

下面是一次操作8个数码管动态显示的代码

第一个数码管显示1,第二个数码管显示2……第八个数码管显示8

1. #include "smg.h"
2. #include "intrins.h"
3. 
4. 
5. void Delay_ms(int xms)   //15单片机延时函数@11.0592MHz
6. {
7.  unsigned char i, j;   
8.  while(xms--)
9.  {
10.     _nop_();
11.     _nop_();
12.     _nop_();
13.     i = 11;
14.     j = 190;
15.     do
16.     {
17.       while (--j);
18.     } while (--i);
19.   } 
20. }
21. 
22. /*共阳极码表 ABCDEF都是大写*/
23. unsigned char wei[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x88, 0x80, 0xC6, 0xC0, 0x86, 0x8E, 0xBF, 0xFF};
24.              //0     1     2     3     4     5     6     7     8     9     A     B     C     D     E     F     -    灭
25. 
26. 
27. void SMG_Diaplay(void)
28. {
29.   //第1个数码管
30.   P2 = 0xC0;  //Y6=0;Y6C=1; 使能锁存器U8     P27 = 1; P26 = 1; P25 = 0;
31.   P0 = 0x01;  //选中第1个数码管
32.   P2 = 0xFF;  //Y7=0;Y7C=1; 使能锁存器U7     P27 = 1; P26 = 1; P25 = 1;
33.   P0 = wei[1];
34.   Delay_ms(1);
35. 
36.   //第2个数码管
37.   P2 = 0xC0;  //Y6=0;Y6C=1; 使能锁存器U8     P27 = 1; P26 = 1; P25 = 0;
38.   P0 = 0x02;  //选中第2个数码管
39.   P2 = 0xFF;  //Y7=0;Y7C=1; 使能锁存器U7     P27 = 1; P26 = 1; P25 = 1;
40.   P0 = wei[2];
41.   Delay_ms(1);
42. 
43.   //第3个数码管
44.   P2 = 0xC0;  //Y6=0;Y6C=1; 使能锁存器U8     P27 = 1; P26 = 1; P25 = 0;
45.   P0 = 0x04;  //选中第3个数码管
46.   P2 = 0xFF;  //Y7=0;Y7C=1; 使能锁存器U7     P27 = 1; P26 = 1; P25 = 1;
47.   P0 = wei[3];
48.   Delay_ms(1);
49. 
50.   //第4个数码管
51.   P2 = 0xC0;  //Y6=0;Y6C=1; 使能锁存器U8     P27 = 1; P26 = 1; P25 = 0;
52.   P0 = 0x08;  //选中第4个数码管
53.   P2 = 0xFF;  //Y7=0;Y7C=1; 使能锁存器U7     P27 = 1; P26 = 1; P25 = 1;
54.   P0 = wei[4];
55.   Delay_ms(1);
56. 
57.   //第5个数码管
58.   P2 = 0xC0;  //Y6=0;Y6C=1; 使能锁存器U8     P27 = 1; P26 = 1; P25 = 0;
59.   P0 = 0x10;  //选中第5个数码管
60.   P2 = 0xFF;  //Y7=0;Y7C=1; 使能锁存器U7     P27 = 1; P26 = 1; P25 = 1;
61.   P0 = wei[5];
62.   Delay_ms(1);
63. 
64.   //第6个数码管
65.   P2 = 0xC0;  //Y6=0;Y6C=1; 使能锁存器U8     P27 = 1; P26 = 1; P25 = 0;
66.   P0 = 0x20;  //选中第6个数码管
67.   P2 = 0xFF;  //Y7=0;Y7C=1; 使能锁存器U7     P27 = 1; P26 = 1; P25 = 1;
68.   P0 = wei[6];
69.   Delay_ms(1);
70. 
71.   //第7个数码管
72.   P2 = 0xC0;  //Y6=0;Y6C=1; 使能锁存器U8     P27 = 1; P26 = 1; P25 = 0;
73.   P0 = 0x40;  //选中第7个数码管
74.   P2 = 0xFF;  //Y7=0;Y7C=1; 使能锁存器U7     P27 = 1; P26 = 1; P25 = 1;
75.   P0 = wei[7];
76.   Delay_ms(1);
77. 
78.   //第8个数码管
79.   P2 = 0xC0;  //Y6=0;Y6C=1; 使能锁存器U8     P27 = 1; P26 = 1; P25 = 0;
80.   P0 = 0x80;  //选中第8个数码管
81.   P2 = 0xFF;  //Y7=0;Y7C=1; 使能锁存器U7     P27 = 1; P26 = 1; P25 = 1;
82.   P0 = wei[8];
83.   Delay_ms(1);
84. }

在while(1)里调用SMG_Diaplay即可

偷偷懒,用stc给的延时1ms代码,延时1ms的目的是消影,即将本次的段选位选上一次的段选位选分隔开,互不影响,否则数码管会重影看不清,莎普爱思也没用

8adfa16cfb83f15680ee536a9086376a_915b02bb9df14cceb7360fc4dfc3b1d6.png

函数中有_nop_();    需要调用#include "intrins.h"头文件


100s倒计时

后三位数码管依次显示百十个位上的数字

我的思路是定义一个时间变量Time,初始化=100

在1s中断的程序里让Time--,这样就实现了100s倒计时

如何让这每一位都显示在数码管上呢?

我采用数位分离的方法,即将一个数的百位、十位、个位都分离出来,分别显示

三位数数位分离方法

bai = Time/100

shi = Time/10%10

ge = Time%10

35058d9b6b75edc30980ab0a106eff7d_372579d9aa284ac5a98a1951c922c34c.jpeg

数码管部分代码

1. #include "smg.h"
2. #include "intrins.h"
3. 
4. 
5. void Delay_ms(int xms)   //15单片机延时函数@11.0592MHz
6. {
7.  unsigned char i, j;   
8.  while(xms--)
9.  {
10.     _nop_();
11.     _nop_();
12.     _nop_();
13.     i = 11;
14.     j = 190;
15.     do
16.     {
17.       while (--j);
18.     } while (--i);
19.   } 
20. }
21. 
22. /*共阳极码表 ABCDEF都是大写*/
23. unsigned char wei[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x88, 0x80, 0xC6, 0xC0, 0x86, 0x8E, 0xBF, 0xFF};
24.              //0     1     2     3     4     5     6     7     8     9     A     B     C     D     E     F     -    灭
25. 
26. 
27. void DJS_Show(unsigned char bai, unsigned char shi, unsigned char ge)
28. {
29.   //第6个数码管
30.   P2 = 0xC0;  //Y6=0;Y6C=1; 使能锁存器U8     P27 = 1; P26 = 1; P25 = 0;
31.   P0 = 0x20;  //选中第6个数码管
32.   P2 = 0xFF;  //Y7=0;Y7C=1; 使能锁存器U7     P27 = 1; P26 = 1; P25 = 1;
33.   P0 = wei[bai];  //显示百位
34.   Delay_ms(1);
35. 
36.   //第7个数码管
37.   P2 = 0xC0;  //Y6=0;Y6C=1; 使能锁存器U8     P27 = 1; P26 = 1; P25 = 0;
38.   P0 = 0x40;  //选中第7个数码管
39.   P2 = 0xFF;  //Y7=0;Y7C=1; 使能锁存器U7     P27 = 1; P26 = 1; P25 = 1;
40.   P0 = wei[shi];  //显示十位
41.   Delay_ms(1);
42. 
43.   //第8个数码管
44.   P2 = 0xC0;  //Y6=0;Y6C=1; 使能锁存器U8     P27 = 1; P26 = 1; P25 = 0;
45.   P0 = 0x80;  //选中第8个数码管
46.   P2 = 0xFF;  //Y7=0;Y7C=1; 使能锁存器U7     P27 = 1; P26 = 1; P25 = 1;
47.   P0 = wei[ge]; //显示个位
48.   Delay_ms(1);
49. }
1. #ifndef __SMG_H__
2. #define __SMG_H__
3. 
4. #include <STC15F2K60S2.H>
5. 
6. extern unsigned char wei[];
7. 
8. void SMG_Diaplay(void);
9. void DJS_Show(unsigned char bai, unsigned char shi, unsigned char ge);
10. 
11. #endif

主程序代码

1. #include <STC15F2K60S2.H>
2. #include "smg.h"
3. #include "Timer0.h"
4. 
5. unsigned char Time = 100;
6. 
7. void main()
8. {
9.  P2 = 0xA0;  P0 = 0x00;  //初始化,关闭蜂鸣器继电器
10.   P2 = 0x80;  P0 = 0xFF;  //Y4=0;选中LED,使其灭
11.   Timer0_Init();  
12. 
13.   while(1)
14.   {
15.     DJS_Show(Time/100, Time/10%10, Time%10);
16.   }
17. }
18. 
19. void Timer0_Rountine(void) interrupt 1
20. { //5ms定时
21.   static unsigned int Count0;
22. 
23.   Count0++;
24.   if(Count0 >= 200) //1s
25.   {
26.     Time--;
27.     Count0 = 0; //软件复位
28.   }
29. }

这个100s是不精确的,因为控制数码管程序里时钟有1ms延时


动态数码管封装代码

改用一位一位单独控制的数码管,操作方便

和51单片机数码管程序差不多

1. void Delay_ms(int xms)   //15单片机延时函数@11.0592MHz
2. {
3.  unsigned char i, j;   
4.  while(xms--)
5.  {
6.    _nop_();    _nop_();    _nop_();
7.    i = 11;   j = 190;
8.    do
9.    {
10.       while (--j);
11.     } while (--i);
12.   } 
13. }
14. 
15. /*共阳极码表 ABCDEF都是大写*/
16. unsigned char NixieTable[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x88, 0x80, 0xC6, 0xC0, 0x86, 0x8E, 0xBF, 0xFF};
17.              //0     1     2     3     4     5     6     7     8     9     A     B     C     D     E     F     -    灭
18. 
19. void Nixie(unsigned char location, unsigned char number)
20. {
21.   P2 = 0xC0;  //Y6=0;Y6C=1; 使能锁存器U8     P27 = 1; P26 = 1; P25 = 0;
22.   switch(location)//选中LED位置,位选
23.   {
24.     case 1:P0 = 0x01;break;
25.     case 2:P0 = 0x02;break;
26.     case 3:P0 = 0x04;break;
27.     case 4:P0 = 0x08;break;
28.     case 5:P0 = 0x10;break;
29.     case 6:P0 = 0x20;break;
30.     case 7:P0 = 0x40;break;
31.     case 8:P0 = 0x80;break;
32.   }
33.   P2 = 0xFF;  //Y7=0;Y7C=1; 使能锁存器U7     P27 = 1; P26 = 1; P25 = 1;
34.   P0=NixieTable[number];//数字
35.   Delay_ms(1);
36.   P0=0xFF;//消影清零,否则重影
37. }


相关文章
|
10天前
|
存储
【期末不挂科-单片机考前速过系列P3】(第三章:13题MOV&MOVX&MOVC&数码管速过)经典例题盘点(带图解析)
【期末不挂科-单片机考前速过系列P3】(第三章:13题MOV&MOVX&MOVC&数码管速过)经典例题盘点(带图解析)
【51单片机】自定义动态数码管显示(设计思路&原理&代码演示)
【51单片机】自定义动态数码管显示(设计思路&原理&代码演示)
【51单片机】自定义静态数码管显示(设计思路&代码演示)
【51单片机】自定义静态数码管显示(设计思路&代码演示)
【51单片机】静态数码管显示(设计思路&原理&代码演示)
【51单片机】静态数码管显示(设计思路&原理&代码演示)
|
10天前
|
芯片 数据格式
【51单片机】要实现动静态数码管,你首先需要知道这些【数码管项目前置知识】
【51单片机】要实现动静态数码管,你首先需要知道这些【数码管项目前置知识】
|
10天前
|
芯片 数据格式
【51单片机】实现一个动静态数码管显示项目(超全详解&代码&图示)(5)
【51单片机】实现一个动静态数码管显示项目(超全详解&代码&图示)(5)
|
10天前
|
C语言
静态数码管显示+动态数码管显示——“51单片机”
静态数码管显示+动态数码管显示——“51单片机”
|
10天前
|
编译器 C语言 开发者
单片机原理与应用:探索微型计算机世界
单片机原理与应用:探索微型计算机世界
22 1
|
10天前
|
数据采集 数据处理 C语言
单片机:探索其原理、应用与编程实践
单片机:探索其原理、应用与编程实践
23 1
|
10天前
|
物联网
STC51单片机-实验开发装置仿真-物联网应用系统设计
STC51单片机-实验开发装置仿真-物联网应用系统设计
64 0