0


【蓝桥杯单片机入门记录】动态数码管

一、数码管动态显示概述

  • LED数码管动态显示接口是单片机中应用最为广泛的一种显示方式之一。
  • 动态驱动是将所有数码管的8个显示笔划(段选端)“a,b,c,d,e,fg,dp”的同名端连在一起,另外为每个数码管的公共极COM增加位选通控制电路,位选通由各自独立的I/O线控制。当单片机输出字形码时,单片机先对位选通COM端电路进行控制,再对段选通进行输出,该位就显示出字形,没有选通的数码管就不会亮。
  • 通过分时轮流控制各个数码管的的COM端,就使各个数码管轮流受控显示,这就是动态驱动。
  • 在轮流显示过程中,每位数码管的点亮时间为1~2ms,由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O端口,而且功耗更低。

二、动态数码管原理图

(1)原理图

(2)动态数码管如何与芯片相连

(3)“此器件” ——>锁存器74HC573

  • 74HC573的八个锁存器都是透明的D型锁存器,当使能(G)为高时,0输出将随数据(D)输入而变当使能为低时,将输出锁存在已建立的数据电平上。
  • 输出控制不影响锁存器的内部工作,即老数据可以保持,甚至当输出被关闭时,新的数据也可以置入。
  • 这种电路可以驱动大电容或低阻抗负载,可以直接与系统总线接口并驱动总线,而不需要外接口。特别适用于缓冲寄存器,1/0通道,双向总线驱动器和工作寄存器。
  • Y7C为高电平,a-dp会随着p0变化;Y7C为低电平时,锁存置为低电平的那一刻的数据,不再变化
  • Y7C和Y6C同时只能有一个为低电平

三、动态数码管显示例程

(1)例程1:两个数码管显示不同内容。本例以第一个数码管显示数字“0”,第二个数码管显示数字“1”为例。

  1. //头文件声明区域
  2. #include <STC15F2K60S2.H>
  3. #include<intrins.h>
  4. //变量声明区域
  5. unsigned int i = 0;
  6. //函数声明区域
  7. void Delay(int ms);
  8. //程序主体
  9. void main()
  10. {
  11. P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;//初始化程序
  12. while(1)
  13. {
  14. P2=0XC0;P0=0X01;//打开控制数码管位选的锁存器,然后选中第一个数码管
  15. P2=0XFF;P0=0XC0;//大家控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  16. Delay(1);
  17. P2=0XC0;P0=0X02;//打开控制数码管位选的锁存器,然后选中第二个数码管
  18. P2=0XFF;P0=0XF9;//打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  19. Delay(1);
  20. }
  21. }
  22. //函数定义区域
  23. void Delay(int ms) //@11.0592MHz
  24. {
  25. unsigned char i, j;
  26. for(i = 0;i < ms;i++)
  27. {
  28. _nop_();
  29. _nop_();
  30. _nop_();
  31. i = 11;
  32. j = 190;
  33. do
  34. {
  35. while (--j);
  36. } while (--i);
  37. }
  38. }

(2)例程2:多个数码管显示不同内容(二)。注:创建数码管显示子函数。

  1. #include <STC15F2K60S2.H>
  2. #include<intrins.h>
  3. void Delay_MS(unsigned int MS);
  4. void main(void)
  5. {
  6. IO_Init();
  7. P2=0XA0;P0=0X00;P2=0X80;P0=0XFF; //初始化程序,后期详解;
  8. while(1)
  9. {
  10. P2=0XC0;P0=0X01; //打开控制数码管位选的锁存器,然后选中第一个数码管
  11. P2=0XFF;P0=0XC0; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  12. Delay_MS(1);
  13. P2=0XC0;P0=0X02; //打开控制数码管位选的锁存器,然后选中第二个数码管
  14. P2=0XFF;P0=0XF9; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  15. Delay_MS(1);
  16. P2=0XC0;P0=0X04; //打开控制数码管位选的锁存器,然后选中第三个数码管
  17. P2=0XFF;P0=0XF9; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  18. Delay_MS(1);
  19. P2=0XC0;P0=0X08; //打开控制数码管位选的锁存器,然后选中第四个数码管
  20. P2=0XFF;P0=0XF9; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  21. Delay_MS(1);
  22. P2=0XC0;P0=0X10; //打开控制数码管位选的锁存器,然后选中第五个数码管
  23. P2=0XFF;P0=0XF9; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  24. Delay_MS(1);
  25. P2=0XC0;P0=0X20; //打开控制数码管位选的锁存器,然后选中第六个数码管
  26. P2=0XFF;P0=0XF9; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  27. Delay_MS(1);
  28. P2=0XC0;P0=0X40; //打开控制数码管位选的锁存器,然后选中第七个数码管
  29. P2=0XFF;P0=0XF9; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  30. Delay_MS(1);
  31. P2=0XC0;P0=0X80; //打开控制数码管位选的锁存器,然后选中第八个数码管
  32. P2=0XFF;P0=0XF9; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  33. Delay_MS(1);
  34. }
  35. }
  36. void Delay_MS(unsigned int MS)
  37. {
  38. unsigned char i, j;
  39. for(i = 0;i < ms;i++)
  40. {
  41. _nop_();
  42. _nop_();
  43. _nop_();
  44. i = 11;
  45. j = 190;
  46. do
  47. {
  48. while (--j);
  49. } while (--i);
  50. }
  51. }

(3)例程3:多个数码管显示不同内容(二)。注:创建数码管显示子函数。

①法一:
  1. //头文件声明区域
  2. #include <STC15F2K60S2.H>
  3. #include<intrins.h>
  4. //变量声明区域
  5. unsigned int i = 0;
  6. unsigned char DSEG[]= {0X00,0X01,0X02,0X04,0X08,0X10,0X20,0X40,0X80};
  7. unsigned char code SEG[] = {0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
  8. //函数声明区域
  9. void Delay(int ms);
  10. void DSED_Display(unsigned char dseg,unsigned char seg);
  11. //程序主体
  12. void main()
  13. {
  14. P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;//初始化程序
  15. while(1)
  16. {
  17. DSED_Display(1,1);
  18. DSED_Display(2,2);
  19. DSED_Display(3,3);
  20. DSED_Display(4,4);
  21. DSED_Display(5,5);
  22. DSED_Display(6,6);
  23. DSED_Display(7,7);
  24. DSED_Display(8,8);
  25. }
  26. }
  27. //函数定义区域
  28. void Delay(int ms) //@11.0592MHz
  29. {
  30. unsigned char i, j;
  31. for(i = 0;i < ms;i++)
  32. {
  33. _nop_();
  34. _nop_();
  35. _nop_();
  36. i = 11;
  37. j = 190;
  38. do
  39. {
  40. while (--j);
  41. } while (--i);
  42. }
  43. }
  44. void DSED_Display(unsigned char dseg,unsigned char seg)
  45. {
  46. P0 = 0XFF;//消影
  47. P2=0XC0;P0=DSEG[dseg];//打开控制数码管位选的锁存器,然后选中第一个数码管
  48. P2=0XFF;P0=SEG[seg];
  49. Delay(1);
  50. }
②法二:
  1. #include <STC15F2K60S2.H>
  2. #include<intrins.h>
  3. unsigned char tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
  4. //unsigned char code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
  5. unsigned char SEG1,SEG2,SEG3,SEG4,SEG5,SEG6,SEG7,SEG8;
  6. void Delay(int ms);
  7. void SEG_Display(unsigned char yi,unsigned char er,unsigned char san,unsigned char si,unsigned char wu,unsigned char liu,unsigned char qi,unsigned char ba);
  8. void main(void)
  9. {
  10. P2=0XA0;P0=0X00;P2=0X80;P0=0XFF; //初始化程序,后期详解;
  11. while(1)
  12. {
  13. SEG1=1,SEG2=2,SEG3=3,SEG4=4,SEG5=5,SEG6=6,SEG7=7,SEG8=8;
  14. SEG_Display(SEG1,SEG2,SEG3,SEG4,SEG5,SEG6,SEG7,SEG8);
  15. }
  16. }
  17. void SEG_Display(unsigned char yi,unsigned char er,unsigned char san,unsigned char si,unsigned char wu,unsigned char liu,unsigned char qi,unsigned char ba)
  18. {
  19. P0=0XFF;
  20. P2=0XC0;P0=0X01; //打开控制数码管位选的锁存器,然后选中第一个数码管
  21. P2=0XFF;P0=tab[yi]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  22. Delay_MS(1);
  23. P0=0XFF;
  24. P2=0XC0;P0=0X02; //打开控制数码管位选的锁存器,然后选中第二个数码管
  25. P2=0XFF;P0=tab[er]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  26. Delay_MS(1);
  27. P0=0XFF;
  28. P2=0XC0;P0=0X04; //打开控制数码管位选的锁存器,然后选中第三个数码管
  29. P2=0XFF;P0=tab[san]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  30. Delay_MS(1);
  31. P0=0XFF;
  32. P2=0XC0;P0=0X08; //打开控制数码管位选的锁存器,然后选中第四个数码管
  33. P2=0XFF;P0=tab[si]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  34. Delay_MS(1);
  35. P0=0XFF;
  36. P2=0XC0;P0=0X10; //打开控制数码管位选的锁存器,然后选中第五个数码管
  37. P2=0XFF;P0=tab[wu]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  38. Delay_MS(1);
  39. P0=0XFF;
  40. P2=0XC0;P0=0X20; //打开控制数码管位选的锁存器,然后选中第六个数码管
  41. P2=0XFF;P0=tab[liu]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  42. Delay_MS(1);
  43. P0=0XFF;
  44. P2=0XC0;P0=0X40; //打开控制数码管位选的锁存器,然后选中第七个数码管
  45. P2=0XFF;P0=tab[qi]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  46. Delay_MS(1);
  47. P0=0XFF;
  48. P2=0XC0;P0=0X80; //打开控制数码管位选的锁存器,然后选中第八个数码管
  49. P2=0XFF;P0=tab[ba]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  50. Delay_MS(1);
  51. }
  52. void Delay(int ms) //@11.0592MHz
  53. {
  54. unsigned char i, j;
  55. for(i = 0;i < ms;i++)
  56. {
  57. _nop_();
  58. _nop_();
  59. _nop_();
  60. i = 11;
  61. j = 190;
  62. do
  63. {
  64. while (--j);
  65. } while (--i);
  66. }
  67. }
③法三
  1. #include <STC15F2K60S2.H>
  2. #include<intrins.h>
  3. //#define uchar unsigned char
  4. //#define uint unsigned int
  5. typedef unsigned char uchar ;
  6. typedef unsigned int uint ;
  7. unsigned char tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
  8. //unsigned char code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
  9. unsigned char SEG1,SEG2,SEG3,SEG4,SEG5,SEG6,SEG7,SEG8;
  10. void Delay(int ms);
  11. void SEG_Display12(uchar yi,uchar er);
  12. void SEG_Display34(uchar san,uchar si);
  13. void SEG_Display56(unsigned char wu,unsigned char liu);
  14. void SEG_Display78(unsigned char qi,unsigned char ba);
  15. void main(void)
  16. {
  17. P2=0XA0;P0=0X00;P2=0X80;P0=0XFF; //初始化程序,后期详解;
  18. while(1)
  19. {
  20. SEG1=1,SEG2=2,SEG3=3,SEG4=4,SEG5=5,SEG6=6,SEG7=7,SEG8=8;
  21. SEG_Display12(SEG1,SEG2);
  22. SEG_Display34(SEG3,SEG4);
  23. SEG_Display56(SEG5,SEG6);
  24. SEG_Display78(SEG7,SEG8);
  25. }
  26. }
  27. void SEG_Display12(unsigned char yi,unsigned char er)
  28. {
  29. P0=0XFF;
  30. P2=0XC0;P0=0X01; //打开控制数码管位选的锁存器,然后选中第一个数码管
  31. P2=0XFF;P0=tab[yi]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  32. Delay_MS(1);
  33. P0=0XFF;
  34. P2=0XC0;P0=0X02; //打开控制数码管位选的锁存器,然后选中第二个数码管
  35. P2=0XFF;P0=tab[er]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  36. Delay_MS(1);
  37. }
  38. void SEG_Display34(unsigned char san,unsigned char si)
  39. {
  40. P0=0XFF;
  41. P2=0XC0;P0=0X04; //打开控制数码管位选的锁存器,然后选中第三个数码管
  42. P2=0XFF;P0=tab[san]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  43. Delay_MS(1);
  44. P0=0XFF;
  45. P2=0XC0;P0=0X08; //打开控制数码管位选的锁存器,然后选中第四个数码管
  46. P2=0XFF;P0=tab[si]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  47. Delay_MS(1);
  48. }
  49. void SEG_Display56(unsigned char wu,unsigned char liu)
  50. {
  51. P0=0XFF;
  52. P2=0XC0;P0=0X10; //打开控制数码管位选的锁存器,然后选中第五个数码管
  53. P2=0XFF;P0=tab[wu]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  54. Delay_MS(1);
  55. P0=0XFF;
  56. P2=0XC0;P0=0X20; //打开控制数码管位选的锁存器,然后选中第六个数码管
  57. P2=0XFF;P0=tab[liu]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  58. Delay_MS(1);
  59. }
  60. void SEG_Display78(unsigned char qi,unsigned char ba)
  61. {
  62. P0=0XFF;
  63. P2=0XC0;P0=0X40; //打开控制数码管位选的锁存器,然后选中第七个数码管
  64. P2=0XFF;P0=tab[qi]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  65. Delay_MS(1);
  66. P0=0XFF;
  67. P2=0XC0;P0=0X80; //打开控制数码管位选的锁存器,然后选中第八个数码管
  68. P2=0XFF;P0=tab[ba]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  69. Delay_MS(1);
  70. }
  71. void Delay(int ms) //@11.0592MHz
  72. {
  73. unsigned char i, j;
  74. for(i = 0;i < ms;i++)
  75. {
  76. _nop_();
  77. _nop_();
  78. _nop_();
  79. i = 11;
  80. j = 190;
  81. do
  82. {
  83. while (--j);
  84. } while (--i);
  85. }
  86. }

(4)例程4:多位数码管倒计时。本例以第6、7、8位数码管显示255→0的倒计时为例,其他数码管保持熄灭。

  1. #include <STC15F2K60S2.H>
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. unsigned char tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
  6. //unsigned char code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
  7. unsigned char SEG1,SEG2,SEG3,SEG4,SEG5,SEG6,SEG7,SEG8;
  8. unsigned char Num = 255 ;
  9. unsigned char Num_Refresh = 0 ;
  10. void Delay(uint MS);
  11. void SEG_Display12(uchar yi,uchar er);
  12. void SEG_Display34(uchar san,uchar si);
  13. void SEG_Display56(unsigned char wu,unsigned char liu);
  14. void SEG_Display78(unsigned char qi,unsigned char ba);
  15. void main(void)
  16. {
  17. P2=0XA0;P0=0X00;P2=0X80;P0=0XFF; //初始化程序,后期详解;
  18. P2=0XC0;P0=0X01;P2=0XFF;P0=0XFF; //打开第一个数码管,后期详解;
  19. SEG1=11,SEG2=11,SEG3=11,SEG4=11,SEG5=11;
  20. SEG6=2,SEG7=5,SEG8=5;
  21. while(1)
  22. {
  23. if(++Num_Refresh==125)
  24. {
  25. Num_Refresh = 0 ;
  26. Num = Num -1; //Num--;
  27. SEG6=Num/100,SEG7=Num%100/10,SEG8=Num%10;
  28. }
  29. SEG_Display12(SEG1,SEG2);
  30. SEG_Display34(SEG3,SEG4);
  31. SEG_Display56(SEG5,SEG6);
  32. SEG_Display78(SEG7,SEG8);
  33. }
  34. }
  35. void SEG_Display12(unsigned char yi,unsigned char er)
  36. {
  37. P0=0XFF;
  38. P2=0XC0;P0=0X01; //打开控制数码管位选的锁存器,然后选中第一个数码管
  39. P2=0XFF;P0=tab[yi]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  40. Delay_MS(1);
  41. P0=0XFF;
  42. P2=0XC0;P0=0X02; //打开控制数码管位选的锁存器,然后选中第二个数码管
  43. P2=0XFF;P0=tab[er]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  44. Delay_MS(1);
  45. }
  46. void SEG_Display34(unsigned char san,unsigned char si)
  47. {
  48. P0=0XFF;
  49. P2=0XC0;P0=0X04; //打开控制数码管位选的锁存器,然后选中第三个数码管
  50. P2=0XFF;P0=tab[san]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  51. Delay_MS(1);
  52. P0=0XFF;
  53. P2=0XC0;P0=0X08; //打开控制数码管位选的锁存器,然后选中第四个数码管
  54. P2=0XFF;P0=tab[si]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  55. Delay_MS(1);
  56. }
  57. void SEG_Display56(unsigned char wu,unsigned char liu)
  58. {
  59. P0=0XFF;
  60. P2=0XC0;P0=0X10; //打开控制数码管位选的锁存器,然后选中第五个数码管
  61. P2=0XFF;P0=tab[wu]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  62. Delay_MS(1);
  63. P0=0XFF;
  64. P2=0XC0;P0=0X20; //打开控制数码管位选的锁存器,然后选中第六个数码管
  65. P2=0XFF;P0=tab[liu]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  66. Delay_MS(1);
  67. }
  68. void SEG_Display78(unsigned char qi,unsigned char ba)
  69. {
  70. P0=0XFF;
  71. P2=0XC0;P0=0X40; //打开控制数码管位选的锁存器,然后选中第七个数码管
  72. P2=0XFF;P0=tab[qi]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  73. Delay_MS(1);
  74. P0=0XFF;
  75. P2=0XC0;P0=0X80; //打开控制数码管位选的锁存器,然后选中第八个数码管
  76. P2=0XFF;P0=tab[ba]; //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
  77. Delay_MS(1);
  78. }
  79. void Delay(uint MS) //@11.0592MHz
  80. {
  81. unsigned char i, j;
  82. for(i = 0;i < ms;i++)
  83. {
  84. _nop_();
  85. _nop_();
  86. _nop_();
  87. i = 11;
  88. j = 190;
  89. do
  90. {
  91. while (--j);
  92. } while (--i);
  93. }

本文转载自: https://blog.csdn.net/La_gloire/article/details/136304399
版权归原作者 La_gloire 所有, 如有侵权,请联系我们删除。

“【蓝桥杯单片机入门记录】动态数码管”的评论:

还没有评论