关于定时器(+PWM波)~

学习使我强壮!!!


准备学习PWM,然后,,,发现自己貌似并不是很懂定时(计数)器这个东东,emmm,木得关系,再学习一下!!!


明确:

1. 时钟周期 = 1/11059200,1个机器周期 = 12个时钟周期;
2. 关于定时功能的实现:定时器内部有一个寄存器,开始计数后,每隔一个机器周期(12/11059200秒)自动加一,当加到上限(比如16位的定时器,最大值是65535),那么加到65535后再加1(65536)就会溢出,然后自动清0,定时就是利用这个特点,我们设置一个初始值,让定时器从这个初始值开始加1,加到65536清0,实现1次计时,那么定时值 = (65536 - 初始值),一句话,从某一个初值开始,经过确定的时间后溢出,这就是定时
3. 定时器分为:定时器0定时器1
4. 注意图中红色线框部分:(以定时器0为例)当写TR0 = 1后,定时器就会每隔1个机器周期自动加1
关于定时器(+PWM波)~
5. 两个工作模式(模式1模式2):
关于定时器(+PWM波)~
模式1:计数范围是 0~65535,溢出后,只要不对 THn 和 TLn 重新赋值,则从 0 开始计数
模式2:只有 TLn做加 1 计数,计数范围 0~255,THn 的值并不发生变化,而是保持原值TLn 溢出后,TFn就直接置 1 了,并且 THn 原先的值直接赋给 TLn,然后 TLn 从新赋值的这个数字开始计数(用来产生串口的通信波特率
6. 关于TMOD: 低四位是定时器0,高四位是定时器1,要控制定时器0,我们就需要让低四位置1定时器1,让高四位置1
关于定时器(+PWM波)~
7. 让我们来看一下计数初值是怎么计算的呢?加入说我们要定时2ms,也就是0.002秒,设需要计时x个机器周期,那么 x * (12/11059200) = 0.002 ,那么x = 0.002 *(11059200 / 12),而这个x就是我们程序中的tmp了,这个tmp是我们需要计时的个数,那我们的初值怎么计算呢?很简单,只要用 65536-tmp 就好了呀,来看一下代码:

void ConfigTimer0(u8 ms)
{
	u32 tmp;
	
	tmp = 11059200 / 12;
	tmp = (tmp * ms) / 1000;
	tmp = 65536 - tmp;
	T0RH = (u8)(tmp >> 8);
	T0RL = (u8)tmp;
	TMOD &= 0xF0;
	TMOD |= 0x01;
	TH0 = T0RH;
	TL0 = T0RL;
	ET0 = 1;
	TR0 = 1;
} 

总之就记住一句话!!!计时个数(tmp) = (11059200/12) * 定时时间


明白了上面那些,我们再来看一下PWM波(调占空比)的程序叭~

/*PWM是指高电平占的百分比*/
void ConfigTimer1(u32 fr, u8 dc)//fr代表频率(时间= 1/fr),dc表示高电平所占的份额
{
	u8 high,low;
	u32 tmp2;
	
	tmp2 = 11059200/12/fr;//算出对应频率下的计数次数
	high = (tmp2 * dc) / 100;//高电平的计数次数
	low = tmp2 - high;//低电平的计数次数
	high = 65536 - high;//高电平的初值
	low = 65536 - low;//低电平的初值
	HIGHRH = (u8)(high >> 8);//给高八位赋值
	HIGHRL = (u8)high;//给低八位赋值
	LOWRH = (u8)(low >> 8);
	LOWRL = (u8)low;
	
	TMOD &= 0x0F;//选定定时器1,定时器0也可以,这里我用的是定时器1
	TMOD |= 0x10;
	TH1 = HIGHRH;//给寄存器高八位赋值
	TL1 = HIGHRL;//给寄存器低八位赋值
	ET1 = 1;//开启中断1
	TR1 = 1;//开启计数器
	PWMOUT = 1;//讲输出口拉高
}