51单片机输出两路相差10ms的,频率为30KHz的PWM用于控制DC-AC半桥逆变电路的程序
时间: 2023-05-29 08:02:21 浏览: 229
以下是51单片机输出两路相差10ms的,频率为30KHz的PWM用于控制DC-AC半桥逆变电路的程序:
```c
#include <reg51.h>
#define SYSCLK 12000000UL // 定义系统时钟频率
unsigned int count; // 控制PWM周期的计数器
void timer0_init() // 初始化Timer0
{
TMOD |= 0x01; // Timer0工作在模式1
TH0 = 0xFC; // 初始值为65536-375=65261
TL0 = 0x99; // 所以定时375个机器周期(12分之1us)
ET0 = 1; // 允许Timer0中断
TR0 = 1; // 启动Timer0
}
void pwm_init() // 初始化PWM
{
TMOD &= 0xF0; // 清除Timer1工作模式
TMOD |= 0x01; // Timer1工作在模式1
TH1 = 0xFF; // 初始值为65536-500=65036
TL1 = 0xFE; // 所以定时500个机器周期(12分之1us)
ET1 = 1; // 允许Timer1中断
TR1 = 1; // 启动Timer1
}
void delay() // 延时函数,用于设置PWM的占空比
{
unsigned int i;
for (i = 0; i < 300; i++); // 延时30us
}
void main()
{
P1 = 0x00; // 初始化P1口
P2 = 0x00; // 初始化P2口
count = 0; // 计数器清零
timer0_init(); // 初始化Timer0
pwm_init(); // 初始化PWM
EA = 1; // 允许中断
while (1); // 死循环
}
void timer0_isr() interrupt 1 // Timer0中断服务程序
{
TH0 = 0xFC; // 重新赋初值,定时375个机器周期
TL0 = 0x99;
count++; // 计数器加1
if (count == 10) // 控制PWM周期
{
count = 0;
}
}
void timer1_isr() interrupt 3 // Timer1中断服务程序
{
TH1 = 0xFF; // 重新赋初值,定时500个机器周期
TL1 = 0xFE;
if (count < 5) // 控制PWM1的占空比
{
P1 = 0x01;
delay();
P1 = 0x00;
}
else
{
P1 = 0x00;
}
if (count > 4) // 控制PWM2的占空比
{
P2 = 0x01;
delay();
P2 = 0x00;
}
else
{
P2 = 0x00;
}
}
```
代码思路:
本例中采用Timer0控制PWM周期,采用Timer1控制PWM占空比,具体实现方式是:
1. 在Timer0中断服务程序中,使用计数器count计数,当count等于10时,清零计数器,表示PWM周期结束,然后在Timer1中断服务程序中控制PWM的占空比。
2. 在Timer1中断服务程序中,根据计数器count的值,控制P1、P2口的电平,从而控制PWM的占空比,实现两路相差10ms的,频率为30KHz的PWM。
需要注意的是,延时函数delay()需要根据具体的系统时钟频率进行调整,在本例中,使用了300个机器周期进行延时,延时时间约为30us,由此计算出的PWM周期为10*0.03ms=0.3ms,PWM占空比由count的值控制,占空比为(count/10)*100%。
阅读全文