21ic问答首页 - 为什么protues上仿真没问题,但是现实中数码管一直在闪动?
为什么protues上仿真没问题,但是现实中数码管一直在闪动?
dzydybz2024-04-06
这是相关代码:
/* 头文件声明区 */
#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]
/* 头文件声明区 */
#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]
赞0
可以用不同频率来测试显示效果,直到自己满意
评论
2024-04-08
赞0
评论
2024-04-07
赞0
我看了下你的主函数,没有用到定时器,那你先不去掉,把delay的次数改小,就不会闪烁了
评论
2024-04-07
@dzydybz :是在不行的话,你加我微信(a1255429984),我也不是一直有登录论坛,我给你解决
@dzydybz :数码管每次刷新之前需要清屏,不清屏当然会全亮了
我改了下这个,这下他不闪烁了,但是不是我想要的效果,我就想要他最高位显示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 :手里有示波器吗?量一下数码管COM口的频率,看看是多少,大于50HZ以上就不闪烁了。
刚才试了试还是不行,数码管还是闪烁
赞0
哦哦,是这两行去掉是吧
评论
2024-04-07
赞0
所以关于自定义延迟函数的的都去掉吗?
评论
2024-04-07
赞0
自己焊的与仿真的电路图
评论
2024-04-07
赞0
这个是数码管底层函数
评论
2024-04-07
赞0
评论
2024-04-07
赞0
看看电路图,还有你的数码管驱动程序在哪里
评论
2024-04-07
您需要登录后才可以回复 登录 | 注册