点亮一位数码管
段选:选中哪一位数码管
位选:选中的数码管要显示的内容
这是我对段选位选的理解,就是选中某个位置,赋值字形码,显示想要的图形
如果只想让第一个数码管显示,就只需要让com1 = 1即可,其他comx都=0
如果想让8个数码管都亮,就让com1~com8都赋值1,此时对数码管赋值,8个数码管都会显示一致的内容
如果想让不同数码管显示不同的内容且互不干扰,就需要不断的段选、位选,段选、位选,段选、位选。
先打开段选的锁存器(U8),用来选择哪个数码管亮,U8的Y6C = 1来控制
往前推导就是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的目的是消影,即将本次的段选位选和上一次的段选位选分隔开,互不影响,否则数码管会重影看不清,莎普爱思也没用
函数中有_nop_(); 需要调用#include "intrins.h"头文件
100s倒计时
用后三位数码管依次显示百十个位上的数字
我的思路是定义一个时间变量Time,初始化=100
在1s中断的程序里让Time--,这样就实现了100s倒计时
如何让这每一位都显示在数码管上呢?
我采用数位分离的方法,即将一个数的百位、十位、个位都分离出来,分别显示
三位数数位分离方法
bai = Time/100
shi = Time/10%10
ge = Time%10
数码管部分代码
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. }