找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 594|回复: 16
收起左侧

单片机按键加减数码管显示不能实现,代码哪里出问题了?

[复制链接]
ID:72649 发表于 2024-1-22 07:54 | 显示全部楼层 |阅读模式
/*按键K1K2加减数字数码管显示  按键K3K4加减数码管显示
1.png

单片机源程序如下:
  1. #include "STC8H.h"
  2. #include "intrins.h"
  3. unsigned char NixieTable[]={ 0x03,/*0*/
  4.         0x9F,/*1*/
  5.         0x25,/*2*/
  6.         0x0D,/*3*/
  7.         0x99,/*4*/
  8.         0x49,/*5*/
  9.         0x41,/*6*/
  10.         0x1F,/*7*/
  11.         0x01,/*8*/
  12.         0x09,/*9*/};
  13. sbit k1 = P0^3 ;
  14. sbit k2 = P5^4 ;
  15. sbit k3 = P3^6 ;
  16. sbit k4 = P3^7 ;

  17. unsigned int Num,Num1;
  18.         
  19. void Delay1ms()                //@11.0592MHz
  20. {
  21.         unsigned char i, j;

  22.         i = 15;
  23.         j = 90;
  24.         do
  25.         {
  26.                 while (--j);
  27.         } while (--i);
  28. }

  29. void DelayXms(unsigned int x) //@11.0592MHz
  30. {
  31.         while (--x)
  32.         {
  33.    Delay1ms();
  34.          }
  35. }

  36. void Led_Seg(unsigned int date) //显示函数
  37. {        
  38.         unsigned int a,b,c;
  39.           a=date/100%10;                        //求百位
  40.           b=date/10%10;                                  //求十位
  41.           c=date%10;                                          //求个位

  42.           P14=1;P15=1;P33=1;
  43.              P2=NixieTable[a];//百位
  44.           P14=0;P15=1;P33=1;
  45.           DelayXms(5);
  46.                         
  47.           P14=1;P15=1;P33=1;  
  48.          P2=NixieTable[b];//十位
  49.           P15=0;P33=1;P14=1;
  50.           DelayXms(5);


  51.                 P14=1;P15=1;P33=1;  
  52.         P2=NixieTable[c];//个位
  53.           P33=0;P14=1;P15=1;
  54.           DelayXms(5);
  55. }

  56. void Led_Seg1(unsigned int date) //显示函数
  57. {        
  58.         unsigned int a,b,c;
  59.           a=date/100%10;                        //求百位
  60.           b=date/10%10;                                  //求十位
  61.           c=date%10;                                          //求个位

  62.           P00=1;P01=1;P02=1;
  63.              P2=NixieTable[a];//百位
  64.           P00=0;P01=1;P02=1;
  65.           DelayXms(5);
  66.                         
  67.           P00=1;P01=1;P02=1;   
  68.          P2=NixieTable[b];//十位
  69.          P00=1;P01=0;P02=1;
  70.           DelayXms(5);


  71.                 P00=1;P01=1;P02=1;   
  72.         P2=NixieTable[c];//个位
  73.          P00=1;P01=1;P02=0;
  74.           DelayXms(5);
  75. }

  76. unsigned char keyscan()
  77. {
  78.    char x=0;
  79.         if ( k1 == 0|k2 == 0|k3 == 0|k4 == 0)
  80.   {
  81.                 DelayXms(10);
  82.                 if (  k1 == 0|k2 == 0|k3 == 0|k4 == 0)
  83.                 {
  84.                 if (k1 == 0)        x=1;
  85.                 else if (k2 == 0)        x=2;
  86.     else if (k3 == 0)        x=3;
  87.                 else         x=4;
  88.                         while ( k1 == 0|k2 == 0|k3 == 0|k4 == 0);
  89.                 }
  90.    }
  91.         return(x);
  92. }

  93. void Timer0_init()  //1ms
  94. {
  95.         AUXR &= 0x7F;                        //定时器时钟12T模式
  96.         TMOD &= 0xF0;                        //设置定时器模式
  97.                                 TL0 = 0xCD;                                //设置定时初始值
  98.                                 TH0 = 0xD4;                                //设置定时初始值
  99.         TF0 = 0;                                //清除TF0标志
  100.         TR0 = 1;                                //定时器0开始计时
  101.         ET0 = 1;      //开T0中断
  102.         EA=1;        
  103. }
  104. void main ()
  105. {
  106.               P0M0 = 0x00; P0M1 = 0x00;
  107.         P1M0 = 0x00; P1M1 = 0xc0;
  108.         P2M0 = 0x00; P2M1 = 0x00;
  109.         P3M0 = 0x00; P3M1 = 0x00;
  110.         k1=k2=k3=k4=1;
  111.        Num=123;Num1=456;
  112.         Timer0_init() ;
  113.         
  114.         while(1)
  115.         {

  116.                                         unsigned char y;         

  117.                                 y=keyscan();
  118.                                         if(y!=0)        
  119.                          {
  120.                                  if(y==1)      Num++;
  121.          else if(y==2) Num--;
  122.          else if(y==3) Num1 ++;        
  123.          else         Num1--;         
  124.                          }

  125.                  }
  126.          }


  127. void TM1_Isr0()interrupt 1   //数码管扫描定时器0        
  128. {   
  129.          
  130.         unsigned int s;

  131.         if(++s>1)
  132.   {      s=0;
  133.       Led_Seg(Num);P00=1;
  134.                         Led_Seg1(Num1);
  135. }
  136. }
复制代码

回复

使用道具 举报

ID:227818 发表于 2024-1-23 12:01 | 显示全部楼层
P2口应该是驱动数码管的,如果是直接接的话,不一定能驱动,是不是要加三极管?再就是您可以加一个小的发光二极管,当检测到按键按下的,可以用另一个IO口,点亮这个二极管,先看看程序和硬件能不能检测到按键按下,一步一步的来。
回复

使用道具 举报

ID:72649 发表于 2024-1-23 12:47 来自手机 | 显示全部楼层
这个四个按键分别控制两组三位数码管加减的程序,没有人能解决啊!
回复

使用道具 举报

ID:69038 发表于 2024-1-23 16:53 | 显示全部楼层
感觉流程有点问题:
void TM1_Isr0()interrupt 1   //数码管扫描定时器0      
{   
  。。。
      Led_Seg(Num); //15ms+
      P00=1;
      Led_Seg1(Num1);//15ms+
。。。
}
中断才1ms,进入后要呆满30ms+...去北京开会,顺便去芬兰泡个桑拿。。
=================
这个测试过的,OK,定时、动扫、6位、共阴数码管。
每进一次中断只显示一位。
你参考一下。
void timer1() interrupt 3
{
char temp;
dis_dig++;   
dis_dig %= 6;  //6位数码管
led_bus = 0x00; //消隐@共阴
temp = 0xfe;
led_com =_crol_(temp,dis_dig); //位选
led_bus = dis_buf[dis_dig];    //段码
}
回复

使用道具 举报

ID:161164 发表于 2024-1-23 17:33 | 显示全部楼层
不说一下数码管程序显示亮度不一致原因是什么吗?
回复

使用道具 举报

ID:72649 发表于 2024-1-23 19:38 来自手机 | 显示全部楼层
newlined 发表于 2024-1-23 12:01
P2口应该是驱动数码管的,如果是直接接的话,不一定能驱动,是不是要加三极管?再就是您可以加一个小的发光 ...

硬件没有问题的,P2直接驱动是根据stc实验箱电路做的,已经点亮数码管了
回复

使用道具 举报

ID:213173 发表于 2024-1-23 22:05 | 显示全部楼层
hjx5548 发表于 2024-1-23 12:47
这个四个按键分别控制两组三位数码管加减的程序,没有人能解决啊!

不要把简单的事情复杂化。给你改了。仿真没有问题。
  1. //按键K1K2加减数字数码管显示  按键K3K4加减数码管显示
  2. #include "STC8H.h"
  3. #include "intrins.h"
  4. sbit k1 = P0^3 ;
  5. sbit k2 = P5^4 ;
  6. sbit k3 = P3^6 ;
  7. sbit k4 = P3^7 ;

  8. sbit w1 = P1^4 ;
  9. sbit w2 = P1^5 ;
  10. sbit w3 = P3^3 ;
  11. sbit w4 = P0^0 ;
  12. sbit w5 = P0^1 ;
  13. sbit w6 = P0^2 ;

  14. unsigned char NixieTable[]={
  15. 0x03,0x9f,0x25,0x0d,0x99,
  16. 0x49,0x41,0x1f,0x01,0x09};

  17. unsigned int Num,Num1;
  18. unsigned char a[6];
  19.       
  20. void Delay1ms()                //@11.0592MHz
  21. {
  22.         unsigned char i, j;
  23.         i = 15;
  24.         j = 90;
  25.         do
  26.         {
  27.         while (--j);
  28.         } while (--i);
  29. }

  30. void Write(unsigned char i)
  31. {   
  32.     w1=i&0x01;i>>=1;       
  33.     w2=i&0x01;i>>=1;
  34.     w3=i&0x01;i>>=1;
  35.     w4=i&0x01;i>>=1;
  36.     w5=i&0x01;i>>=1;
  37.     w6=i&0x01;
  38. }

  39. void Led_Seg() //显示函数
  40. {      
  41.         static unsigned char i;
  42.         P2=0xff;
  43.         Write(~(0x01<<i));
  44.         P2=a[i];
  45.         i=++i%6;
  46. }
  47. void keyscan()
  48. {
  49.         static unsigned char count=0;
  50.         static bit sign=0;
  51.         if(!k1||!k2||!k3||!k4)
  52.         {
  53.                 if(++count>=10 && sign==0)
  54.                 {
  55.                         sign=1;
  56.                         if(!k1)Num++;
  57.                         if(!k2)Num--;
  58.                         if(!k3)Num1++;
  59.                         if(!k4)Num1--;
  60.                 }
  61.         }
  62.         else
  63.         {
  64.                 count=0;
  65.                 sign=0;
  66.         }
  67. }

  68. void main ()
  69. {
  70.         P0M0 = 0x00; P0M1 = 0x00;
  71.         P1M0 = 0x00; P1M1 = 0x00;
  72.         P2M0 = 0x00; P2M1 = 0x00;
  73.         P3M0 = 0x00; P3M1 = 0x00;
  74.         P4M0 = 0x00; P4M1 = 0x00;
  75.         P5M0 = 0x00; P5M1 = 0x00;
  76.         Num=123;Num1=456;
  77.         while(1)
  78.         {
  79.                 a[0]=NixieTable[Num/100%10];
  80.                 a[1]=NixieTable[Num/10%10];
  81.                 a[2]=NixieTable[Num%10];
  82.                 a[3]=NixieTable[Num1/100%10];
  83.                 a[4]=NixieTable[Num1/10%10];
  84.                 a[5]=NixieTable[Num1%10];
  85.                 Led_Seg();
  86.                 keyscan();
  87.                 Delay1ms();
  88.         }
  89. }
复制代码
回复

使用道具 举报

ID:72649 发表于 2024-1-23 23:10 来自手机 | 显示全部楼层
zhuls 发表于 2024-1-23 16:53
感觉流程有点问题:
void TM1_Isr0()interrupt 1   //数码管扫描定时器0      
{   

现在主要是按键控制问题了,数码管问题解决了。
回复

使用道具 举报

ID:161164 发表于 2024-1-24 08:55 | 显示全部楼层
hjx5548 发表于 2024-1-23 23:10
现在主要是按键控制问题了,数码管问题解决了。

中断里不要用延时!
中断里不要用延时!
中断里不要用延时!
回复

使用道具 举报

ID:72649 发表于 2024-1-24 10:05 | 显示全部楼层
wulin 发表于 2024-1-23 22:05
不要把简单的事情复杂化。给你改了。仿真没有问题。

谢谢,这个程序在板子上能实现功能了,如果我要增加四个数码管应该这样修改。增加的数码管段码还是P2,位码分别为P10-P13.
回复

使用道具 举报

ID:72649 发表于 2024-1-24 10:10 | 显示全部楼层
lkc8210 发表于 2024-1-23 17:33
不说一下数码管程序显示亮度不一致原因是什么吗?

每组数码管需要消隐
回复

使用道具 举报

ID:72649 发表于 2024-1-26 18:15 | 显示全部楼层
lkc8210 发表于 2024-1-23 17:33
不说一下数码管程序显示亮度不一致原因是什么吗?

消隐问题
回复

使用道具 举报

ID:72649 发表于 2024-1-26 18:22 | 显示全部楼层
wulin 发表于 2024-1-23 22:05
不要把简单的事情复杂化。给你改了。仿真没有问题。

#ifndef __KEY_H__
#define __KEY__

#include "STC8H.h"

sbit k1 = P3^6 ;
sbit k2 = P3^7 ;
sbit k3 = P0^3 ;
sbit k4 = P5^4 ;
extern unsigned int Temp_Off,Temp_On;
#define KEY_DELAY_TIME                        50                
void Key_Service();
extern unsigned int Temp_Off,Temp_On;
#endif

#include "key.h"
unsigned int Temp_Off = 25,Temp_On =12;

unsigned char key1_lock_flag;                                               
unsigned char key1_cnt;     //按键蜂鸣器响 时长

unsigned char key2_lock_flag;                                               
unsigned char key2_cnt;     //按键蜂鸣器响 时长

unsigned char key3_lock_flag;                                               
unsigned char key3_cnt;     //按键蜂鸣器响 时长

unsigned char key4_lock_flag;                                               
unsigned char key4_cnt;     //按键蜂鸣器响 时长


unsigned char keyscan()       
{
unsigned char KeyNum = 0 ;
        if (k1)            //如果没有按下
                {
                key1_lock_flag = 0;   //清零自锁标志
                key1_cnt = 0 ;   //累计循环次数,也是消抖时间
                }
        else if(!key1_lock_flag)
                {
                        key1_cnt ++ ;
                        if(key1_cnt > KEY_DELAY_TIME)
                                {
                                key1_cnt = 0;            //清零
                                key1_lock_flag = 1 ;        //自锁标记,防止按键多次触发
                                KeyNum = 1 ;                 //赋键值编码
                                }
                }
               
        if (k2)            //如果没有按下
                {
                key2_lock_flag = 0;   //清零自锁标志
                key2_cnt = 0 ;   //累计循环次数,也是消抖时间
                }
        else if(!key1_lock_flag)
                {
                        key2_cnt ++ ;
                        if(key2_cnt > KEY_DELAY_TIME)
                                {
                                key2_cnt = 0;            //清零
                                key2_lock_flag = 1 ;        //自锁标记,防止按键多次触发
                                KeyNum = 2 ;                 //赋键值编码
                                }
                }

   if (k3)            //如果没有按下
                {
                key3_lock_flag = 0;   //清零自锁标志
                key3_cnt = 0 ;   //累计循环次数,也是消抖时间
                }
        else if(!key3_lock_flag)
                {
                        key3_cnt ++ ;
                        if(key1_cnt > KEY_DELAY_TIME)
                                {
                                key3_cnt = 0;            //清零
                                key3_lock_flag = 1 ;        //自锁标记,防止按键多次触发
                                KeyNum = 3 ;                 //赋键值编码
                                }
                }

    if (k4)            //如果没有按下
                {
                key4_lock_flag = 0;   //清零自锁标志
                key4_cnt = 0 ;   //累计循环次数,也是消抖时间
                }
        else if(!key4_lock_flag)
                {
                        key4_cnt ++ ;
                        if(key4_cnt > KEY_DELAY_TIME)
                                {
                                key4_cnt = 0;            //清零
                                key4_lock_flag = 1 ;        //自锁标记,防止按键多次触发
                                KeyNum = 4 ;                 //赋键值编码
                                }
                }               

return KeyNum;
}

void Key_Service()
{
        unsigned char a;
        a = keyscan()         ;
        switch(a)
                {
                                case0:                break;
                                case1:  Temp_Off  = 0; Temp_Off++;if (Temp_Off>150) Temp_Off=150;break;
                                case2:  Temp_Off  = 0;  Temp_Off--;if (Temp_Off<0) Temp_Off=0;break;
                                case3:  Temp_On = 0; Temp_On++;break;
                                case4:  Temp_On = 0;  Temp_On--;break;
                         default:
                                break;
                }
}

你的可以的,我这样数码管为什么就不能工作?
回复

使用道具 举报

ID:213173 发表于 2024-1-26 21:21 | 显示全部楼层
hjx5548 发表于 2024-1-24 10:05
谢谢,这个程序在板子上能实现功能了,如果我要增加四个数码管应该这样修改。增加的数码管段码还是P2,位 ...

void Write(unsigned int i)
{   
    w1=i&0x01;i>>=1;      
    w2=i&0x01;i>>=1;
    w3=i&0x01;i>>=1;
    w4=i&0x01;i>>=1;
    w5=i&0x01;i>>=1;
    w6=i&0x01;i>>=1;
    w7=i&0x01;i>>=1;
    w8=i&0x01;i>>=1;
    w9=i&0x01;i>>=1;
    w10=i&0x01;
}
void Led_Seg() //显示函数
{      
        static unsigned int i;
        P2=0xff;
        Write(~(0x01<<i));
        P2=a[i ];
        i=++i%10;
}
注意数据类型
回复

使用道具 举报

ID:72649 发表于 2024-1-29 00:09 | 显示全部楼层
wulin 发表于 2024-1-26 21:21
void Write(unsigned int i)
{   
    w1=i&0x01;i>>=1;      

这样修改了数码管显示不均匀
回复

使用道具 举报

ID:213173 发表于 2024-1-29 08:19 | 显示全部楼层
hjx5548 发表于 2024-1-29 00:09
这样修改了数码管显示不均匀

由于数据类型不同,CPU处理速度也不同,同一个函数,在不同的运行环境,也会产生不同效果。将数码管扫描放在定时器中断中运行。
  1. //按键K1K2加减数字数码管显示  按键K3K4加减数码管显示
  2. #include "STC8H.h"
  3. #include "intrins.h"
  4. sbit k1 = P0^3 ;
  5. sbit k2 = P5^4 ;
  6. sbit k3 = P3^6 ;
  7. sbit k4 = P3^7 ;

  8. sbit w1 = P1^4 ;
  9. sbit w2 = P1^5 ;
  10. sbit w3 = P3^3 ;
  11. sbit w4 = P0^0 ;
  12. sbit w5 = P0^1 ;
  13. sbit w6 = P0^2 ;
  14. sbit w7 = P1^0 ;
  15. sbit w8 = P1^1 ;
  16. sbit w9 = P1^2 ;
  17. sbit w10 =P1^3 ;

  18. unsigned char NixieTable[]={
  19. 0x03,0x9f,0x25,0x0d,0x99,
  20. 0x49,0x41,0x1f,0x01,0x09};

  21. unsigned int Num,Num1,Num2;
  22. unsigned char a[10];

  23. void Timer0_Init(void)                //1毫秒@11.0592MHz
  24. {
  25.         AUXR |= 0x80;                        //定时器时钟1T模式
  26.         TMOD &= 0xF0;                        //设置定时器模式
  27.         TL0 = 0xCD;                                //设置定时初始值
  28.         TH0 = 0xD4;                                //设置定时初始值
  29.         TF0 = 0;                                //清除TF0标志
  30.         TR0 = 1;                                //定时器0开始计时
  31.         ET0 = 1;                                //使能定时器0中断
  32.         EA  = 1;
  33. }

  34. void Write(unsigned int i)
  35. {   
  36.     w1=i&0x01;i>>=1;      
  37.     w2=i&0x01;i>>=1;
  38.     w3=i&0x01;i>>=1;
  39.     w4=i&0x01;i>>=1;
  40.     w5=i&0x01;i>>=1;
  41.     w6=i&0x01;i>>=1;
  42.     w7=i&0x01;i>>=1;
  43.     w8=i&0x01;i>>=1;
  44.     w9=i&0x01;i>>=1;
  45.     w10=i&0x01;
  46. }
  47. void Led_Seg() //显示函数
  48. {      
  49.         static unsigned char i;
  50.         P2=0xff;
  51.         Write(~(0x01<<i));
  52.         P2=a[i];
  53.         i=++i%10;
  54. }

  55. void keyscan()
  56. {
  57.         static unsigned char count=0;
  58.         static bit sign=0;
  59.         if(!k1||!k2||!k3||!k4)
  60.         {
  61.                 if(++count>=50 && sign==0)
  62.                 {
  63.                         sign=1;
  64.                         if(!k1)Num++;
  65.                         if(!k2)Num--;
  66.                         if(!k3)Num1++;
  67.                         if(!k4)Num1--;
  68.                 }
  69.         }
  70.         else
  71.         {
  72.                 count=0;
  73.                 sign=0;
  74.         }
  75. }

  76. void main ()
  77. {
  78.         unsigned char t;
  79.         P0M0 = 0x00; P0M1 = 0x00;
  80.         P1M0 = 0x00; P1M1 = 0x00;
  81.         P2M0 = 0x00; P2M1 = 0x00;
  82.         P3M0 = 0x00; P3M1 = 0x00;
  83.         P4M0 = 0x00; P4M1 = 0x00;
  84.         P5M0 = 0x00; P5M1 = 0x00;
  85.         Num=123;Num1=456;Num2=7890;
  86.         Timer0_Init();
  87.         while(1)
  88.         {
  89.                 switch(t)
  90.                 {
  91.                         case 0: a[0]=NixieTable[Num/100%10]; break;
  92.                         case 1: a[1]=NixieTable[Num/10%10]; break;
  93.                         case 2: a[2]=NixieTable[Num%10]; break;
  94.                         case 3: a[3]=NixieTable[Num1/100%10]; break;
  95.                         case 4: a[4]=NixieTable[Num1/10%10]; break;
  96.                         case 5: a[5]=NixieTable[Num1%10]; break;
  97.                         case 6: a[6]=NixieTable[Num2/1000%10]; break;
  98.                         case 7: a[7]=NixieTable[Num2/100%10]; break;
  99.                         case 8: a[8]=NixieTable[Num2/10%10]; break;
  100.                         case 9: a[9]=NixieTable[Num2%10]; break;
  101.                 }       
  102.                 t=++t%10;
  103.                 keyscan();
  104.         }
  105. }

  106. void Timer0_Isr(void) interrupt 1
  107. {
  108. //自动重装1ms
  109.         Led_Seg();
  110. }
复制代码
回复

使用道具 举报

ID:458247 发表于 2024-1-29 09:29 | 显示全部楼层
wulin 发表于 2024-1-29 08:19
由于数据类型不同,CPU处理速度也不同,同一个函数,在不同的运行环境,也会产生不同效果。将数码管扫描 ...

t=++t%10;

这句的意义是什么?0-10循环么?那不建议这么写啊,取模计算速度有点慢。不如用三目运算符了或者if了。
t=(++t >= 10) ? 0 : t;
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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