0x00 简介
提前声明,stc 公司的 51 单片机,新的型号有 PWM 的功能,而且有标准库,可以做参考,一般的单片机如果没有,可以用下面的方法生成。
本例使用的是 stc15w204s 单片机,用的定时器 2,没有使用原生的 PWM 的功能。
所有例子都是使用 vscode + eide + sdcc 的全开源编译环境来实现的,语法上会和 keil 些许区别。
PWM是脉冲宽度调制(Pulse Width Modulation)的缩写,它是一种用数字信号控制模拟电路的技术。简单来说,PWM就是通过改变信号的脉冲宽度来控制电路的输出。
占空比是PWM信号中高电平时间与一个周期时间之比,通常用百分比表示。例如,50%的占空比表示高电平时间占一个周期时间的一半。
频率是PWM信号中脉冲的重复频率,通常用赫兹(Hz)表示。例如,一个频率为1kHz的PWM信号表示每秒钟有1000个脉冲。频率越高,脉冲的间隔时间越短,控制精度越高,但同时也会增加系统的计算负担和电路噪声。
以下是图示
U
^ ton
<------------> toff
| <---->
+------------+ +-----------+
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
+------------+------+-----------+--> T
0 tcycle
<------------------->
图示中的 ton 为高电平的时间,toff为低电平时间,tcycle 为一个周期,加入一个周期 10 ms,那么 1 秒重复 100 次,这个 pwm 为 100 HZ 的频率。
0x01 代码实现
// pwm输出 定时器· P15 输出
// pwm 输出 100 us 最小的一个分度,所以 pwm 周期为 10 ms,频率为 100 HZ。
// 频率不变,用 compare 来做占空比,0-100 之间。
#include "stc15.h"
#include "mysdcc.h"
#define PWMPIN P15 //定义PWM输出引脚。
u8 compare,counter;
void Timer2_Isr(void) interrupt 12
{
// 计数器
counter++;
// 计数器限制在 0-99 之间
if(counter > 99)
{
counter = 0;
}
// 设置 pwm 输出,counter 与 compare 作比较,compare输出的是 低电平 部分,如果想改成高电平部分,改下面的代码的 1 和 0 互换位置即可
PWMPIN = (counter >= compare) ? 1 : 0;
}
void Timer2_Init(void) //100微秒@12.000MHz
{
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0x50; //设置定时初始值
T2H = 0xFB; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
IE2 |= 0x04; //使能定时器2中断
}
void main()
{
compare = 65; // 设置占空比初始值
Timer2_Init(); //初始化定时器2
EA = 1; //开全局中断
while(1)
{
// compare 的值小于 0 时定义为0;
// compare 的值大于 100 时定义为100;
// 否则 compare 的值不变。
compare = (compare <= 0) ? 0 : compare;
compare = (compare >= 100) ? 100 : compare;
}
}