【问题标题】:PWM for LED dimming unusual behavior用于 LED 调光异常行为的 PWM
【发布时间】:2020-12-07 19:50:38
【问题描述】:

我做了一个函数,在输出端(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;
}

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

  • 传递给pwm函数的第二个参数是占空比(以%为单位),从0变为100
  • 通过可变“宽度”控制占空比从 0% 前进到 100% 所需的时间(宽度 = 100 表示最快的时间,高于此值的所有时间都被认为是从 0% 到 100% 逐渐变慢的时间)
  • 表达式((j*100)/width) 用作pwm 函数内“while”循环内的步进变量:
  1. 如果width = 100,步长每增加一个“j”
  2. 如果width = 1000,步长每增加10个“j”, 等
  • PORTD作为它的地址传递给函数,而在函数pwm中,这个地址是通过指针变量lat来操作的

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

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

这是,程序应该如何运行:https://vimeo.com/488207207

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

【问题讨论】:

  • 你是否切换了看门狗?
  • 你用调试器检查过吗?
  • @Mike Watchdog 设置为关闭。我检查了调试器,这就是我知道传递给 pwm 函数的变量在从 655 转换到 656 时重置(不知何故)的方式。
  • @Mike 如果好奇,您可以检查编辑,我提供了配置位设置。但是,我认为这些定义是应有的定义。我也认为,硬件(或连接)没有问题,因为在调试器中发现了错误(使用 MPLAB X)。

标签: c pic microchip pwm


【解决方案1】:

问题是 16 位溢出:

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

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

例如

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

【讨论】:

  • 还没有尝试过,但我认为j/(width/100) 不会溢出,当j 从 655 变为 656 时?
  • @Keno 注意整数除法(width / 100),它仅适用于 100 的倍数。
  • @thebusybee 是的,我在实现代码时意识到了这一点。现在我选择了一种不同的方法,它不包括整数除法或任何除法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-11
  • 1970-01-01
相关资源
最近更新 更多