单片机进中断后执行中断里的程序,比如你进定时中断,执行完后退出中断后做其他事,但定时还在计数,这样计数和做其他事情两不误。
你的程序中本来就没做其他事情,你的LED移动就是等待中断计数到10才操作的,LED动作的先决条件就是中断计数结束更多
亲,首先谢谢您无私的奉献,小弟还有一点不理解,就上面的这个程序,在第一次进入中断定时器数数的时候,主程序在干什么? 好像什么也没有做,在等呢?是不是这样?
下面的程序就不一样了,没进中断时执行主循环,有中断就进中断,中断执行完再回到中断前主程序执行的位置
进中断后,主程序就等啊,等中断退出才回到主程序
谢谢您 ,如果是进中断后,主程序在等,那和软件延时,感觉差不多啊!!软件延时好比是在等的时间内在数数 是这样吗? 小弟刚开始学单片机,所以脑袋有些不开翘,嘿嘿
在你这个程序是差不多的,但是软件延时,就一直在那计数,要不然中断计数,中断计数器满了才进中断累加的,比如说,要定时1分钟,用延时的话,这一分钟都在delay,不能做其他事情,中断的话中断累加10次到达1分中的话,不到0.1分钟内的时间不进中断,那这0.1分钟可以做其他事情,等到0.1后进中断,累加一次,就退出中断,再过0.1才进中断,这之间大部分时间可以做其他了
真的谢谢您无私的奉献,感谢
求一个单片机定时程序。。。。。。
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar timer[3]={0,0,0};//时分秒 按实际的情况修改这个数组里的数字 分别为{时,分,秒} 另外我很费解电动机是啥 所以我就写一个定时功能
uint timer_data;
void main_init()//程序初始化
{
timer_data=0;//数据初始化
TMOD=1;//使用到 定时器0
TH0=0xfc;TL0=0x18;//定时 1毫秒
TR0=ET0=EA=1;//定时器开启
}
void main()
{
main_init();
while(1)
{
//然后在这里判断if () 你所需要的时间数据 就可以做一些动作了;
}
}
void timer0()interrupt 1//定时器0入口
{
TH0=0xfc;TL0=0x18;//本次定时 1毫秒
if(timer_data==1000)//1000毫秒=1秒
{
timer[2]++;
if (timer[2]==60)//判断是否过了60秒;
{
timer[1]++;//分钟加1;
timer[2]=0;//秒清0
if (timer[1]==60)//判断是否过了60分;
{
timer[0]++;//小时加1;
timer[1]=0;//分清0
if (timer[0]==24)//判断是否过了24小时
{
timer[0]=0;//时清0
}
}
}
timer_data=0;
}
else
{
timer_data++;
}
}
51单片机程序定时器怎么这么不准确啊,求高手指点!
这是编译器造成的,你最好用Debug模式看看生成的汇编代码是什么摸样,比较一下你那三种方 式给TH0和TL0赋的是什么样的值。
这是我试验的结果:
4: TH0=-780/256;
C:0x0003 758CFD MOV TH0(0x8C),#0xFD
5: TL0=-780%256;
C:0x0006 758AF4 MOV TL0(0x8A),#0xF4
6: TH0=-516/256;
C:0x0009 758CFE MOV TH0(0x8C),#0xFE
7: TL0=-516%256;
C:0x000C 758AFC MOV TL0(0x8A),#0xFC
8: TH0=(65536-516)/256;
C:0x000F 758CFD MOV TH0(0x8C),#0xFD
9: TL0=(65536-516)%256;
C:0x0012 758AFC MOV TL0(0x8A),#0xFC
看出差别了吧?使用-780时给T0赋值0xFDF4,使用第三种方式赋值为0xFDFC,这两个数字相近,所以结果基本正确。但是使用-516时赋值的0xFEFC,这差别就大了,结果就是不正确。
一般建议用TH0=(65536-516)/256 ;TL0=(65536-516)%256;这种方式,保证不出问题。
51单片机定时器精确定时方法
精确定时一般用汇编来写,如果你选用晶体 F=12MHZ,则定时器每加一就是 1uS,这样就可以设定定时器的初始值了,
如果你需要50mS的定时,定时器初始值为:65536-50000=15536 即 3CH,B0H TH0=3CH TL0=B0H (设定时器0用来定时,工作在16位 MOV TMOD,#11H)如果你需要更长时间定时则需要软件计时了,比如一秒,需要 (50ms *20=1000ms) 20次了,这需要在定时器0的中断程序中计算了!
关于51单片机用定时器1秒延时,这有个程序不知对了?求解。
你这个程序肯定不行,别说1秒,0.1秒都达不到,我帮你改一下:
void delay1()
{
uchar t = 19;
TMOD=0x10;
for(t=19;t>0;t--)
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
TR1=1;
while(!TF1);//等待定时器1溢出标志置位
TF1 = 0;//清0标志位
}
}
你没有说明晶体振荡器频率,所以定时器初值和循环次数t按原程序
谢谢你,大侠,我写的错在哪了啊?晶体是12MHz的。
你没有等待定时器溢出,怎能达到延时效果。
51单片机定时器精确定时方法
他可以通过定时器T0 T1啊,这两个就是精确定时的,误差在零点几微秒,
一般51单片机的 1个机器周期=12个振荡周期,即记术频率为晶振频率的1/12.
定时时间=(2的X次方-初值)*机器周期。x又定时器工作方式决定。分别为13. 16 。 8.
机器周期=12/系统的晶振。
比如 系统晶振频率为12MHZ,则机器周期为1微妙秒。
利用定时器T0的工作方式1实现1秒钟延时程序(单片机)
#include <reg51.h>
#define uchar unsigned char
sbit LED=P1^0;
uchar time;
void initT0( )
{
TMOD = 0x01; //定时器0,工作方式1
TH0 = (65536-50000)/256;
TL0 = (65536-50000)%256; //50ms中断一次
EA = 1;
ET0 = 1;
TR0 = 1;
}
void main(void)
{
initT0();
while(1)
if(time==20) //中断20次,1s
{
time=0;
LED=!LED; //P1.0上的LED,1s亮或灭一次
}
}
void T0int( ) interrupt 1
{
TH0 = (65536-65536)/256;
TL0 = (65536-65536)%256;
time++;
}
C51单片机定时器1以方式1定时1秒如何设置?
在中断里面写上累加100次的变量,就等于是1s了):
#include <reg51.h>
void InitTimer1(void)
{
TMOD = 0x10;
TH1 = 0x0DC;
TL1 = 0x00;
EA = 1;
ET1 = 1;
TR1 = 1;
}
void main(void)
{
InitTimer1();
}
void Timer1Interrupt(void) interrupt 3
{
TH1 = 0x0DC;
TL1 = 0x00;
//add your code here!
}
51单片机是对所有兼容Intel 8031指令系统的单片机的统称。该系列单片机的始祖是Intel的8004单片机,后来随着Flash rom技术的发展,8004单片机取得了长足的进展,成为应用最广泛的8位单片机之一,其代表型号是ATMEL公司的AT89系列,它广泛应用于工业测控系统之中。很多公司都有51系列的兼容机型推出,今后很长的一段时间内将占有大量市场。51单片机是基础入门的一个单片机,还是应用最广泛的一种。需要注意的是51系列的单片机一般不具备自编程能力。
定时器人类最早使用的定时工具是沙漏或水漏,但在钟表诞生发展成熟之后,人们开始尝试使用这种全新的计时工具来改进定时器,达到准确控制时间的目的。定时器确实是一项了不起的发明,使相当多需要人控制时间的工作变得简单了许多。人们甚至将定时器用在了军事方面,制成了定时炸弹,定时雷管。现在的不少家用电器都安装了定时器来控制开关或工作时间。
转载请注明出处51数据库 » 软件定时器单片机 51单片机软件延时和定时器的区别
凹凸欧巴