⑴ 单片机怎么用定时器替代延时函数
1、首先分析您的程序,
void
delay()
{
int
i;
if(1
==
tf0)//if(tf0==1),查询定时器溢出标志位
{
tf0=0;
i=10000;//定时溢出时给i赋值1000
th0=0xdc;tl0=0x00;
i--;//i=999,如果还没有减到0时定时器又溢出,则i永远不会减到0!!!!所以您的这段程序不应该行不通!!
}
while(1)
{
if(i==0)
break
;
}
}
2、建议做法
(1)定义一个全局变量用于作定时计数如unsigned
char
n;
(2)定时器采用以某一时间基准(10ms)中断方式,每中断一次中断处理程序里n++;
(3)在延时函数中对n进行操作,如延时1s即1000ms则:
void
delay_1s()
{
while(n<100);//如果n<100,即还没有到1s就等待
n=0;如果1s时间到则清零n,退出子程序
}
当然这样定时精度可能需要调整,但思路可以试试。
⑵ 单片机程序什么作用啊 尤其是X++作用 定时器中断作用是什么呢
x应该是一个全局变量,每次中断函数都会将x加1,程序的其余函数会扫描x的值来做出相应的动作,
interrupt 1 是计时器中断洞局,这里应该是用一个全局变量计时,main函数或者其他中断函数检查x的数值做到定时的响应,如闪灯或者屏幕刷新又或者PWM输出 ,
定时器中断的作用是在CPU运行期间 ,定时器在不干扰CPU正常运行的情况下不停地将自身寄存器(从你的函数初始化看是TH0和TL0并起来的一个16位值)减一,当寄存器值为0时候发起中断(从1减去1开始到寄存器值为0之间发起的),这样可以做到CPU不用一直等待一个时间的到来而空转,或者运行一个程序的过程中计算运行的时间并定时插入一个额外的工作,
C51的计时器有4个工作模式(对于At89S51或者STC89C52及以上型号来说)不同的模式有不同的功能,这个网络文库能看到的,另外TMOD寄存器和其他寄存器还设定了计时器是外部的跳带腊变信号或者单片机内部时钟来引起计时器的一次减1动作(计时动作)。
另外计时器可以设置为外部输入模式,这样就能作为计数器,比如说一个外接的按键,按10次后才触发中断,如果用外中断处理蠢颤滑,那么整个主函数会被中断九次做无效中断才能等到第十次按键执行需要的中断处理动作。
这一点在操作系统中也用到了,比如我们的PC的多任务操作系统,就是用时钟中断来把一个程序中断执行另一个程序(比如操作系统和应用程序间)实现了时间片轮转,不过PC的操作系统把所有的中断处理函数都包含进去了,所以我们基本不用去管硬件中断就能编程。 反观单片机,因为资源有限,想要做到多任务(主函数与各个中断函数及其子函数)必须用定时器(也可以通过外部信号做计数器)以及外中断作为契机来切换多个任务。
如果需要解答整个中断函数的功能,最好把全部的程序都帖出来,因为x这个全局变量的作用没有在中断函数中体现
有问题可以继续跟我交流,我现在是大学本科生,学过C51单片机,正在学STM32
⑶ 用C语言给单片机编程时,主函数中的变量为什么都得定义成全局变量
变量是定义成全局变量还是局部变量得看变量的在程序中所起的作用,比如如下程序:
#include <REGX52.h>
unsigned int int_count=0;
unsigned char count=0;
unsigned char second=0;
unsigned char seg[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x40};
unsigned char seg1[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x98};
Delay_1s() //500m秒延时子程序
{unsigned char l,i,n;
for(l=50;l>0;l--)
for(i=20;i>0;i--)
for(n=248;n>0;n--);
}
void t0(void) interrupt 1 using 0
{int_count++;
if(int_count==4000)
{ int_count=0;
second=1;
}
}
void main (void)
{TMOD=0x02;
TH0=0x06;
TL0=0x06;
TR0=1;
ET0=1;
EA=1;
while(1)
{
if(second)
{
second=0;
P0=seg1[count];
count++;
if(count>=10)
count=0;
}
}
}
定时器输出0到9,每一秒变化一次,其中int_count、second是全局变量这是因为,int_count是中断次数统计,他需要在完成一次次的中断以雹锋后数值保持不变,如果定义成局部变量,没发生一次中断,它加一,中断结束又变成0了,所以定义成全局变量,这样他的数值会根据中断发生的次数不断增加。而second则因为是数码管显示的数组镇举的下标,如果定义成局部变量那么每次函数调用结束,内存释放变量值也就没有了,这样就达不到每秒输出不同数字的要求。、
总的来讲呢,如果变量的值在函数调用结束以后还会被其他的函数,活着表达式使用,源旅晌才定义成全局变量。
⑷ 51单片机定时器定时 2秒灯亮 3秒灯灭,如此循环
如果想实现无限循环那就采用死循环方式,可以无限的循环如while(1){};然后设定定时器定时时间为1s(此值需要根据单片机确定是否可以设定这么大),其次,设定一个变量对时间进行计数,根据计数情况做出相应的改变,程序可以这样设定:
unsigned
char
gucledstatus
=
0x00;
//全局变量,表示灯当前的状态
0为灭,1为亮
volatile
unsigned
int
gustimecnt;
//全局变量对时间计数
int
main()
{
//增加定时器初始化并开放中断
while(1)
{
if(gucledstatus
==
0x01)
//当前为亮状态
{
if(gustimecnt
>=
7200)
//两个小时时间到
{
gustimecnt
=
0x00;
//清零
gucledstatus
=
0x00;
//灯为灭状态
//此处加程序代码,控制灯为灭的状态
}
else
{
//此处加程序代码,控制灯为亮的状态,此处会重复执行,可以进行控制
}
}
else
if(gucledstatus
==
0x00)
//灯为灭的状态
{
if(gustimecnt
>=
3600)
//1个小时
{
gustimecnt
=
0x00;
gucledstatus
=
0x01;
//亮状态
//增加程序代码,控制灯亮
}
else
{
//增加程序代码,控制灯灭,此处会重复执行,可以进行控制
}
}
}
return
0;
}
在中断函数中,对gustimecnt进行递增即可!
⑸ c8051单片机定时器中断求助
那为什么要 每隔 5ms 判断一次呢?直伏槐接在主函数判断不行吗?
void main()
{
while(Flag)
{
//……继续的内容
}
while(1);//这缺羡友就是不继派嫌续的结果,死在这里,不执行任何东西。当然,定时器还是会工作。
}
这还涉及到另一个问题,如果 这个 变量,一会 0,一会 1,一会又 0,一会 又 1,你想咋整啊?
⑹ 单片机两分钟定时器,从2:00:00~0:00:00
通过这个函埋瞎数可以定时A*time ms
定时器精确定时Ams的程序
uchar T0RH,T0RL; //全局变量
uint time;
void configtime(uchar ms)
{
unsigned long tmp;
tmp=11059200/12;//晶振除12,就是机器周期每秒的次数
tmp=(tmp*ms)/1000;//除以1000,就是每毫秒的次塌液散数,乘ms,即每ms毫秒的次数
tmp=65536-tmp; //转换为计数初值;
tmp=tmp+18; //补偿中断响应延团氏时造成的误差
T0RH=(uchar)(tmp>>8);
T0RL=(uchar)tmp;
TMOD=0x01;
TH0=T0RH;
TL0=T0RL;
ET0=1;
TR0=1;
}
void Timer0() interrupt 1
{
TH0=T0RH;
TL0=T0RL;
time++;
}
⑺ 单片机定时器中断改变全局变量
int h1,m1,s1; //时分秒全局变量
int tt; //定时器0进入中断的次数
void main()
{
init(); //初始化
while(1)
{
display(h1,m1,s1);
}
}
void dingshi0() interrupt 1 //定时器0中断
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
tt++;
if(tt==20)
{
tt=0;
s1++; //秒数+1
if(s1==60){ s1=0; m1++;}//计满60秒分位进1,秒位清0
if(m1==60){ m1=0; h1++; }//计满60分时位进1
if(h1==24){ h1=0; }//计满24小时时位清0
}
}
在中断内,你可以直接写成这样
只用全局变量更方便
再有,你苦恼的问题是因为函数每次调用的时候
都是以0为数据传递的,错误在串口初始化部分以及你调用函数的时候
你的变量S,没有全局变量声明,切也没有局部变量声明
所以每次调用函数的时候,S都是以0开始,最多加到1,之后又从0开始递增
⑻ 单片机中什么叫做全局变量,请帮忙谢谢
单改培片机中全局变量就是在所有子程序中都通用的变量,一般在主程序的前面部位声明,当然也可以在其他侍歼斗位置声明,只要老磨在子程序外部就可以。
⑼ 51单片机50ms定时
12MHz 的晶振,那么一个周穗磨期就是 1 us,所以需要计数 50ms / 1us = 50000,可以选唯圆择定时器工作方式 1。
由上述计算:
TH1 = (65536 - 50000) / 256;
TL1 = (65536 - 50000) % 256;
方式一,所以:
TMOD = 0x10;
运行 TR1 = 1,所以:
TCON = 0x40;
允许中断 ET1 = 1,EA = 1,所以:
IE = 0x88;
综合可以编写如下程序(汇编我不会指族塌,不知道你要的是汇编还是C):
#include <reg52.h>
void timer1_int() interrupt 3
{
TH1 = (65536 - 50000) / 256;
TL1 = (65536 - 50000) % 256;
}
void timer1_init()
{
TH1 = (65536 - 50000) / 256;
TL1 = (65536 - 50000) % 256;
TMOD = 0x10;
IE = 0x88;
TCON = 0x40;
}
void main()
{
timer1_init();
while(1);
}
⑽ 请教如何用51单片机的一个定时器计算三路开关量输入的频率
方案1:51的定时器定时时间不长,为了解决这一问题,可以设置一全局变量(假设你用c编程序)作计数器,等到定时中断发生时中断函数给这一全局变量加一,在主程序中判断这一变量的大小,从而推算出定时时间。譬如说,定时器设置成0.5秒中断一次,中断时给变量t加一,那么当t等于16时,就是8秒了。这种方案的缺点是必须在中断函数中加入给变量加一的额外语句,使得定时出现误差,但是也能通过减少定时器的定时时间来补偿,不过计算较麻烦,而且不便于精确定时。
方案2:使用低频的晶振或低频外部震荡。有些型号的单片机支持0至12mhz的震荡频率,只要频率足够低绝对能够在定时器最大定时时间内产生出想要的脉冲。这种方案是以牺牲单片机的运行速度为前提的,不过要是做一些简单控制的话,倒是一种不错的选择。