单片机控制程序 问 设置时钟程序 因代码太多 以至于数码管用延时函数无法稳定显示,前辈们有什么方法?

用的是51单片机,因为动态显示代码存在于外部中断0函数中,目的是为了调节时钟并动态显示调节的结果,所以定时器中断不起作用,不能用于动态显示,目前只完成了能够实现秒分时其中... 用的是51单片机,因为动态显示代码存在于外部中断0 函数中,目的是为了调节时钟并动态显示调节的结果,所以定时器中断不起作用,不能用于动态显示,目前只完成了能够实现 秒 分 时其中之一的调节, 想过利用 创建调用函数 用 指针参数来节约代码,但可能因为消震用得太多,嵌入的太深,以至于一在外部中断中调用函数就使得KEIL4 宝镜告..求前辈们热心解答!!!
void int0() interrupt 0
{
uint key=0,temp;
uint i=12000;
while(i--);
if(key1==0)
{
time_s=time_m=time_h=0;
jishu[0]=jishu[1]=jishu[3]=jishu[4]=jishu[6]=jishu[7]=0;
while(1)
{
if(key1==0)
{
i=12000;
while(i--);
if(key1==0)
{break;}
}
P0=number[jishu[weishu-1]];
P2=control[weishu-1];
for(i=0;i<300;i++);
weishu++;
if(weishu==9)
weishu=1;
if(key2==0)
{
i=12000;
while(i--);
if(key2==0)
{
time_s+=1;
if(time_s==60)
time_s=0;
temp=time_s;
jishu[0]=time_s%10;
jishu[1]=time_s/10%10;
}
}
}
}
这个外部中断函数勉强合适, 除了在调的时候会有一点点不稳定之外,别无大碍
但功能上只能实现秒的转换 如果再加上2套分和时的调整代码,基本上晃得眼睛花而且不容易由while语句识别按键...实现对应功能.
展开
 我来答
joyoustech
推荐于2017-09-30 · TA获得超过1874个赞
知道小有建树答主
回答量:1465
采纳率:71%
帮助的人:1300万
展开全部
前面几个的回答都很好,找到了问题的原因和解决办法。
写程序之前一定要先从系统的级别构建一下程序的结构。
你的程序中,有数码管扫描显示、按键扫描、RTC三部分。
在构建程序结构的时候,考虑到几个部分的特点,一般情况如下:
1、如果时间显示到秒,应在100ms左右读一次RTC。
2、为了保证显示不删,应在20ms以内完成一次显示刷新,假设你用了20个数码管显示日期和时间。
3、按键是随机的,需要检测,一般按键按下的时间不小于50ms,可以考虑在10ms检测一次按键。

程序可以定义一个1ms的定时器,设置几个变量对定时器进行计数。
每个1ms定时到时,自加对定时器的计数,并更新数码管显示,20ms更新完20个数码管。
每到10ms检测一次按键,记录状态,与上次状态进行比较,如果连续两次或三次检测到按键按下,设置按键动作的标记,并确定如何更改显示,改变显存
如果不在设置状态,每100ms读一次RTC的值,将值更新到显存。

如果数码管需要调整亮度,可以将1ms定时器改为100us,分给每个数码管的1ms内,改变其点亮的时间,就可以调出十种亮度。

用这种架构做这个程序,处理器负担很轻,对所有的外设的响应一样迅速。你会感到51单片机还是能干很多活的。
追问
呵呵 谢谢你们的思路 都说得很好 给我上了一课  以前我都是看着题目就写程序 对架构,算法,没有考虑,谢谢你们的提醒,真心感谢,一会去实践实践。
追答
呵呵,刚上手都这样,以后慢慢更好了。
做而论道
高能答主

2013-01-21 · 把复杂的事情简单说给你听
知道大有可为答主
回答量:3万
采纳率:80%
帮助的人:1.1亿
展开全部
void int0() interrupt 0
{
uint key=0,temp;
uint i=12000;
while(i--);--这是延时多少时间哪??!!!!
……

在中断函数里面,延时干什么?

呵呵,编程的思路,有问题。
更多追问追答
追问
怎么思路有问题?说了哈  在中断调时的时候需要动态显示数码管所以需要一个延时函数 ,你刚刚说的uint key=0,temp;
uint i=12000;
while(i--);--
这个 是为了消震啊 ,确保按一下键位就是一个指令 而不是按一个键发出了好几次的指令,不知道么?
追答
按键,是有抖动的,需要延时消抖,延时后,确认按下了再进行处理。

呵呵,这样不紧不慢的东西,就不应该放在《外部中断》上。

在外部中断,应该连接那些需要《立即执行处理》的外设。

编程思路,确实需要端正一下了。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
zhxiufan
2013-01-21 · 知道合伙人软件行家
zhxiufan
知道合伙人软件行家
采纳数:14923 获赞数:38381
国家科技进步奖

向TA提问 私信TA
展开全部
....
uint ex0flag;
void int0() interrupt 0
{
ex0flag=1;//仅仅作为有键按下的标记
}

main()
{
....
uint key=0,temp,i;
ex0flag=0;
while(1)

{
if(ex0flag==1)如果有键按下则做如下按键处理
{
ex0flag=0;
i=12000;

while(i--);

if(key1==0)
{
time_s=time_m=time_h=0;
jishu[0]=jishu[1]=jishu[3]=jishu[4]=jishu[6]=jishu[7]=0;
while(1)
{
if(key1==0)
{
i=12000;
while(i--);
if(key1==0)
{break;}
}
P0=number[jishu[weishu-1]];
P2=control[weishu-1];
for(i=0;i<300;i++);
weishu++;
if(weishu==9)
weishu=1;
if(key2==0)
{
i=12000;
while(i--);
if(key2==0)
{
time_s+=1;
if(time_s==60)
time_s=0;
temp=time_s;
jishu[0]=time_s%10;
jishu[1]=time_s/10%10;
}
}
}
}
}
}
更多追问追答
追问
这个不错 可以 但是貌似遗漏了一点 要暂停计时器。不然就算没按键计时器一样运行让秒增加
追答
可以稍微修改一下,不按键就停止定时器TR0=0不就可以了吗,中断是处理特殊事件和紧急事件的,里面程序不能太多,特别忌讳的是延时。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
百度网友283d78e
2013-01-21 · 知道合伙人IT服务行家
百度网友283d78e
知道合伙人IT服务行家
采纳数:1491 获赞数:2979

向TA提问 私信TA
展开全部
中断当中使用标志位,不要运行太多程序,在大循环里去找标志位执行相应的程序
更多追问追答
追问
在大循环中执行了数遍 最多是跳的频率快了一点,没有任何稳定迹象
而且他确实需要这么多条语句才能达到效果
追答
楼上几位答得比我详尽,但是我已经说出了要点,能不能悟道,看你造化啦
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式