概述
PWM(脉宽调制)大家可以上网查查,其原理讲解很多。为了更好的学习PWM,我特意参照别人写的文章,自己也写了一份代码来实现PWM。代码如下:
#include <stc12c5a60s2.h>
unsigned long cnt;
unsigned int cnt_T1;
unsigned int high;
unsigned int low;
unsigned char TH0_high;
unsigned char TL0_high;
unsigned char TH0_low;
unsigned char TL0_low;
unsigned char T1H1;
unsigned char T1L1;
unsigned char flag=0;
unsigned char duty[19] = {5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95};
unsigned char index=0;
void config_Fy_and_dy(unsigned char fy, unsigned char dy);
void config_Timer1(unsigned char ms);
void modify_duty(unsigned char dy);
sbit PWM_OUT = P2^5;
void main()
{
TMOD = 0X11; // 定时器0/1都工作在方式1,是2^16计数
EA=1;
config_Fy_and_dy(100, 20);
config_Timer1(50);
while(1);
}
void config_Fy_and_dy(unsigned char fy, unsigned char dy) // 输入频率fy,占空比dy
{
cnt = (11059200/fy)/12; // 要产生频率为fy,定时器0所要计的数值
high = (cnt*dy)/100; // 计算出高电平所要计的数值
low = cnt - high; // 计算出低电平所要计的数值
high = 65536 - high; // 确定定时器0,从哪个初值开始计时,记录的是高电平
low = 65536 - low; // 确定定时器0,从哪个初值开始计时,记录的是低电平
TH0_high = (unsigned char)(high>>8); // 高电平,给TH0预备重装初值
TL0_high = (unsigned char)high; // 高电平,给TL0预备重装初值
TH0_low = (unsigned char)(low>>8); // 低电平,给TH0预备重装初值
TL0_low = (unsigned char)low; // 低电平,给TL0预备重装初值
TH0 = TH0_high;
TL0 = TL0_high;
PWM_OUT = 1;
ET0 = 1;
TR0 = 1;
}
void config_Timer1(unsigned char ms)
{
unsigned long temp;
temp = 11059200/1000;
temp = (temp*ms)/12;
cnt_T1 = 65536 - temp;
T1H1 = (unsigned char)(cnt_T1>>8);
T1L1 = (unsigned char)cnt_T1;
TH1 = T1H1;
TL1 = T1L1;
ET1=1;
TR1=1;
}
void modify_duty(unsigned char dy)
{
high = (cnt*dy)/100;
low = cnt - high;
high = 65536 - high;
low = 65536 - low;
TH0_high = (unsigned char)(high>>8); // 高电平,给TH0预备重装初值
TL0_high = (unsigned char)high; // 高电平,给TL0预备重装初值
TH0_low = (unsigned char)(low>>8); // 低电平,给TH0预备重装初值
TL0_low = (unsigned char)low; // 低电平,给TL0预备重装初值
}
void T0_Timer0() interrupt 1
{
if(PWM_OUT==0) // 准备产生高电平
{
TH0 = TH0_high; // 高电平产生 初值重装
TL0 = TL0_high;
PWM_OUT = 1;
}
else
{
TH0 = TH0_low; // 低电平产生 初值重装
TL0 = TL0_low;
PWM_OUT = 0;
}
}
void T1_Timer1() interrupt 3
{
TH1 = T1H1;
TL1 = T1L1;
modify_duty(duty[index]);
if(0 == flag) // flag=0时,表示呼吸灯由暗变亮
{
index++;
if(index >=18)
{
flag = 1;
}
}
else
{
index--;
if(index <=0)
{
flag=0;
}
}
}
其实,PWM这种实现方法并不适合编程,因为它占用了两个定时器中断口,会影响程序的执行效率。
我是通过两个定时器来更好的掌握PWM的调制原理。
接下来,我将会通过单片机(STC12C5A60S2)内部模块实现PWM,实现比较简单,将在下个文章来完成。
最后
以上就是鲜艳吐司为你收集整理的使用两个定时器实现PWM(脉宽调制)——呼吸灯的全部内容,希望文章能够帮你解决使用两个定时器实现PWM(脉宽调制)——呼吸灯所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复