7319|16

135

帖子

1

TA的资源

一粒金砂(中级)

楼主
 

按键按下时数码管显示会有些闪烁(续) [复制链接]

大侠们!!!
好好的帮我看看这个程序好吗?
之前的程序
https://bbs.eeworld.com.cn/forum. ... 5521&fromuid=582339
(出处: 电子工程世界-论坛)
下面是我更改之后的程序!之前的闪烁消除了,就是对于定时器中断1里的这段程序
  if(flag==1)/*有按键按下时蜂鸣器响一下(除按下S2键数码管不显示时不响外)*/
    {               
        BZ=1;
        cnt++;
        if(cnt==12)
        {
            cnt=0;
            BZ=0;
            flag=0;
        }
是放在中断里比较好还是主程序中~~~另外我重复的按键按得快的时候有时会死机,为什么不会看们狗复位呢~~~~~~~~~~   

/*************************************************************
实验效果:用定时器定时来控制继电器的工作,初始时定时为150分钟、
继电器吸合、同时所定的时间在三位数码管上显示出来。开始时定时器
工作,按下S1确认定时键,每过1分钟时间减1,当所定的150分钟减为0时
继电器释放、定时器0不工作、数码管不显示单片机进入掉电模式。按下S1、
S2、S3均可唤醒单片机。S1的作用是按下该键时确认开始定时键,S2的作用
是按下该键时数码管显示或者不显示之间进行切换,S3的作用是设置需要定
时的时间,每按该键定时时间减10分钟。同时每个按键按下时都会发出滴的
一声。晶振采用12MHZ.
****************************************************************/
#include"STC15F204EA.h"
#include
#define GPIO_DIG P1
#define Fosc 12000000

sbit DS1=P3^7;
sbit DS2=P0^0;/*我所使用的单片机是A版本P0.0。B版本为P5.4*/
sbit DS3=P0^1;/*我所使用的单片机是A版本,所以这里用P0.1。B版本为P5.5*/      
sbit S3=P3^0;
sbit S2=P3^2;
sbit S1=P3^3;
sbit BZ=P3^4;
sbit RELAY=P3^5;
bit flag;
unsigned int Time;
unsigned char bit100,bit10,bit1, Num=150;
unsigned char code DIG[10]={0x7e,0x0c,0xb6,0x9e,0xcc,0xda,0xfa,0x0e,0xfe,0xde};
void Delay3ms();                //@12.000MHz
void Delay10ms();                //@12.000MHz

main()
{       
    unsigned char a;
    BZ=0;
    /*喂狗*/
    WDT_CONTR=0x34;/*12.000MHz,看门狗溢出时间为1秒左右,溢出之后看门狗复位*/
    P5M0=0x30;
    P3M0=0xB0;
          P1M0=0XFF;

    IT1=1;/*外部中断1为下降沿触发方式*/
    IT0=1;/*外部中断0为下降沿触发方式*/
    INT_CLKO=0x40;/*允许外部中断4中断*/
    EX1=1;/*允许外部中断1中断*/
    EX0=1;/*允许外部中断0中断*/       

    TMOD=0x00;/*设定定时器0、1工作模式为0*/
        AUXR=0x00;/*设定定时器0、1工作在12T模式*/
        TH0=(65536-Fosc/12/20)>>8;/*给定时器0赋初值,定时50ms*/
        TL0=(65536-Fosc/12/20);
        TH1=(65536-4*Fosc/12000)>>8;/*给定时器0赋初值,定时3ms*/
        TL1=(65536-4*Fosc/12000);
        ET0=1;/*开定时器0中断允许*/
        ET1=1;/*开中断允许*/
    PT1=1;/*设置定时器1为高优先级*/
        TR0=0;/*关闭定时器0*/
        TR1=1;/*关闭定时器1*/
        EA=1;/*打开总中断*/



        while(1)
        {       

        WDT_CONTR=0x34;/*12.000MHz,看门狗溢出时间为1秒左右,溢出之后看门狗复位*/
        /*喂狗*/
            a=Num;
            bit100=a/100;/*提取百位*/
            a=a%100;

            bit10=a/10;/*提取十位*/

            bit1=a%10;/*提取个位*/
        RELAY=1;/*打开继电器*/
        if(Time==20)
        {
            Time=0;
            Num--;
            if(Num==0)
            {
                Num=180;
                RELAY=0;/*关闭继电器*/
                TR0=0;/*关闭定时器0*/
                TR1=0;/*关闭定时器1*/
                GPIO_DIG=0;/*关闭数码管*/
                PCON=0x02;/*掉电模式,单片机睡觉*/
            }   
        }

        if(TR1==0)/*关闭数码管显示*/
        {
           //DS1=1;DS2=1;DS3=1;
            GPIO_DIG=0;
        }
        }                          
}
void Timr0() interrupt 1
{
        Time++;   

}

void Int0() interrupt 0
{
    Delay10ms();
    if(S2==0)
    {
        TR1=~TR1;/*数码管显示位取反*/
        flag=1;
    }   
}

void Int1() interrupt 2
{   
    Delay10ms();
    if(S1==0)
    {
        flag=1;
        TR0=1;/*定时器0启动*/
        TR1=1;/*启动定时计数器1扫描显示数码管*/
    }

}

void Int4() interrupt 16
{
    Delay10ms();
    if(S3==0)
    {   
        TR0=0;/*关闭定时计数器0进行调时间*/
        flag=1;
        if(TR1==1)/*数码管显示时才可以进行调节时间*/
        {
            Num=Num-10;
            if(Num<=0)
            Num=180;
        }
        TR1=1;/*启动定时计数器1扫描显示数码管*/
    }
}
void Timr1() interrupt 3
{
    unsigned char n,cnt;
    if(flag==1)/*有按键按下时蜂鸣器响一下(除按下S2键数码管不显示时不响外)*/
    {               
        BZ=1;
        cnt++;
        if(cnt==12)
        {
            cnt=0;
            BZ=0;
            flag=0;
        }     
    }
    if(Num>=100)
    {
        switch(n)
        {
            case(0):DS1=1;/*关闭第3位数码管显示*/                      
                        GPIO_DIG=DIG[bit100];/*送出数字段码*/
                        DS3=0; /*打开第一个数码的位选*/
                    break;
            case(1):DS3=1;/*关闭第1位数码管显示*/                 
                        GPIO_DIG=DIG[bit10];/*送出数字段码*/
                        DS2=0;/*打开第二个数码的位选*/
                    break;
            case(2):DS2=1;/*关闭第2位数码管显示*/                       
                        GPIO_DIG=DIG[bit1];/*送出数字段码*/
                        DS1=0;/*打开第三个数码的位选*/
                    break;
        }
    }
    else if((Num>=10)&&(Num<100))
    {   
        switch(n)
        {            
            case(0): DS1=1;/*关闭第3位数码管显示*/
                     break;                      
            case(1): DS3=1;/*关闭第1位数码管显示*/               
                          GPIO_DIG=DIG[bit10];/*送出数字段码*/
                         DS2=0;/*打开第二个数码的位选*/
                     break;
            case(2): DS2=1;/*关闭第2位数码管显示*/                       
                         GPIO_DIG=DIG[bit1];/*送出数字段码*/
                          DS1=0;/*打开第三个数码的位选*/
                     break;
        }
    }
    else
    {
        switch(n)
        {
            case(0): DS1=1;/*关闭第3位数码管显示*/
                     DS3=1;/*关闭第1位数码管显示*/
                     break;            
            case(1): DS2=1;/*关闭第2位数码管显示*/
                     break;      
            case(2): GPIO_DIG=DIG[bit1];/*送出数字段码*/
                         DS1=0;/*打开第三个数码的位选*/
                     break;
        }
    }
    n++;
    if(n>2)
    n=0;
}        

void Delay3ms()                //@12.000MHz
{
        unsigned char i, j;

        _nop_();
        _nop_();
        i = 36;
        j = 1;
        do
        {
                while (--j);
        } while (--i);
}
void Delay10ms()                //@12.000MHz
{
        unsigned char i, j;

        _nop_();
        _nop_();
        i = 117;
        j = 183;
        do
        {
                while (--j);
        } while (--i);
}



此帖出自51单片机论坛

最新回复

中断里不能用延时函数   ,这是常识  详情 回复 发表于 2015-2-17 16:34
点赞 关注
 

回复
举报

1万

帖子

24

TA的资源

版主

沙发
 
如果用51单片机,建议你可以去试试RTX51Tiny,一个简单易用的RTOS。使用RTOS实现你现在的功能,你在和现在程序比较试试。
此帖出自51单片机论坛

点评

大侠!我是初学者知道的单片机好少!现在根本都不知道什么是RTOS!  详情 回复 发表于 2015-2-4 22:11
 
 
 

回复

135

帖子

1

TA的资源

一粒金砂(中级)

板凳
 
dcexpert 发表于 2015-2-4 21:33
如果用51单片机,建议你可以去试试RTX51Tiny,一个简单易用的RTOS。使用RTOS实现你现在的功能,你在和现在程序比较试试。

大侠!我是初学者
知道的单片机好少!现在根本都不知道什么是RTOS!


此帖出自51单片机论坛

点评

如果真要学单片机,这是需要去了解的,可以慢慢来。RTX51tiny是Keil C51自带的,看看帮助文件和例程,基本就会用了。  详情 回复 发表于 2015-2-4 22:47
 
 
 

回复

1万

帖子

24

TA的资源

版主

4
 
werjufour 发表于 2015-2-4 22:11
大侠!我是初学者知道的单片机好少!现在根本都不知道什么是RTOS!


如果真要学单片机,这是需要去了解的,可以慢慢来。RTX51tiny是Keil C51自带的,看看帮助文件和例程,基本就会用了。

此帖出自51单片机论坛
 
 
 

回复

1634

帖子

0

TA的资源

裸片初长成(高级)

5
 
建议:不要长篇大论贴程序。估计没错的话99.9%的人只看前几行。
应该用文字描述你的程序结构、出现的现象等就好。
此帖出自51单片机论坛
 
 
 

回复

135

帖子

1

TA的资源

一粒金砂(中级)

6
 
哦,谢谢




此帖出自51单片机论坛
 
 
 

回复

135

帖子

1

TA的资源

一粒金砂(中级)

7
 
那这个KELL C51自带的要在哪里才能够看得到呢?谢谢了




此帖出自51单片机论坛

点评

安装Keil C51后,在IDE的帮助中,可以找到RTX51的帮助 [attachimg]188316[/attachimg] 在keil的C51下有RTX51tiny的源码和例程 [attachimg]188317[/attachimg]  详情 回复 发表于 2015-2-5 20:37
 
 
 

回复

135

帖子

1

TA的资源

一粒金砂(中级)

8
 
大侠!好像都是英文的啊!
看不懂哦
郁闷




此帖出自51单片机论坛

点评

如果下决心学,英文也不是问题的。  详情 回复 发表于 2015-2-5 20:43
 
 
 

回复

1634

帖子

0

TA的资源

裸片初长成(高级)

9
 

1.JPG (22.42 KB, 下载次数: 0)

1.JPG
此帖出自51单片机论坛
 
 
 

回复

1万

帖子

24

TA的资源

版主

10
 

安装Keil C51后,在IDE的帮助中,可以找到RTX51的帮助


在keil的C51下有RTX51tiny的源码和例程


此帖出自51单片机论坛
 
 
 

回复

1万

帖子

24

TA的资源

版主

11
 


如果下决心学,英文也不是问题的。

此帖出自51单片机论坛
 
 
 

回复

135

帖子

1

TA的资源

一粒金砂(中级)

12
 
好像例程里面只有函数名,而看不到集体的函数

那这么知道该函数是什么功能呢?




此帖出自51单片机论坛
 
 
 

回复

1万

帖子

24

TA的资源

版主

13
 
先看看帮助文件,里面有使用方法,在运行参考例程,很快就可以上手了。
此帖出自51单片机论坛

点评

先谢过了!冒昧问你一下你是如何知道自带了这样的函数呢?  详情 回复 发表于 2015-2-6 22:01
 
 
 

回复

135

帖子

1

TA的资源

一粒金砂(中级)

14
 
先谢过了!冒昧问你一下你是如何知道自带了这样的函数呢?

此帖出自51单片机论坛
 
 
 

回复

1万

帖子

24

TA的资源

版主

15
 
学过一次,就知道了呀。
此帖出自51单片机论坛

点评

大侠!我又遇到问题了!对于上面的程序!如果我早主函数一开始就把RELAY=0;/*关闭继电器*/而在死循环里取消RELAY=1;/*打开继电器*/这一句为什么在我上电的时候继电器会先吸合一下然后释放呢?在这里谢谢你了  详情 回复 发表于 2015-2-7 21:20
 
 
 

回复

135

帖子

1

TA的资源

一粒金砂(中级)

16
 
大侠!我又遇到问题了!
对于上面的程序!
如果我早主函数一开始就把
RELAY=0;/*关闭继电器*/
而在死循环里取消RELAY=1;/*打开继电器*/这一句
为什么在我上电的时候继电器会先吸合一下然后释放呢?
在这里谢谢你了







此帖出自51单片机论坛
 
 
 

回复

33

帖子

0

TA的资源

一粒金砂(中级)

17
 
中断里不能用延时函数   ,这是常识
此帖出自51单片机论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表