找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2227|回复: 8
收起左侧

单片机数码管显示程序问题求助

[复制链接]
ID:1001745 发表于 2023-2-7 14:40 | 显示全部楼层 |阅读模式
各位大神:新年好!    最近做了一个温度报警器,数码管为3位的共阴数码管。在全显时显示正常的,在动态显示时就会出现笔画暗淡不清楚的现象。看了一下论坛,感觉应该是程序中的消隐没有处理好,因个人能力有限,程序基本上都是摘录论坛各路大神的现有程序修改的。希望各位大神能帮忙看一下程序看看是否程序有问题,谢谢!
  1. /***********四位共阴数码管驱动程序************/
  2. //stc15w单片机
  3. //1在主程序前加上初始化init();程序
  4. //2硬件连接变动时需修改下面的参数
  5. sbit H1        = P1^0;//设置第1位数码管阴极连接的I/O口
  6. sbit H2        = P1^1;//设置第2位数码管阴极连接的I/O口
  7. sbit H3        = P1^2;//设置第3位数码管阴极连接的I/O口
  8. //sbit H4        = P1^5;//设置第4位数码管阴极连接的I/O口
  9. sbit a        = P3^5;
  10. sbit b        = P3^4;
  11. sbit c        = P3^3;
  12. sbit d        = P3^2;
  13. sbit e        = P2^1;
  14. sbit f        = P2^0;
  15. sbit g        = P3^7;
  16. sbit dp        = P3^6;

  17. #define P1M0SET                0x00 //设置I/O口工作方式//00000000(左到右,高到低位)
  18. #define P1M1SET                0x00 //设置I/O口工作方式//00000000
  19. #define P3M0SET                0xff //设置I/O口工作方式//11111111
  20. #define P3M1SET                0x00 //设置I/O口工作方式//00000000
  21. #define P2M0SET     0xff //设置IO口工作方式11111111
  22. #define P2M1SET     0x00 //设置IO口工作方式00000000
  23. /*****以上定义需要根据实际硬件情况更改******/
  24. data unsigned char PWM;//显示亮度
  25. #define light                        9         //设置LED显示的亮度(值域:1~9)
  26. #define DELAY_L                12         //设置每一个点显示的时间长度(1~20)
  27. /********* 延时函数    ***************/
  28. void delay (unsigned int a){ // 用于点扫描的延时
  29.         unsigned int i;
  30.         while( a-- != 0){
  31.                 for(i = 0; i < DELAY_L; i++);
  32.         }                                      
  33. }
  34. /*********************************************************************************************/
  35. unsigned char code disdata[]={
  36. 0x3F,0x06,0x5B,0x4F,0x66,
  37. 0x6D,0x7D,0x07,0x7F,0x6F,
  38. 0x77,0x7C,0x39,0x5E,0x79,
  39. 0x71,0x40};//0-9,A-F,-



  40. //数码管:正向位置;共YIN极;正向连接

  41. void dis_off (void)
  42. {
  43.         P3 = ~P3M0SET; //关所有显示
  44.     P2 = ~P2M0SET;
  45.         H1=H2=H3=1;//P1 = ~P1M0SET;
  46.         delay(10-PWM);


  47. }
  48. /*********************************************************************************************/
  49. void displayHH1 (unsigned char q){ //第1位数码管显示程序
  50.         unsigned char i;
  51.         i = q & 0x01;
  52.         if(i == 0x01){
  53.                 H1 = 0;a = 1;}delay(PWM);dis_off();
  54.         i = q & 0x02;
  55.         if(i == 0x02){
  56.                 H1 = 0;b = 1;}delay(PWM);dis_off();
  57.         i = q & 0x04;
  58.         if(i == 0x04){
  59.                 H1 = 0;c = 1;}delay(PWM);dis_off();
  60.         i = q & 0x08;
  61.         if(i == 0x08){
  62.                 H1 = 0;d = 1;}delay(PWM);dis_off();
  63.         i = q & 0x10;
  64.         if(i == 0x10){
  65.                 H1 = 0;e = 1;}delay(PWM);dis_off();
  66.         i = q & 0x20;
  67.         if(i == 0x20){
  68.                 H1 = 0;f = 1;}delay(PWM);dis_off();
  69.         i = q & 0x40;
  70.         if(i == 0x40){
  71.                 H1 = 0;g = 1;}delay(PWM);dis_off();
  72.         i = q & 0x80;
  73.         if(i == 0x80){
  74.                 H1 = 0;dp = 1;}delay(PWM);dis_off();
  75. }
  76. /*********************************************************************************************/
  77. void displayHH2 (unsigned char q){ //第2位数码管显示程序
  78.         unsigned char i;
  79.         i = q & 0x01;
  80.         if(i == 0x01){
  81.                 H2 = 0;a = 1;}delay(PWM);dis_off();
  82.         i = q & 0x02;
  83.         if(i == 0x02){
  84.                 H2 = 0;b = 1;}delay(PWM);dis_off();
  85.         i = q & 0x04;
  86.         if(i == 0x04){
  87.                 H2 = 0;c = 1;}delay(PWM);dis_off();
  88.         i = q & 0x08;
  89.         if(i == 0x08){
  90.                 H2 = 0;d = 1;}delay(PWM);dis_off();
  91.         i = q & 0x10;
  92.         if(i == 0x10){
  93.                 H2 = 0;e = 1;}delay(PWM);dis_off();
  94.         i = q & 0x20;
  95.         if(i == 0x20){
  96.                 H2 = 0;f = 1;}delay(PWM);dis_off();
  97.         i = q & 0x40;
  98.         if(i == 0x40){
  99.                 H2 = 0;g = 1;}delay(PWM);dis_off();
  100.         i = q & 0x80;
  101.         if(i == 0x80){
  102.                 H2 = 0;dp = 1;}delay(PWM);dis_off();
  103. }
  104. /*********************************************************************************************/
  105. void displayHH3 (unsigned char q){ //第3位数码管显示程序
  106.         unsigned char i;
  107.         i = q & 0x01;
  108.         if(i == 0x01){
  109.                 H3 = 0;a = 1;}delay(PWM);dis_off();
  110.         i = q & 0x02;
  111.         if(i == 0x02){
  112.                 H3 = 0;b = 1;}delay(PWM);dis_off();
  113.         i = q & 0x04;
  114.         if(i == 0x04){
  115.                 H3 = 0;c = 1;}delay(PWM);dis_off();
  116.         i = q & 0x08;
  117.         if(i == 0x08){
  118.                 H3 = 0;d = 1;}delay(PWM);dis_off();
  119.         i = q & 0x10;
  120.         if(i == 0x10){
  121.                 H3 = 0;e = 1;}delay(PWM);dis_off();
  122.         i = q & 0x20;
  123.         if(i == 0x20){
  124.                 H3 = 0;f = 1;}delay(PWM);dis_off();
  125.         i = q & 0x40;
  126.         if(i == 0x40){
  127.                 H3 = 0;g = 1;}delay(PWM);dis_off();
  128.         i = q & 0x80;
  129.         if(i == 0x80){
  130.                 H3 = 0;dp = 1;}delay(PWM);dis_off();
  131. }
  132. void diplay_data (unsigned char l,unsigned char q){
  133.                 switch (l){//显示的数码管位置               
  134.                                 case 1://                        
  135.                                         displayHH1(q); //将显示数据送入               
  136.                                         break;//               
  137.                                 case 2://                        
  138.                                         displayHH2(q); //将显示数据送入               
  139.                                         break;//               
  140.                                 case 3://                        
  141.                                         displayHH3(q); //将显示数据送入               
  142.                                         break;//
  143. //                                case 4://                        
  144. //                                        displayHH4(q); //将显示数据送入               
  145. //                                        break;//                        
  146.                                 
  147.                 }
  148. }

  149. /*******************************************/
  150. void init (void){        
  151.                 P3M1=P3M1SET;
  152.                 P3M0=P3M0SET;
  153.                 P1M0=P1M0SET;
  154.                 P1M1=P1M1SET;
  155.                 dis_off();
  156.                 PWM = light;}
  157. /******************显示程序*************************
  158. i=t/100;
  159. diplay_data (1,disdata[i]);
  160. i=t%100/10;
  161. diplay_data (2,disdata[i]+0x80);
  162. i=t%100%10;
  163. diplay_data (3,disdata[i]); */
复制代码


篇幅限制,具体全部显示代码见附件。
4LED_YIN.rar (1.25 KB, 下载次数: 7)
回复

使用道具 举报

ID:1001745 发表于 2023-2-7 18:03 | 显示全部楼层
111.png 测试图片 222.png 显示部分原理图
回复

使用道具 举报

ID:824490 发表于 2023-2-7 22:11 | 显示全部楼层
你这个是MCU直驱数码管,要想提高亮度只能是亮时延时加长,但是加太长会闪。。
小于20mS内要扫一次,3个数码管,每个点亮约6ms..这是没有其它任务时的时间分配,若有其它任务,则适当调整。或是用定时器中断方式把时间分片,每6mS点亮一个数码管。
回复

使用道具 举报

ID:1001745 发表于 2023-2-8 08:36 | 显示全部楼层
名字不是重点 发表于 2023-2-7 22:11
你这个是MCU直驱数码管,要想提高亮度荒苁橇潦毖邮奔映ぃ羌犹せ嵘痢!�
小于20mS内要扫一次,3个数 ...

感谢大神的回复,小弟不才。您说的这些小弟不知道如何修改啊。
回复

使用道具 举报

ID:213173 发表于 2023-2-8 10:44 | 显示全部楼层
mcuhui 发表于 2023-2-7 18:03
测试图片显示部分原理图

你这个数码管动态显示函数太奇葩了,不可能正常显示。按你的硬件图,给你写个示例。适用于STC15系列MCU,主函数中5ms延时不是必须的,是留有足够的时间用于添加其它应用程序。主函数循环周期在1~6ms范围都不会影响数码管动态显示。
无标题.jpg



  1. #include <STC15F2K60S2.H>
  2. /***********四位共阴数码管驱动程序************/
  3. //stc15w单片机
  4. //1在主程序前加上初始化init();程序
  5. //2硬件连接变动时需修改下面的参数
  6. sbit H1        = P1^0;//设置第1位数码管阴极连接的I/O口
  7. sbit H2        = P1^1;//设置第2位数码管阴极连接的I/O口
  8. sbit H3        = P1^2;//设置第3位数码管阴极连接的I/O口
  9. //sbit H4        = P1^5;//设置第4位数码管阴极连接的I/O口
  10. sbit a        = P3^5;//11111100
  11. sbit b        = P3^4;
  12. sbit c        = P3^3;
  13. sbit d        = P3^2;
  14. sbit e        = P2^1;//00000011
  15. sbit f        = P2^0;
  16. sbit g        = P3^7;
  17. sbit p        = P3^6;
  18. sbit DQ       = P2^4;
  19. unsigned char code disdata[]={
  20. 0x3F,0x06,0x5B,0x4F,0x66,
  21. 0x6D,0x7D,0x07,0x7F,0x6F,
  22. 0x77,0x7C,0x39,0x5E,0x79,
  23. 0x71,0x40};//0-9,A-F,-
  24. unsigned char data dis_buf[3];//缓存
  25. unsigned char num=123;//模拟欲显示数12.3

  26. /****1ms延时子程序(12MHz 1T)****/
  27. void Delay_ms(unsigned int t)//1T@12MHz
  28. {
  29.         unsigned int i,j;
  30.         for(i=t;i>0;i--)
  31.                 for(j=1200;j>0;j--);//j=1100 1T@11.0592MHz
  32. }
  33. void dula(unsigned char i)        //写入8位段码
  34. {   
  35.         a=i&0x01;i>>=1;
  36.         b=i&0x01;i>>=1;
  37.         c=i&0x01;i>>=1;
  38.         d=i&0x01;i>>=1;
  39.         e=i&0x01;i>>=1;
  40.         f=i&0x01;i>>=1;
  41.         g=i&0x01;i>>=1;
  42.         p=i&0x01;
  43. }
  44. void wela(unsigned char i)        //写入3位位码
  45. {
  46.         H1=i&0x01;i>>=1;
  47.         H2=i&0x01;i>>=1;
  48.         H3=i&0x01;
  49. }
  50. void display()//数码管动态显示函数
  51. {
  52.         static unsigned char i=0;
  53.         switch(i)//分解数据
  54.         {
  55.                 case 0: dis_buf[0] = disdata[num/100%10];    break;
  56.                 case 1: dis_buf[1] = disdata[num/10%10]|0x80;break;//加小数点
  57.                 case 2: dis_buf[2] = disdata[num%10];        break;
  58.         }       
  59.         wela(0xff);//位码消隐
  60.         dula(dis_buf[i]);//送段码
  61.         wela(~(0x01<<i));//送位码
  62.         i=++i%3;    //循环计数
  63. }
  64. /*******************************************/
  65. void init(void)
  66. {
  67.         P1M0 = 0x00;
  68.         P1M1 = 0x00;
  69.         P2M0 = 0x03;//0000 0011推挽
  70.         P2M1 = 0x00;
  71.         P3M0 = 0xfe;//1111 1100推挽
  72.         P3M1 = 0x00;
  73.         P5M0 = 0x00;
  74.         P5M1 = 0x00;
  75. }
  76. void main()//主函数
  77. {
  78.         init();
  79.         while(1)
  80.         {
  81.                 display();        //数码管显示
  82.                 Delay_ms(5);                //延时控制主循环时间
  83.         }
  84. }
复制代码



回复

使用道具 举报

ID:1001745 发表于 2023-2-10 19:44 | 显示全部楼层
wulin 发表于 2023-2-8 10:44
你这个数码管动态显示函数太奇葩了,不可能正常显示。按你的硬件图,给你写个示例。适用于STC15系列MCU, ...

感谢大神的不吝赐教,我按照你的这个代码添加到程序中去,总算编译过了,但只显示12.3,其中12。很淡,3很亮。不知道什么原因。我把整个程序上传上来,希望大师帮忙看看怎么修改。谢谢啦
回复

使用道具 举报

ID:1001745 发表于 2023-2-10 19:46 | 显示全部楼层
temp_detection.rar (39.78 KB, 下载次数: 10)
回复

使用道具 举报

ID:213173 发表于 2023-2-10 20:56 | 显示全部楼层
mcuhui 发表于 2023-2-10 19:44
感谢大神的不吝赐教,我按照你的这个代码添加到程序中去,总算编译过了,但只显示12.3,其中12。很淡,3 ...

数码管各位亮度不均匀是各位显示时间不相同。你没有真正看懂给你的示例,为什么给你写5ms的主循环周期,就是给你留有充足时间来调用读取温度值、按键扫描、报警等程序。可是你把大量的时间消耗在阻滞型延时上了,这是编程的大忌。由于ds18b20对时序要求很高,完整读一次ds18b20温度值远远超过5ms。这就要把读ds18b20温度拆分成5部分,主循环1次只完成1部分。这就完美解决了在时间上与数码管、蜂鸣器的冲突。再给你一个示例参考,重点要理解这部分:
  1. void ReadTemperature()//读取温度的函数
  2. {
  3.         static uchar i=0;
  4.         uchar a=0,b=0;
  5.         uint t=0;
  6.         switch(i)
  7.         {
  8.                 case 0: int_DS18b20();
  9.                                 write_byte(0xcc);//跳过读写序列号
  10.                                 write_byte(0x44);//启动温度转换
  11.                                 break;
  12.                 case 1: break;//利用定时循环周期替代5ms延时
  13.                 case 2: int_DS18b20();
  14.                                 write_byte(0xCC);//跳过读写序列号
  15.                                 write_byte(0xBE);//读温度寄存器
  16.                                 break;
  17.                 case 3: break;//利用定时循环周期替代5ms延时

  18.                 case 4: a=read_byte();//读取温度低8位
  19.                                 b=read_byte();  //读取温度高8位
  20.                                 t=b<<8|a;
  21.                                 sh=t>>4;//取整数
  22.                                 ge=(a&0x0f)*0.625;//取1位小数
  23.                                 break;
  24.         }
  25.         i++;i%=5;
  26. }
复制代码
4位数码管时钟温度表仿真.rar (332.03 KB, 下载次数: 6)
回复

使用道具 举报

ID:1060328 发表于 2023-2-10 21:15 | 显示全部楼层
  Delay_ms(5);      

把5改小试试,用2或者3
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表