找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7977|回复: 10
收起左侧

51单片机LED延时闪烁delay(50000); 用定时器延时代替delay(50000)延时怎么样写?

[复制链接]
回帖奖励 1 黑币 回复本帖可获得 1 黑币奖励! 每人限 1 次
ID:475031 发表于 2020-3-11 15:34 | 显示全部楼层 |阅读模式
51单片机LED延时闪烁delay(50000); 用定时器延时代替delay(50000)延时怎么样写?

LED闪烁实验 *
实现现象:下载程序后D11指示灯闪烁
注意事项:无
***************************************************************************************/

#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;

sbit led=P0^0; //将单片机的P0.0端口定义为led
sbit led1=p0^1;
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);
}

/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
while(1)
{
led=0;
delay(50000); //大约延时450ms
led=1;
delay(50000); //大约延时450ms
led1=0;
delay(50000); //大约延时450ms
led1=1;
delay(50000);
}
}
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
以上程序中 delay(50000); 用定时器延时代替delay(50000)延时怎么样写?
回复

使用道具 举报

ID:475031 发表于 2020-3-11 15:48 | 显示全部楼层




下面是在网上找了点资料。,三次定时中断调用。
我试了,没有反应。不知道那错了了








U8 a =0;//计中断次数的全局变量

void main()
{
TMOD=0X01;
TH0=(65536-50000)/256;//定时50ms
TL0=(65536-50000)%256;
ET0=1; EA=1;
while(1)
{
led=0;
TR0=1;
while(a!=9); //9 次中断450ms
TR0=0; a=0

led=1;

TR0=1;
while(a!=9); //9 次中断450ms
TR0=0; a=0

led1=0;

TR0=1;
while(a!=9); //9 次中断450ms
TR0=0; a=0

led1=1;

TR0=1;
while(a!=9); //9 次中断450ms
TR0=0; a=0
}
}

中断程序:
void timer0(void) interrupt 1
{
TH0=(65536-50000)/256;//定时50ms
TL0=(65536-50000)%256;
a++;
}
回复

使用道具 举报

ID:475031 发表于 2020-3-11 16:55 | 显示全部楼层
本帖最后由 鬼推磨 于 2020-3-11 17:57 编辑



成功了,


经过反复测试修改,。终于找到问题。纠正了,。下面是正确的代码了,
以后写程序就可以使用定时器来做延时,精准可靠,放弃使用delay延时不准,
特别是新手可以借鉴下面的代码。为这个问题网上找资料搞了好几天了,




#include "reg52.h"
#define uchar unsigned char  
typedef unsigned int u16;          //对数据类型进行声明定义
typedef unsigned char u8;
u16 a =0;//计中断次数的全局变量
sbit led=P2^6;
sbit led1=P2^7;
//晶振频率是11.0592M,可算出,计数脉冲个数是921个=1ms
//TH0=(65536-921)/256=252=0xFC
//TL0=(65536-921)%256=103=0x67
////////T0定时器///////////////////
void Timer0Init()//晶振频率是11.0592M
{
//0X00:0 0 方式0 13位计数器
//0X01:0 1 方式1 16位计数器
//0X10:1 0 方式2 自动重装8位计数器
//0X11:1 1 方式3 T0分为2个8位独立计数器,T1为无中断重装8位计数器

        TMOD|=0X01;// 工作方式1,16位计数器。此处0X01;下面定时1000就是1秒,若设置为0X10下面1000就是0.1秒
        TH0=0XFC;        //给定时器赋初值,定时1ms
        TL0=0x67;        
        ET0=1;//打开定时器0中断允许
        EA=1;//打开总中断
        TR0=1;//打开定时器                        
}

void main()
{
Timer0Init();  //定时器0初始化
while(1)
{
led=0;//亮
TR0=1;//打开定时器0
while(a!=1000); //1000 次中断是1000ms=1s
TR0=0; //关闭定时器0
        a=0; //中断计数清零
led=1;//灭
TR0=1;//打开定时器0
while(a!=1000); //1000 次中断是1000ms=1s
TR0=0; //关闭定时器0
        a=0;//中断计数清零

led1=0;//亮
TR0=1;//打开定时器
while(a!=1000); //1000 次中断是1000ms=1s
TR0=0; //关闭定时器0
        a=0;//中断计数清零
led1=1;//灭
TR0=1;//打开定时器0
while(a!=1000); //1000 次中断是1000ms=1s
TR0=0;  //关闭定时器0
        a=0;//中断计数清零
}
}
//中断程序:

void Timer0() interrupt 1//晶振频率是11.0592M
{

        TH0=0XFC;        //给定时器赋初值,定时1ms
        TL0=0x67;
   a++;

}






、、、
//////////////////////////////////////////////////////
新问题来了:吧上面void main()里面代码换成下面的,
下面代码只是加了个按键IF判断。
里面定时中断延时就不执行了,没有反应了,
这句代码出问题了while(k!=650); //650ms
不知何故,望大师们帮忙解答。,谢谢


void main()
{

Timer0Init();  //定时器0初始化
a=0;//清零
   while(1)
{  
       
         if(k3==0)
         {
             delay(10);
                 if(k3==0)
                 {
k1=0;
TR0=1;
while(k!=650); //650ms
TR0=0;
k=0;               


k1=1;
TR0=1;
while(k!=350); // 350ms
TR0=0;
k=0;               
k1=0;       
         }
                                                 
                                 }
       


}  



         }




回复

使用道具 举报

ID:475031 发表于 2020-3-11 17:53 | 显示全部楼层



新问题又来了:吧上面void main()换成下面的。
加了个按键if判断。里面定时中断就没有反应。
不执行while(k!=650); //650ms,不知道是什么问题。
大师们帮忙解答下:


void main()
{

Timer0Init();  //定时器0初始化
a=0;//清零
   while(1)
{  
       
         if(k3==0)
         {
             delay(10);
                 if(k3==0)
                 {
k1=0;
TR0=1;
while(k!=650); //650ms
TR0=0;
k=0;               


k1=1;
TR0=1;
while(k!=350); // 350ms
TR0=0;
k=0;               
k1=0;       
         }
                                                 
                                 }
       


}  



         }

回复

使用道具 举报

ID:316880 发表于 2020-3-11 17:56 | 显示全部楼层
定时器这样用真的很费劲,为什么不用if判断
回复

使用道具 举报

ID:342451 发表于 2020-3-11 18:33 | 显示全部楼层
用这个程序,仔细理解定时器怎么用
#include "reg51.h"
typedef unsigned int u16;
typedef unsigned char u8;
sbit led=P2^0;
u16 t;
void Timer1Init()
{
        TMOD|=0X10;//选择为定时器1模式,工作方式1,仅用TR1打开启动。
        TH1=0XFF;        //给定时器赋初值,定时0.1ms
        TL1=0X9C;       
        ET1=1;//打开定时器1中断允许
        EA=1;//打开总中断
        TR1=1;//打开定时器                       
}
void main()
{       
        Timer1Init();//定时器1初始化
        while(1)
        {
                if(t == 5000)//5000*0.1=500ms
                {
                        t==0;
                        led=~led;
                }
        }               
}
void Timer1() interrupt 3
{
        TH1=0XFF;        //给定时器赋初值,定时0.1ms
        TL1=0X9C;
        t++;
}
回复

使用道具 举报

ID:685726 发表于 2020-3-11 18:41 | 显示全部楼层
可以先不加中断,只用定时器,从简单到复杂。先设置定时器TMOD的模式为1,即TMOD=0x01;
回复

使用道具 举报

ID:234075 发表于 2020-3-11 19:01 | 显示全部楼层
你这是要LED1,450ms状态反转一次吗?
unsigned char a =0;//计中断次数的全局变量
void main()
{
        EA=1;
        ET0=1;
        TMOD=0X01;
        TH0=(65536-50000)/256;//定时50ms
        TL0=(65536-50000)%256;
        TR0=1;
        while(1);
}

void timer0(void) interrupt 1
{
        TH0=(65536-50000)/256;//定时50ms
        TL0=(65536-50000)%256;
        a++;
        if(a>=9)
        {
                a=0;
                LED1=~LED1;
        }
}
回复

使用道具 举报

ID:316880 发表于 2020-3-11 19:08 | 显示全部楼层
之一知足 发表于 2020-3-11 18:33
用这个程序,仔细理解定时器怎么用
#include "reg51.h"
typedef unsigned int u16;

这才是定时器真正的使用方法。
回复

使用道具 举报

ID:475031 发表于 2020-3-11 20:18 | 显示全部楼层
之一知足 发表于 2020-3-11 18:33
用这个程序,仔细理解定时器怎么用
#include "reg51.h"
typedef unsigned int u16;

led=0;
delay(50000); //大约延时450ms
led=1;
delay(50000); //大约延时450ms
led1=0;
delay(50000); //大约延时450ms
led1=1;
delay(50000);


这个delay(50000); 怎么用你代码替换调用呢。

N多个子程序需要用到这个延时。

子程序需要用到延时用一句话代码调用。我还实验过,
你这个代码没有办法在子程序运行不工作

还有个问题。你这个代码只能在main()里运行。并且在加一个延时。没有没有反应




while(1)
        {
                if(t == 5000)//5000*0.1=500ms
                {
                        t==0;
                        led=~led;
                }


                if(t == 3000)//3000*0.1=300ms 比如另外一个发光管LED1,你这个就没法运行了,编译通过,下载开发板没有反应
                {
                        t==0;
                        led1=~led1;
                }


        }               
}
回复

使用道具 举报

ID:475031 发表于 2020-3-11 22:17 | 显示全部楼层



#include<reg51.h>
sbit LED=P2^7;
void delay(unsigned int times)
{
unsigned int i ;
TR0=1;
for(i=0;i<times;i++)
{
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
while(TF0==0);
TF0=0;//中断标志位
}
TR0=0;
}
void main()
{
TMOD=0x01;
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
while(1)
{
delay(50); //延时50毫秒
LED=~LED;
}
}




又找到一个版本,。吧定时器中断搞延时里,
这样又变成老方法的delay(50); //延时50毫秒调用了,




我测试了,好像不能长时间调用,短时间2000以内是可以的,
下面10秒就不行。运行起来,没有10秒就灭了,好像只亮2秒就过了。不知道是什么问题
LED=0;
delay(10000); //延时10秒
LED=1;



回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表