【发布时间】: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”循环内的步进变量:
- 如果
width = 100,步长每增加一个“j” - 如果
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)。