打印

为什么protues上仿真没问题,但是现实中数码管一直在闪动?

[复制链接]
20288|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
这是相关代码:
/* 头文件声明区 */
#include <STC89C5xRC.H>//89c52专用头文件
#include <init.h>//初始化底层驱动专用头文件
#include <key.h>//按键底层驱动专用头文件
#include <seg.h>//数码管底层驱动专用头文件
#include <led.h>//Led底层驱动专用头文件
#include <intrins.h>//包含了各种内联函数和宏,用于访问处理器特定的指令和功能的头文件


/* 变量声明区 */
unsigned char Key_Val,Key_Down,Key_Old,Key_Up;//按键专用变量
unsigned char Key_Slow_Down;//按键减速专用变量
unsigned char Seg_Buf[8] = {10,10,10,10,10,10,10,10};//数码管显示数据存放数组
unsigned char Seg_Point[8] = {0,0,0,0,0,0,0,0};//数码管小数点数据存放数组
unsigned char Seg_Pos;//数码管扫描专用变量
unsigned int Seg_Slow_Down;//数码管减速专用变量
unsigned char ucLed[8] = {0,0,0,0,0,0,0,0};//Led显示数据存放数组
unsigned char Seg_Disp_Mode=1;//数码管模式显示变量 0为学号显示 1为按键显示
unsigned char Seg_Student[16]={8,2,0,6,2,2,0,7,2,7,0,0,0,0,0,0};//学号存储数组


/*自定义延迟函数(毫秒)*/
void Delay(unsigned int xms)                //@12.000MHz
{
        unsigned char i, j;
  while(xms--)
        {
                i = 2;
          j = 239;
          do
                {
                        while (--j);
          } while (--i);
        }
}


/* 键盘处理函数 */
void Key_Proc()
{
        if(Key_Slow_Down) return;
        Key_Slow_Down = 1;//键盘减速程序

        Key_Val = Key_Read();//实时读取键码值
        Key_Down = Key_Val & (Key_Old ^ Key_Val);//捕捉按键下降沿
        Key_Up = ~Key_Val & (Key_Old ^ Key_Val);//捕捉按键上降沿
        Key_Old = Key_Val;//辅助扫描变量

       
  switch(Key_Down)
        {
                case 16:
                        if(Seg_Disp_Mode==1)
                   Seg_Buf[0] =0;
                   LcdGotoXY(3,0);                                                           
           LcdPrintStr("键盘显示0  ");
                break;
                case 1:
                        if(Seg_Disp_Mode==1)
                   Seg_Buf[0] =1;
                     LcdGotoXY(3,0);                                                           
           LcdPrintStr("键盘显示1  ");
                break;
                case 2:
                        if(Seg_Disp_Mode==1)
                   Seg_Buf[0] =2;
                     LcdGotoXY(3,0);                                                           
           LcdPrintStr("键盘显示2  ");
                break;
                case 3:
                        if(Seg_Disp_Mode==1)
                   Seg_Buf[0] =3;
                     LcdGotoXY(3,0);                                                           
           LcdPrintStr("键盘显示3  ");
                break;
                case 4:
                        if(Seg_Disp_Mode==1)
                   Seg_Buf[0] =4;
               LcdGotoXY(3,0);                                                           
           LcdPrintStr("键盘显示4  ");
                break;
                case 5:
                        if(Seg_Disp_Mode==1)
                   Seg_Buf[0] =5;
                     LcdGotoXY(3,0);                                                           
           LcdPrintStr("键盘显示5  ");
                break;
                case 6:
                        if(Seg_Disp_Mode==1)
                   Seg_Buf[0] =6;
                    LcdGotoXY(3,0);                                                           
           LcdPrintStr("键盘显示6  ");
                break;
                case 7:
                        if(Seg_Disp_Mode==1)
                   Seg_Buf[0] =7;
                    LcdGotoXY(3,0);                                                           
           LcdPrintStr("键盘显示7  ");
                break;
                case 8:
                        if(Seg_Disp_Mode==1)
                   Seg_Buf[0] =8;
                     LcdGotoXY(3,0);                                                           
           LcdPrintStr("键盘显示8  ");
                break;
                case 9:
                        if(Seg_Disp_Mode==1)
                   Seg_Buf[0] =9;
                    LcdGotoXY(3,0);                                                           
           LcdPrintStr("键盘显示9  ");
                break;
                case 10:
                        if(Seg_Disp_Mode==1)
                   Seg_Buf[0] =11;
                     LcdGotoXY(3,0);                                                           
           LcdPrintStr("键盘显示A  ");
                break;
                        case 11:
                        if(Seg_Disp_Mode==1)
                   Seg_Buf[0] =12;
                     LcdGotoXY(3,0);                                                           
           LcdPrintStr("键盘显示b  ");
                break;
                case 12:
                        if(Seg_Disp_Mode==1)
                   Seg_Buf[0] =13;
                    LcdGotoXY(3,0);                                                           
     break;
                case 13:
                        if(Seg_Disp_Mode==1)
                   Seg_Buf[0] =14;
                     LcdGotoXY(3,0);                                                           
           LcdPrintStr("键盘显示d  ");               
                break;
                case 14:
                        if(Seg_Disp_Mode==1)
                   Seg_Buf[0] =15;       
                     LcdGotoXY(3,0);                                                           
           LcdPrintStr("键盘显示E  ");
                break;
                case 15:
                        if(Seg_Disp_Mode==1)
                   Seg_Buf[0] =16;
                     LcdGotoXY(3,0);                                                           
           LcdPrintStr("键盘显示F  ");
                   break;
    case 17:
                        Seg_Disp_Mode = 0;
                   LcdWriteCmd(0xff);
                   LcdGotoXY(3,0);                                                           
           LcdPrintStr("学号流水显示");
                break;
          case 18:
                        Seg_Disp_Mode = 1;
                break;
        }
       
}



/* 信息处理函数 */
void Seg_Proc()
{
        unsigned char i,j;//循环变量
       
        if(Seg_Slow_Down) return;
        Seg_Slow_Down = 1;//数码管减速程序

        if(Seg_Disp_Mode==0)//学号显示界面
{
         Seg_Buf[7] =0;
                 for(i=0,j=0;i<=5,j<=15;i++,j++)
         {
         if(i==6)
                 {
                         i=0;
                   Seg_Buf =Seg_Student[j];
             Delay(500);
                 }
         else
                 {
       Seg_Buf =Seg_Student[j];
             Delay(500);
           }
   }
}
          if(Seg_Disp_Mode==1)//按键响应界面
{
     Seg_Buf[1] =10;   
                 Seg_Buf[2] =10;
                 Seg_Buf[3] =10;
                 Seg_Buf[4] =10;
                 Seg_Buf[5] =10;
                 Seg_Buf[6] =10;
                 Seg_Buf[7] =1;
}
}

/* 其他显示函数 */
void Led_Proc()
{

}


void Timer0Init(void)                //1毫秒@12.000MHz
{
        AUXR &= 0x7F;                //定时器时钟12T模式
        TMOD &= 0xF0;                //设置定时器模式
        TL0 = 0x18;                //设置定时初始值
        TH0 = 0xFC;                //设置定时初始值
        TF0 = 0;                //清除TF0标志
        TR0 = 1;                //定时器0开始计时
        ET0 = 1;    //定时器中断0打开
        EA = 1;     //总中断打开
}


void Timer0Server() interrupt 1
{  
        if(++Key_Slow_Down == 10) Key_Slow_Down = 0;//键盘减速专用
        if(++Seg_Slow_Down == 500) Seg_Slow_Down = 0;//数码管减速专用
        if(++Seg_Pos == 8) Seg_Pos = 0;//数码管显示专用
        Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
        Led_Disp(Seg_Pos,ucLed[Seg_Pos]);
}


/* Main函数 */
void main()
{
        Timer0Init();
        LcdInit();                                                                // LCD12864液晶功能初始化       
        LcdShowInit();
        while (1)
        {
                Key_Proc();
                Seg_Proc();
                Led_Proc();
        }
}

有些是关于lcd12864的代码我去掉了,与这个模块没关系



[img][/img]

[img][/img]

[img][/img]

[img][/img]

[img][/img]

使用特权

评论回复

相关帖子

沙发
dzydybz|  楼主 | 2024-4-6 17:44 | 只看该作者
就是像这样一样,protues上com端一直在扫描,但是数码管就显示一个一,这也是我想要的结果。
但是显示做的就是不行,数码管疯狂闪动,求求各位大佬,根本想不明白为什么。

IMG_20240406_172853.jpg (178.63 KB )

IMG_20240406_172853.jpg

IMG_20240406_172839.jpg (217.79 KB )

IMG_20240406_172839.jpg

使用特权

评论回复
评论
minfugan 2024-4-7 21:06 回复TA
@dzydybz :换个思路:只点亮一个数码管,依次显示0~9,刷新频率尽量慢,其他的都灭掉。观察显示0~9的时候,这个数码管是不是还闪烁。如果是,要么硬件电路没焊好要么数码管驱动写的不对。 
dzydybz 2024-4-7 17:08 回复TA
@minfugan :我改了下这个,这下他不闪烁了,但是不是我想要的效果,我就想要他最高位显示1,但是他现在每个都是全亮:( void Timer0Server() interrupt 1 { if(++Key_Slow_Down == 10) Key_Slow_Down = 0;//键盘减速专用 if(++Seg_Slow_Down == 200) Seg_Slow_Down = 0;//数码管减速专用 if(++Seg_Pos == 8) Seg_Pos = 0;//数码管显示专用 Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]); Led_Disp(Seg_Pos,ucLed[Seg_Pos]); } 
minfugan 2024-4-7 16:11 回复TA
大幅调高或者调低刷新频率,再观察实际效果 
板凳
qinlu123| | 2024-4-7 08:24 | 只看该作者
本帖最后由 qinlu123 于 2024-4-7 08:26 编辑

看看电路图,还有你的数码管驱动程序在哪里

使用特权

评论回复
地板
一叶倾城wwq| | 2024-4-7 08:39 | 只看该作者
那个delay一定要去掉,当然是刷新频率不够啦

使用特权

评论回复
5
dzydybz|  楼主 | 2024-4-7 12:53 | 只看该作者
qinlu123 发表于 2024-4-7 08:24
看看电路图,还有你的数码管驱动程序在哪里

这个是数码管底层函数

IMG_20240407_125209.jpg (113.5 KB )

IMG_20240407_125209.jpg

IMG_20240407_125204.jpg (127.36 KB )

IMG_20240407_125204.jpg

使用特权

评论回复
6
dzydybz|  楼主 | 2024-4-7 12:58 | 只看该作者
qinlu123 发表于 2024-4-7 08:24
看看电路图,还有你的数码管驱动程序在哪里

自己焊的与仿真的电路图

IMG_20240407_125501.jpg (180.67 KB )

IMG_20240407_125501.jpg

IMG_20240407_125401.jpg (237.19 KB )

IMG_20240407_125401.jpg

IMG_20240407_125232.jpg (187.27 KB )

IMG_20240407_125232.jpg

使用特权

评论回复
7
dzydybz|  楼主 | 2024-4-7 13:00 | 只看该作者
一叶倾城wwq 发表于 2024-4-7 08:39
那个delay一定要去掉,当然是刷新频率不够啦

所以关于自定义延迟函数的的都去掉吗?

使用特权

评论回复
8
dzydybz|  楼主 | 2024-4-7 13:05 | 只看该作者
一叶倾城wwq 发表于 2024-4-7 08:39
那个delay一定要去掉,当然是刷新频率不够啦

哦哦,是这两行去掉是吧

IMG_20240407_130457.jpg (197.2 KB )

IMG_20240407_130457.jpg

使用特权

评论回复
9
一叶倾城wwq| | 2024-4-7 13:35 | 只看该作者
dzydybz 发表于 2024-4-7 13:00
所以关于自定义延迟函数的的都去掉吗?

我看了下你的主函数,没有用到定时器,那你先不去掉,把delay的次数改小,就不会闪烁了

使用特权

评论回复
评论
一叶倾城wwq 2024-4-7 19:20 回复TA
@dzydybz :是在不行的话,你加我微信(a1255429984),我也不是一直有登录论坛,我给你解决 
一叶倾城wwq 2024-4-7 19:17 回复TA
@dzydybz :数码管每次刷新之前需要清屏,不清屏当然会全亮了 
dzydybz 2024-4-7 17:06 回复TA
我改了下这个,这下他不闪烁了,但是不是我想要的效果,我就想要他最高位显示1,但是他现在每个都是全亮:( void Timer0Server() interrupt 1 { if(++Key_Slow_Down == 10) Key_Slow_Down = 0;//键盘减速专用 if(++Seg_Slow_Down == 200) Seg_Slow_Down = 0;//数码管减速专用 if(++Seg_Pos == 8) Seg_Pos = 0;//数码管显示专用 Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]); Led_Disp(Seg_Pos,ucLed[Seg_Pos]); } 
dzydybz 2024-4-7 16:56 回复TA
没示波器 
一叶倾城wwq 2024-4-7 16:53 回复TA
@dzydybz :手里有示波器吗?量一下数码管COM口的频率,看看是多少,大于50HZ以上就不闪烁了。 
dzydybz 2024-4-7 16:51 回复TA
刚才试了试还是不行,数码管还是闪烁 
10
田舍郎| | 2024-4-7 22:42 | 只看该作者
刷新率低了么?

使用特权

评论回复
11
springvirus| | 2024-4-8 08:47 | 只看该作者
没看你程序,一般闪烁就是由于动态扫描的频率不够高,人眼能看到识别到闪烁,频率足够高时,就看不到了

可以用不同频率来测试显示效果,直到自己满意

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

20

帖子

1

粉丝