大家好,
我将TM4C1290的定时器配置为pwm模式时,无论上升沿还是下降沿事件触发同步更新pwm的周期和占空比时(占空比保证为50%),都会出现问题(并非必然)。
比如:1)当周期变化(单位us)如:10us开始以5us增量递增,当达到50us后又以5us减量递减回到10us,以此循环。 无论上、下边缘事件更新都现象正常
2)当周期变化(单位us)如:10us开始以10us增量递增,当达到50us后又以10us减量递减回到10us,以此循环。 下边缘事件更新正常,上升沿事件更新不正常
3)当周期变化(单位us)如:10us开始以20us增量递增,当达到50us后又以20us减量递减回到10us,以此循环。 下边缘和上升沿事件都更新不正常
当我只更新周期而不更新占空比时(固定占空比控制寄存器值),无论上升沿还是下降沿事件更新,如何更新都不会出问题。
以下是我捕捉的一组异常波形:(异常点本应是20us的周期,占空比50%)
xyz549040622:
1.异常的那几个小波形是否有规律呢?
2.观察异常的时候主频是否产生了变化
3.是否观察了寄存器中pwm的值
wesley zeng:
回复 xyz549040622:
您好,
1、这种异常是有规律的,都是同一个点出现问题
2、主频没去测量
3、我将pwm周期拖长(1ms,异常存在) ,打印出pwm的值与我的预期是一样的。
Susan Yang:
另外能否上传或私信一下您现在的代码?您是使用的是TI开发板还是您自制的板子?
wesley zeng:
回复 Susan Yang:
您好,
板子是我们自制的,代码如下
/* timer configuration */GPIOPinConfigure(GPIO_PL7_T1CCP1);GPIOPinTypeTimer(GPIO_PORTL_BASE, GPIO_PIN_7);
TimerConfigure(TIMER1_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_B_PWM);HWREG(TIMER1_BASE + TIMER_O_TBMR)|=0x00000500; // update on the next timeout.
TimerControlLevel(TIMER1_BASE,TIMER_B,0);TimerControlEvent(TIMER1_BASE, TIMER_B, TIMER_EVENT_POS_EDGE); //TIMER_EVENT_NEG_EDGE);
TimerIntClear(TIMER1_BASE, TIMER_CAPB_EVENT);TimerIntEnable(TIMER1_BASE,TIMER_CAPB_EVENT);IntEnable(INT_TIMER1B);/* timer start */TimerLoadSet(TIMER1_BASE, TIMER_B, 120000 & 0xFFFF); // 1ms periodTimerPrescaleSet(TIMER1_BASE,TIMER_B, (120000 >> 16)&0xff);TimerMatchSet(TIMER1_BASE,TIMER_B, 60000 & 0xFFFF); // 50% dutyTimerPrescaleMatchSet(TIMER1_BASE,TIMER_B, (60000 >> 16)&0xff);TimerEnable(TIMER1_BASE, TIMER_B);
/* interrupt handle */void Timer1BIntHandler(void){ static uint32_t period = 120000; // 1ms static uint32_t duty = 0; static uint8_t inc_flag = 1; // printf("timer1B int\n");
if (inc_flag) { period += 120000; if (period >= 600000) { inc_flag = 0; } } else { period -= 120000; if (period <= 120000) { inc_flag = 1; } }
duty = period >> 1; TimerLoadSet(TIMER1_BASE, TIMER_B, period&0xffff); // period TimerPrescaleSet(TIMER1_BASE, TIMER_B, (period >> 16)&0xFF); TimerMatchSet(TIMER1_BASE, TIMER_B, duty&0xffff); // duty TimerPrescaleMatchSet(TIMER1_BASE, TIMER_B, (duty >> 16)&0xFF); // TimerIntClear(TIMER1_BASE, TIMER_TIMB_TIMEOUT); TimerIntClear(TIMER1_BASE, TIMER_CAPB_EVENT);}