【单片机应试】定时器/计数器、占空比、脉冲周期总结

苦于百度没有找到这种题型的解法,所以将自己备战考试的一点总结写出来。
整篇都是关于定时器和计数器的,原理在此不做赘述,只总结看到这类题该怎么算。
题型1:
1.假定单片机内部定时器T0工作在方式1下,要求从P2.0产生频率为20HZ的方波脉冲信号,已知单片机的晶振频率为12MHZ。
解法:这种题目上来先算由晶振频率得到的机器周期:
三个重要的公式:
公式1
公式2
公式3所以

步骤1:

机器周期=(1/12MHZ)*12=1us;

步骤2:

现在看下题目:产生频率为20HZ的方波脉冲。这又是什么鬼?查了很多资料,现在方便大家O(∩_∩)O~
解答:一个脉冲周期=20HZ对应的周期=1s/20HZ=0.05s=50ms
也就是需要定时25ms(个人理解是50ms/2),即25000us;
上面得知机器周期=1us,而一个指令周期=1、2、4个机器周期,在这里指令周期为1个机器周期,所以计数值=25000/1=25000

步骤3:
- (插曲)看一下初值的计算:
C/T=0时为定时功能: 加1计数器对脉冲f进行计数,每来一个脉冲,计数器加1,直到计时器TFx满溢出;
C/T=1时为计数功能: 加1计数器对来自输入引脚T0(P3.4)和T1(P3.5)的外信号脉冲进行计数,每来一个脉冲,计数器加1,直到计时器TFx满溢出;
GATE=1时,“与门”的输出信号K由INTx输入电平和TRx位的状态一起决定(即此时K=TRx·INTx),当且仅当TRx=1,INTx=1(高电平)时,计数启动;否则,计数停止。
当INT0引脚为高电平时且TR0置位,TR0=1;启动定时器T0;
当INT1引脚为高电平时且TR1置位,TR1=1;启动定时器T1。
GATE=0时,“或门”输出恒为1,“与门”的输出信号K由TRx决定(即此时K=TRx),定时器不受INTx输入电平的影响,由TRx直接控制定时器的启动和停止。
当TR0=1,启动定时器T0。
当TR1=1,启动定时器T1。
定时器1,则后四位为0;模式2(M1M2=10,计数器C/T=1,gate默认为0.除非送1)即:0110=6
YANSHEN
下面介绍一下确定定时器/计数器初值的具体方法。
因为在不同工作方式下计数器位数不同,因而最大计数值也不同。
现假设最大计数值为M,那么各方式下的
最大值M值如下:
方式0:M=2 ^13=8 192
方式1:M=2^16=65 536
方式2:M=2^8=256
方式3:定时器0分成两个8位计数器,所以两个M均为256。
因为定时器/计数器是作“加1”计数,并在计数满溢出时产生中断,因此初值X可以这样计算:
*在计数方式下:X=M-计数值
在定时方式下:X=(M-定时值)机器周期

例子:
TMOD=0x01; //0000 0001
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
程序是采用定时器0工作方式1,TH0=(65536-45872)/256;TL0=(65536-45872)%256;这是定时的时间,定时时间一到就进入中断程序执行。
回到题目
再看题目:
定时器T0,工作方式1,(M=2^16=65 536)
TMOD
GATE一般默认为0,除非题目额外告诉你别的信息。所以这里:
TMOD=0000 0001=0x01H;
定时方式下初值的计算:
TH0=(65536-25000)/256;//H
TL0=(65536-25000)%256;//L

简单总结一下:
方波信号,就是在一个周期内产生一次跳变。频率是20HZ说明1s时间有20个周期,则每个周期50ms,一个方波信号经过25ms跳变,又晶振周期是按照1us计算,固按照方式1的话,是65536-25000。
下面编程就简单了:
#include “regh1.h”
sbit PWM = P2^0;
unsigned char T_Cnt;
void T0_Init(void)
{
TMOD = 0x01;
TH0 = (65536-25000)/256;
TL0 = (65536-25000)%256;
ET0 = 1;
EA = 1;
}
void T0_Int(void) interrupt 1
{
TH0 = (65536-25000)/256;
TL0 = (65536-25000)%256;
PWM = ~PWM; //转变PWM口的状态
}
void main(void)
{
T0_Init();
PWM = 1; //设置初值
TR0 = 1;
while(1);
}
题型2:
2.设fosc = 6MHz,利用单片机内定时/计数器及P10口线输出1000个脉冲,脉冲周期为2ms,试编程
解答:
这个题目没有频率方波了。老套路,先算机器周期,能那一分是一分。
机器周期=(1/6)*12=2us
这道题目直接告诉你输出1000个脉冲了,所以计数初值直接是1000;
再看脉冲周期:2ms,砍一半(除2),1ms=1000us
而脉宽为脉冲周期的一般,1000us/2=500us
定时初值,根据你设定的方式按照上面说的计算方法计算。
在本题中,我们设置TMOD=50H,即用T0定时,T1计数。
看代码:
ORG 0000H
LJMP MAIN
ORG 000BH;定时器T0中断开始地址
LJMP TOS
ORG 1000H

MAIN:MOV TMOD,#50H;0101 0000 T1模式1计数,T0模式0定时
MOV TL0,#0CH;设置定时初值(2的13次方-500us)高八位赋给TH0,低8位给TL0;
MOV TH0,#0F0H
MOV TL1,#18H;设置计数初值(2的16次方-1000)
MOV TH1,#0FCH
SETB TR1;SETB是让后面的数置1
SETB TR0
SETB ET0
SETB EA
TCON
WAIT:JNB TF1,WAIT; 当TF1为0时,转到wait,代表未溢出
CLR EA;TF1溢出,计满则执行
CLR ET0
ANL TCON,#0FH ;定时器T0T1关闭;
SJMP $
TOS: MOV TL0,#0CH
MOV TH0,#0F0H
CPL P10;逻辑去反
RETI
END。
题型3
编写程序,要求使用T0,采用方式2定时,在P1.0输出周期为400微秒,占空比为1:9的矩形脉冲**(高电平:低电平=40us:360us)**。单片机时钟为12MHZ(机器周期1us)。
ps:如果时6MHZ,则高电平需要除2去计算。
代码:
#include “regh1.h”
sbit PWM = P1^0;
unsigned char T_Cnt=0;
void T0_Init(void)
{
TMOD = 0x02; //方式2定时,选择工作方式为8位自动重装的八位定时器/计时器
TH0 = 256-40; //固定值,当TL0递增到256产生中断后,将TL0重新装填
TL0 = 256-40; //逐渐递增,到八位全一产生TF中断标志,产生一个定时中断
ET0 = 1;//开启外部定时器T0中断
EA = 1;//开启总中断
}
void T0_Int(void) interrupt 1 //中断源是定时器0
{
if(T_Cnt >= 10)
T_Cnt = 0;
else
T_Cnt += 1;
if(T_Cnt == 0)
PWM = 1;
else
PWM = 0;
}
void main(void)
{
T0_Init();//初始化函数
PWM = 1;
TR0 = 1;//高电平定时器启动
while(1);
}

猜你喜欢

转载自blog.csdn.net/OrangeChenZ/article/details/84561199