你看过汇编吗?与汇编的格式是一样的。具体就是先开中断允许标志位(IE里面对应的各个位)在设定TMOD工作方式。下一步就是设定初始值了(TH、TL)。设置完这些就可以开定时器了。写中断中段函数是是需要另加interrupt 加上一个常数(比如是定时器0就在后面加上1)。我用89S52芯片编过一个定时器程序你参考一下,希望对你有一点帮助。
//功能:感应外界温度并用数码管显示
//时间:2005年6月20日
//设计人:
#include<reg52h>
#define uchar unsigned char
sbit ad0809_oe=P1^0; //定义各个位
sbit ad0809_start=P1^1;
sbit ad0809_ale=P1^2;
sbit ls595_rclk=P1^3;
sbit ad0809_eoc=P1^5;
sbit ls595_oe=P1^4;
sbit ls595_ser=P3^0;
sbit ls595_srclr=P3^1;
uchar nn,mm;
uchar code tab[]={0x81,0xcf,0x92,0x86,0xcc,0xa4,0xa0,0x8f,0x80,0x84};
send(uchar); //声明函数
AD(uchar);
void display(uchar);
void init();
//普通口输入数据
send(uchar shu) //普通口串行输入
{
unsigned char i,k;
k=0x01;
for(i=0;i<8;i++)
{
if(k==(k&shu)) //判断每位上是否为1
ls595_ser=1;
else
ls595_ser=0;
k<<=1; //左移一位
ls595_srclr=0; //输入一个上升沿讲数送入595中
ls595_srclr=1;
}
}
//595显示子程序
void display(uchar du)
{
uchar ge,shi,flge; //ge拆字后个位的存放处shi拆字后十位的存放处flge ℃的存放处
shi=tab[du/10]; //拆字
send(shi); //给595送数
ge=tab[du%10];
send(ge);
flge=0xb1;
send(flge);
ls595_rclk=0; //上升沿送出数据
ls595_rclk=1;
}
//初始化程序
void init() //初始化AD、定时器
{
ad0809_start=0; //Start管教上升沿将AD内部寄存器清零
ad0809_start=1;
ad0809_ale=1; //ALE高电平选择通道
nn=0;
mm=0;
TMOD=0x01; //定时器初始化
//IE=0x82;
EA=1;
ET0=1;
TCON=0x00;
TL0=(65536-50000)%256; //定时50ms
TH0=(65536-50000)/256;
}
AD(uchar wen)
{
// unsigned char tt=0;
// ad0809_ale=1; //选择通道
ad0809_start=1;
ad0809_start=0; //start下降沿启动转换信号
while(ad0809_eoc==0); //判断转换是否结束
ad0809_oe=1; //转换结束送出转换数据
wen=P2;
return (wen);
}
//中断服务程序
void tiam0() interrupt 1 using 1 //中断服务程序
{
TL0=(65536-50000)%256; //定时50ms
TH0=(65536-50000)/256;
nn++;
if(nn==10) //05秒M加一
{
mm++;
nn=0;
}
}
//主程序
void main()
{
unsigned char bb,aa,cc; //bb=计算后得到温度,aa=AD输出数据
unsigned char wen; //wen存放转换的得到的数据
init();
// wen=17;
ls595_oe=0;
cc=0;
TR0=1;
while(1)
{
aa=AD(wen);
// ad0809_oe=0;
aa=~aa;
bb=aa/4;
if(mm==2)
{
mm=0;
cc=bb;
}
display(cc); //调用显示子程序
}
}
我觉得是这样的,单片机的定时器,它的计数过程是相当于电脑里面一个后台运行的东东一样。在计数时单片机同时在执行其他程序,计数周期就是单片机的一个机器周期。
当我们给定时器初始化后,一但打开(这指内部定时器方式,还有外部脉冲计数方式,都差不多),下个机器周期到来便累加一次。计满时,即定时器十六位为0xffff,再计一次后,相应中断标志置1(TF0、TF1),若之前开启了相应的定时器中断(ET0、ET1)且有相应中断服务函数,单片机会暂停当前正在执行的程序,进入相应中断服务函数里面执行,若定时器还在开启状态,则仍会计数。中断执行完后回到暂停处的主程序里。在一个机器周期一般会做六件事情,其中有项是检查访问内部寄存器,包括中断标志。
#define uint unsigned int
#define uchar unsigned char
#include <reg52h>
uint i;
uchar code TAB[]=[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void main(void)
{
TMOD=0x22; /定时器0设置为工作方式2,基准定时(256-6)/1M=025ms/
TH0 =6; //赋T0的预置值6,溢出4000次就是1秒钟
TL0 =6;
ET0=1; //打开定时器0中断
EA=1; //打开总中断
TR0=1; //启动定时器
while(1) //程序循环
{
P3=TAB[(i)];//p3送数
}
}
//定时器0中断
void timer0(void) interrupt 1 using 1
{
static uint t; //注意t的范围,这里涉及到C51变量取值范围这个知识点
t++;
if(t==4000) //T0的预置值6,溢出4000次就是1秒钟,晶振12MHz
{
t=0;
i++;
i=i%10;
}
}
一、利用定时器实现:
/预处理命令/
#include<reg52h>
#define OUT P0
//晶振:12MHZ
/重新定义数据类型/
typedef unsigned char unit8;
typedef unsigned short unit_16;
/
函数名:main()
函数功能: 主函数
输入:无
输出:无
/
void main()
{
TMOD = 0x01;
TR0 = 1;
ET0 = 1;
EA = 1;
while(1);
}
/
函数名:Timer0_Rountine() interrupt 1
函数功能:内部中断T0 服务函数
输入: 无
输出:无
/
void Timer0_Rountine() interrupt 1
{
static unit_16 Count=0;
static unit8 Count_Sign=0;
static bit Sign=0;
TH0 = 0xfc;
TL0 = 0x18;
Count++;
if(!Sign)
OUT = 0xaa; //奇数 (1秒)
if(Count>=1000)
{
Sign=1;
Count=0;
if(Count_Sign<3) //2秒
OUT = 0xaa; //奇数
else if(Count_Sign>=3&&Count_Sign<=10) //8秒
OUT = 0x55; //偶数
else if(Count_Sign>10&&Count_Sign<=22) //12秒
OUT = 0x00; //全部
else if(Count_Sign>22)Count_Sign=Sign=0;
Count_Sign++;
}
}
二、利用软件延时实现:
#include<reg52h>
#define OUT P0
typedef unsigned char unit8;
typedef unsigned int unit16;
/
函数名:delay_ms(unit16 x)
函数功能: 延时函数1MS
输入:x
输出:无
/
void delay_ms(unit16 x)
{
unit8 a,b;
while(x--)
{
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
}
/
函数名:main()
函数功能: 主函数
输入:无
输出:无
/
void main()
{
while(1)
{
OUT = 0xaa; //奇数
delay_ms(3000); //3秒
OUT = 0x55; //偶数
delay_ms(8000); //8秒
OUT = 0x00; //全部
delay_ms(12000);//12秒
}
}
以上就是关于请问单片机C语言定时器程序怎么写全部的内容,包括:请问单片机C语言定时器程序怎么写、定时器在单片机中程序的运行过程、怎样用单片机定时器设计0到9秒的循环程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)