知识来源于链接:https://www.bilibili.com/video/BV1eT4y1J7wB/?spm_id_from=333.880.my_history.page.click&vd_source=b91967c499b23106586d7aa35af46413
这种模拟实现 PWM 波的应用只能应用于对波形精度和频率要求不高的情况下。
一、程序思路分析
这里想要产生一个 100 Hz 的正弦波,对应周期就是 1/100 = 0.01s = 10 ms = 10 000 us
把这段时间分为100份,其中,若前 20 份为高电平,后80份为低电平,就是占空比为 20%,若100份全为高电平,则占空比就为 100% 。因此,使用定时器定时为100 us ,每经过100us,就让 I/O 输出高电平或低电平,由此,可实现模拟 PWM 的输出。
二、程序源码
time.h
#ifndef _TIME_H_
#define _TIME_H_
#include <reg52.h>
sbit PWM = P1^0;
#define PWM_DUTY 50 // 50%
// 函数的声明
void Timer0_Init(void); //1毫秒@11.0592MHz
#endif
time.c
#include "time.h"
unsigned char PWM_Cnt = 0;
void Timer0_Init(void) //100微秒@12.000MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x9C; //设置定时初始值
TH0 = 0xFF; //设置定时初始值
TF0 = 0; //清除TF0标志
ET0 = 1;
EA = 1;
TR0 = 1; //定时器0开始计时
}
void timer_isr() interrupt 1
{
TR0 = 0; //定时器0开始计时
PWM_Cnt++;
if(PWM_Cnt >= 100)
{
PWM_Cnt = 0;
}
if(PWM_Cnt < PWM_DUTY)
{
PWM = 1;
}
else
{
PWM = 0;
}
TL0 = 0x9C; //设置定时初始值
TH0 = 0xFF; //设置定时初始值
TR0 = 1; //定时器0开始计时
}
main.c
#include <reg52.h>
#include "time.h"
void main()
{
Timer0_Init();
while(1);
}
通过修改 PWM_DUTY 的值,可改变占空比大小。
通过示波器观察波形,如下图所示
该占空比为 20%
该占空比为 0%
可以发现,程序中设定的频率为100,结果输出的频率只有 77 Hz,占空比也有1%左右的误差。
三、扩展程序源码(加入按键调节)
将宏定义修改为变量
unsigned char PWM_DUTY = 0;