新手记录学习:单片机C语言之定时器模拟PWM输出
一、先构思一下思路:
1、设定100HZ的频率,PWM级数200级,定时中断时间50us,也就是每一级的时间为50us。
2、用一个变量r_PwmDuty来确定占空比,默认为高电平时间比例。200-r_PwmDuty =低电平时间。
3、再用一个计数变量来r_pwm_cnt 来确认输出高低电平的时间。
4、默认先输出高电平,高电平计数=r_PwmDuty时,就输出低电平,低电平的计数=200r_PwmDuty后,再输出高电平,如此反复,设置高低电平完成标志位。
5、当PWM使能位=0时,占空比为0时,不进PWM输出循环,默认输出低电平。
二、画出流程图:
三、把流程理顺后,按照流程图编写代码并调试输出:
/********************** 包含的头文件 *********************************/
#include "my_HC89F0541.H"
#include "analog_pwm.H"
/***************** 函数的变量与位定义 *******************************/
unsigned char data r_PwmDuty=0; //高电平占空比,全局变量
static unsigned char data r_pwn_cnt=0; //计数
/********************功能声明与定义**********************************/
bit F_PWM_HV=0; //电平参考标志位 1 输出低电平, 0 输出高电平。
bit F_pwm_EN =0; // PWM使能标志位
/************************************************************************
函 数:定时器模拟PWM,200级占空比可调,频率100HZ
输 入:r_PwmDuty--> PWM占空比;F_level--> PWM使能标志位
输 出:无
返 回:无
说 明:
1、在.H文件中定义输出IO口,
2、定时器设置50us中断一次
3、在中断外控制使能位和PWM占空比(0~200)
*************************************************************************/
void analog_pwm()
{
if((F_pwm_EN)&&(r_PwmDuty !=0)) // PWM使能标志位 =1, 则输出PWM
{ //查询PWM占空比是否=0;
if (F_PWM_HV==1) //查询高电平输出完成,则输出低电平
{
if(r_PwmDuty<200)
{
if (r_pwn_cnt>(200-r_PwmDuty)) //PWM最大级数200 ,
{ //减去高电平占空比==低电平占比
F_PWM_HV=0; //查询电平计数是否=低电平占比
r_pwn_cnt=0; //如相等,则清0
}
else
{
IO_PWM=0; // 如!= 则输出低电平,计数++
r_pwn_cnt++;
}
}
}
else
{
IO_PWM=1; //输出高电平
if (++r_pwn_cnt >r_PwmDuty) //查询高电平计数是否=r_PwmDuty (占空比)
{
F_PWM_HV=1; // 等于 置1
r_pwn_cnt=0; // 计数清0
}
}
}
else // PWM使能标志位 =0, 则输出低电平
{
IO_PWM=0;
r_pwn_cnt=0;
F_PWM_HV=0;
}
}
四、在中断中调用上面的子函数就可以了,定时50us中断一次
/************************************************************************
函 数:定时中断
输 入:无
输 出:无
返 回:无
说 明:
1、
*************************************************************************/
void T0_TIMER0(void) interrupt 1 using 1 //定时器0 中断
{
if (++r_time_t0==20)
{
r_time_t0=0;
F_1ms=1;
F_key_1ms =1;
if (++r_time_t1==20)
{
F_10ms=1;
r_time_t1=0;
}
}
P05=~P05;
analog_pwm(); //调用模拟PWM子函数
}
五、在主循环中设置按键控制PWM使能位和PWM占空比,就可以输出啦。
#define ALLOCATE_EXTERN
#include "my_HC89F0541.H" //芯片头文件
#include "init.h" //初始化定义头文件
#include "key.h"
#include "sleep.h"
#include "analog_pwm.H"
/*********************** 函数声明 ************************************/
/******************声明全局字节变量*********************************/
unsigned char data r_time_t0=0;
unsigned char data r_time_t1=0;
/********************声明全局位变量*********************************/
bit F_1ms=0;
bit F_10ms=0;
/********************功能声明与定义*********************************/
/************************************************************************
函 数:main 主函数
输 入:无
输 出:无
返 回:无
说 明:
1、
*************************************************************************/
void main()
{
sys_init(); //系统初始化
while(1)
{
WDTC |= 0x10; //看门狗清0
key_scan(); //按键扫描
if (F_key_short)
{
F_key_short=0;
F_pwm_EN=~F_pwm_EN; //按键开关PWM
r_PwmDuty=0; //PWM占空比从0开始
}
if (F_10ms)
{
F_10ms=0;
if (++r_PwmDuty==201) //间隔时间 占空比++
{
r_PwmDuty=0; //最大后再从零开始
}
}
sleep(); //睡眠
}
}
有图有真相,调试成功~!!!
每天努力一点点,十年之功,必出大成果, 加油加油~!!!