用于 LED 调光异常行为的 PWM

PWM for LED dimming unusual behavior

我创建了一个函数,其中在输出端 (PORTD) 生成 PWM 信号,而无需使用 PIC 微控制器 (PIC18F452) 内部的 PWM 控制寄存器。为了慢慢调暗连接在输出端的 LED,我试图增加脉冲从一个周期的 0% 前进到方波一个周期的 100% 所需的时间,同时使方波频率恒定。一切都应该按计划进行,除了第二个参数被传递到 pwm 函数,当从 655 变为 666 时(即,当占空比为 65% 时)以某种方式重置。在此事件之后,传递给 pwm 函数的值从 0 开始。它不应在从 655 到 656 的转换时重置,而是在从 1000 到 1001 的转换时重置。

void main(void) {
    TRISD = 0x00; //port D set as output
    LATD = 0x00; //port D output set LOW

    unsigned int width = 1000;      // length of T_on + T_off
    unsigned int j;
    unsigned int res;
    while(1){
        for (j = 1; j <= width; j++){
            res = (unsigned int)((j*100)/width);
            pwm(&LATD, res);
        }
    }
    return;
}

void pwm(volatile unsigned char *lat, unsigned int cycle){
    if(cycle > 100){        // reset the "cycle"
        cycle = 100;
    }
    unsigned int i = 1;
    while(i<=(cycle)){    // T_on
        *lat = 0x01;    
        i++;
    }
    unsigned int j = 100-cycle;
    while(j){    // T_off
        *lat = 0;
        j--;
    }
    return;
}

至于程序本身,它应该是这样工作的:

  1. 如果width = 100,每增加“j”步长就增加
  2. 如果width = 1000,每增加10个“j”,step就会增加, 等等

至于问题本身,我只能假设两种可能:函数pwm的第二个参数的数据类型不正确,或者PIC微处理器内部存在一些未知的限制。

此外,这里是 PIC 的配置位(设备特定寄存器)的定义,位于该程序中包含的 int 头文件中:https://imgur.com/a/UDYifgN

程序应该这样运行:https://vimeo.com/488207207

这是程序当前的运行方式:https://vimeo.com/488207746

问题是 16 位溢出:

res = (unsigned int)((j*100)/width);

如果j大于655则j*100的计算结果大于16位。将其切换为 32 位。或者更容易让你的循环从 0...100 for res.

例如

for (res = 0; res <= 100; res++){
    pwm(&LATD, res);
}