微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 各位大神帮我看看这是怎么回事

各位大神帮我看看这是怎么回事

时间:10-02 整理:3721RD 点击:
刚学单片机不就,写了一个时钟程序,在proteus仿真中运行良好,但是将程序下载到实际的硬件上时,数码管会闪烁,实在是不知道怎么回事了,特来求助
#include<reg52.h>
/*------功能位设置-----------*/
sbit dula = P2^0;/*段锁存位*/
sbit wela = P2^1;/*位锁存位*/
sbit keyHour = P2^2;
sbit keyMinute = P2^3;
sbit keySecond = P2^4;
sbit watchStop = P2^5;
/*---------------------------*/
/*------------------函数初始化-----------------------------*/
void display(unsigned char,unsigned char);/*数码管显示程序*/
void delay(unsigned int);/*延时子程序*/
void timeLogic();/*时钟运行逻辑*/
void giveTimeTableSetValue();/*给时间码表设置值*/
void initTime0();/*定时器0初始化*/
void keyCheck();
/*---------------------------------------------------------*/
/*----------相关码表-----------------*/
/*段码表*/
unsigned char code SEGCCTable [] ={
    0x3f,0x06,0x5b,0x4f,
    0x66,0x6d,0x7d,0x07,
    0x7f,0x6f,0x77,0x7c,
    0x39,0x5e,0x79,0x71
};
/*位码表*/
unsigned char code WELATable [] = {
    0xFE,0xFD,0xFB,0xF7,
    0xEF,0xDF,0xBF,0x7F
};
unsigned char time[8];
/*-----------------------------------*/
/*--------变量的定义-----------------*/
unsigned char temp;/*用于循环计数*/
unsigned char timeCount;/*定时器计数*/
unsigned char hour=23; /*小时*/
unsigned char minute=59; /*分钟*/
unsigned char second=0; /*秒*/
/*-----------------------------------*/

/*主函数*/
main(){
    initTime0();/*定时器初始化*/
    while(1){
        keyCheck();
    }
}
/*显示子函数*/
void display(unsigned char duCode,unsigned char weCode){
        P0 = duCode;
        dula = 1;
        dula = 0;        
        P0 = weCode;
        wela = 1;
        wela = 0;
}
/*延时子函数*/
void delay(unsigned int xms){
    unsigned int i,j;
    for(i=0;i<xms;i++)
        for(j=0;j<110;j++);
}
/*时钟逻辑程序*/
void timeLogic(){
            if(timeCount == 20){
                    timeCount = 0;
                    second++;
                    if(second==60){
                        minute++;
                        second = 0;
                    }
                    if(minute==60){
                        hour++;
                        minute=0;
                    }
                    if(hour==24)
                        hour = 0;
                }
}
/*给时间表赋值子程序*/
void giveTimeTableSetValue(){
            time[0] = SEGCCTable[hour/10];
            time[1] = SEGCCTable[hour%10];
            
            time[2] = 0x40;
            
            time[3] = SEGCCTable[minute/10];
            time[4] = SEGCCTable[minute%10];
            time[5] = 0x40;
            time[6] = SEGCCTable[second/10];
            time[7] = SEGCCTable[second%10];
}
/*定时器0初始化*/
void initTime0(){
    TMOD |= 0x01;
    //TH0 = 0x00;
    //TL0 = 0x00;
    EA = 1;  /*总中断*/
    ET0 = 1;    /*定时器0中断打开*/
    TR0 = 1;    /*定时器0开关打开*/
}
void time0Inturp()interrupt 1 {
    TH0=(65536-50000)/256;
    TL0=(65536-50000)%256;
   
    timeCount++;
    timeLogic();   
        giveTimeTableSetValue();
        /*数码管显示逻缉(紧限时钟)*/
        for(temp=0;temp<8;temp++){
            display(time[temp],WELATable[temp]);
            delay(1);
            P0 = 0xFF;
            wela = 1;
            wela = 0;
        }
}
/*按键检测程序*/
void keyCheck(){
        if(keyHour==0){
            delay(10);
            if(keyHour==0){
                while(keyHour==0);
                hour++;//小时
                if(hour==24)
                        hour=0;
            }
        }
        
        if(keyMinute==0){
            delay(10);
            if(keyMinute==0){
                while(keyMinute==0);
                minute++;//分钟
                if(minute==60)
                        minute=0;
            }
        }
        if(keySecond==0){
            delay(10);
            if(keySecond==0){
                while(keySecond==0);
                second++;//秒
                if(second==60)
                        second=0;
            }
        }
        /*这段程序可要可不要,就是让数码管不显示,对应的P2.5口的按键*/
        if(watchStop==0){
            delay(10);
            if(watchStop==0){
                while(watchStop==0);
                TR0 = ~TR0;
            }
        }
}
附上仿真图片一张。



/*显示子函数*/,里面数码管扫描要短暂的延时

应该是延时函数的时间设定值太小!

这个延时我在调用这个函数的时候已经加了,就在中断程序里的那个for循环里面有个delay(1);

试过了,调的越高越闪烁

求解惑啊,都疑惑了两天了

试一下把显示函数写在主函数里面!键盘放在中断里!

像这种数码管显示  一般按键之类的尽量少用中断   主函数里面处理就可以了  中断时用在很重要的地方的   中断里面还延时  程序结构太混乱了

我试过了,按按键的时候会影响现实。

弱弱的说一句,我是写java的,这个程序中带有我写java的一些习惯,所以看起来会比较混乱,我想知道我写的这个程序在仿真里面行而放到真实硬件上就不行,我刚刚学不久,练习一下中断的使用,你说的很有价值,我以后会注意

看了一下你的按键延时用了大概30个毫秒延时 的确不适合放在中断里使用!

仿真软件是根据硬件来模拟的,不可能做到跟硬件完全一样,只能作为参考,但如果与硬件效果不一样,只能说明你的程序有问题了。

试试在/*显示子函数*/送段选和位选值的中间加上短暂的延时,再加上“P0=0xFF”

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top