以下是基于Keil C51编译器的89C52RC单片机PWM波输出程序:

#include <reg52.h>

#define FREQ_INIT 50000 // 初始频率
#define DUTY_INIT 50    // 初始占空比
#define DUTY_STEP 5     // 占空比调整步长
#define MAX_DUTY 100    // 最大占空比
#define MIN_DUTY 0      // 最小占空比

unsigned long freq;     // 实际频率
unsigned char duty;     // 实际占空比
unsigned long th;       // 定时器计数器上限
unsigned long tl;       // 定时器计数器下限
unsigned char increase; // 是否需要增加占空比
unsigned char decrease; // 是否需要减少占空比

void timer0_init() // 定时器0初始化
{
    TMOD &= 0xF0; // 清空定时器0模式
    TMOD |= 0x01; // 定时器0工作在模式1(16位定时器模式)
    TH0 = (unsigned char)(th >> 8); // 初始化定时器0上限
    TL0 = (unsigned char)(tl & 0xFF); // 初始化定时器0下限
    TR0 = 1; // 启动定时器0
}

void pwm_init() // PWM初始化
{
    freq = FREQ_INIT; // 初始化频率为50000HZ
    duty = DUTY_INIT; // 初始化占空比为50%
    increase = 0; // 初始化占空比调整标志位
    decrease = 0; // 初始化占空比调整标志位
    th = (65536UL - 11059200UL / 12 / freq) / 2; // 计算定时器计数器上限
    tl = th * duty / 100; // 计算定时器计数器下限
    timer0_init(); // 初始化定时器0
}

void main()
{
    pwm_init(); // 初始化PWM
    while (1)
    {
        if (increase) // 如果需要增加占空比
        {
            if (duty < MAX_DUTY) // 如果占空比未达到最大值
            {
                duty += DUTY_STEP; // 增加占空比
                tl = th * duty / 100; // 重新计算定时器计数器下限
                increase = 0; // 清除标志位
            }
        }
        if (decrease) // 如果需要减少占空比
        {
            if (duty > MIN_DUTY) // 如果占空比未达到最小值
            {
                duty -= DUTY_STEP; // 减少占空比
                tl = th * duty / 100; // 重新计算定时器计数器下限
                decrease = 0; // 清除标志位
            }
        }
    }
}

void timer0_isr() interrupt 1 // 定时器0中断服务函数
{
    TH0 = (unsigned char)(th >> 8); // 重新加载定时器0上限
    TL0 = (unsigned char)(tl & 0xFF); // 重新加载定时器0下限
    P1_0 = !P1_0; // 反转P1.0口输出电平
}

void s1_isr() interrupt 0 // S1键中断服务函数
{
    increase = 1; // 设置占空比增加标志位
}

void s2_isr() interrupt 2 // S2键中断服务函数
{
    decrease = 1; // 设置占空比减少标志位
}

程序中使用定时器0实现PWM波输出,定时器0中断服务函数中反转P1.0口输出电平,从而输出PWM波。程序中还使用两个外部中断服务函数实现按键S1和S2的检测,按下S1键时将占空比增加5%,按下S2键时将占空比减少5%。注意,程序中需要根据实际频率和占空比计算定时器计数器上限和下限,以确保输出的PWM波形准确无误


原文地址: https://www.cveoy.top/t/topic/fkTr 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录