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


    目录

    一、数码管动态显示概述

    二、动态数码管原理图

    (1)原理图

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

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

    三、动态数码管显示例程

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

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

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

    ①法一:

    ②法二:

    ③法三

    (4)例程4:多位数码管倒计时。本例以第6、7、8位数码管显示255→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
    3. #include
    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
    2. #include
    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
    3. #include
    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
    2. #include
    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
    2. #include
    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
    2. #include
    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. }

  • 相关阅读:
    Qt的.pro文件格式解析
    通俗易懂,多位P8以及以上的大佬联袂编写设计模式核
    自动化项目倍加福测距仪QSM WCS RS485 与西门子S7 200通信
    复习单片机:定时器/计数器部分(内含:1.51 单片机定时器原理 +2.51 单片机定时/计数器结构+3.定时器配置+4.代码部分+5.实验现象)
    第三章《数组与循环》第6节:嵌套循环
    Python前景如何?有哪些就业方向?
    ARM的异常处理
    单片机-如何让数码管动态显示
    大黑书《离散数学及其应用》之Dijkstra算法
    Java Static
  • 原文地址:https://blog.csdn.net/La_gloire/article/details/136304399