找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

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

查看数: 1904 | 评论数: 16 | 收藏 1
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2024-1-22 07:54

正文摘要:

/*按键K1K2加减数字数码管显示  按键K3K4加减数码管显示 单片机源程序如下: #include "STC8H.h" #include "intrins.h" unsigned char NixieTable[]={ 0x03,/*0*/      &n ...

回复

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;
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: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-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-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:72649 发表于 2024-1-26 18:15
lkc8210 发表于 2024-1-23 17:33
不说一下数码管程序显示亮度不一致原因是什么吗?

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

每组数码管需要消隐
ID:72649 发表于 2024-1-24 10:05
wulin 发表于 2024-1-23 22:05
不要把简单的事情复杂化。给你改了。仿真没有问题。

谢谢,这个程序在板子上能实现功能了,如果我要增加四个数码管应该这样修改。增加的数码管段码还是P2,位码分别为P10-P13.
ID:161164 发表于 2024-1-24 08:55
hjx5548 发表于 2024-1-23 23:10
现在主要是按键控制问题了,数码管问题解决了。

中断里不要用延时!
中断里不要用延时!
中断里不要用延时!
ID:72649 发表于 2024-1-23 23:10
zhuls 发表于 2024-1-23 16:53
感觉流程有点问题:
void TM1_Isr0()interrupt 1   //数码管扫描定时器0      
{   

现在主要是按键控制问题了,数码管问题解决了。
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 19:38
newlined 发表于 2024-1-23 12:01
P2口应该是驱动数码管的,如果是直接接的话,不一定能驱动,是不是要加三极管?再就是您可以加一个小的发光 ...

硬件没有问题的,P2直接驱动是根据stc实验箱电路做的,已经点亮数码管了
ID:161164 发表于 2024-1-23 17:33
不说一下数码管程序显示亮度不一致原因是什么吗?
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:72649 发表于 2024-1-23 12:47
这个四个按键分别控制两组三位数码管加减的程序,没有人能解决啊!
ID:227818 发表于 2024-1-23 12:01
P2口应该是驱动数码管的,如果是直接接的话,不一定能驱动,是不是要加三极管?再就是您可以加一个小的发光二极管,当检测到按键按下的,可以用另一个IO口,点亮这个二极管,先看看程序和硬件能不能检测到按键按下,一步一步的来。

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

Powered by 单片机教程网

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