STM32F100RBTx无法输出PWM信号求助(附代码)
STM32F100RBTx PWM输出故障排查求助
我尝试使用STM32F100RBTx输出PWM信号,但始终无法成功。已经反复核对所有寄存器地址,问题仍然存在。起初不确定烧录是否成功,于是将PB7引脚配置为GPIO输出并连接LED,LED正常点亮,说明烧录及GPIO配置均无问题。以下是我的代码,求排查思路:
TUFAN_VLDCMS_Global.h
#include <stdint.h> #define RCC 0x40021000 #define RCC_AHBENR 0x40021014 #define RCC_APB2ENR 0x40021018 #define RCC_APB1ENR 0x4002101C #define AFIO 0x40010000 #define AFIO_MAPR 0x40010004 #define GPIOB 0x40010C00 #define GPIOB_ODR 0x40010C0C #define TIM4 0x40000800 #define TIM4_CR1 0x40000800 #define TIM4_CR2 0x40000804 #define TIM4_SMCR 0x40000808 #define TIM4_DIER 0x4000080C #define TIM4_SR 0x40000810 #define TIM4_EGR 0x40000814 #define TIM4_CCMR1 0x40000818 #define TIM4_CCMR2 0x4000081C #define TIM4_CCER 0x40000820 #define TIM4_CNT 0x40000824 #define TIM4_PSC 0x40000828 #define TIM4_ARR 0x4000082C #define TIM4_CCR1 0x40000834 #define TIM4_CCR2 0x40000838 #define TIM4_CCR3 0x4000083C #define TIM4_CCR4 0x40000840 #define TIM4_DCR 0x40000848 #define TIM4_DMAR 0x4000084C
main.c
#include <stdio.h> #include <stdint.h> #include "TUFAN_VLDCMS_Global.h" int main(){ volatile uint32_t * tim4Cr1 = (volatile uint32_t *) TIM4_CR1; volatile uint32_t * tim4Psc = (volatile uint32_t *) TIM4_PSC; volatile uint32_t * tim4Arr = (volatile uint32_t *) TIM4_ARR; volatile uint32_t * tim4Ccr1 = (volatile uint32_t *) TIM4_CCR1; volatile uint32_t * tim4Ccmr1 = (volatile uint32_t *) TIM4_CCMR1; volatile uint32_t * tim4Ccer = (volatile uint32_t *) TIM4_CCER; volatile uint32_t * tim4Egr = (volatile uint32_t *) TIM4_EGR; volatile uint32_t * rccApb1enr = (volatile uint32_t *) RCC_APB1ENR; volatile uint32_t * rccApb2enr = (volatile uint32_t *) RCC_APB2ENR; volatile uint32_t * gpiobCrL = (volatile uint32_t *) GPIOB; volatile uint32_t * gpiobOdr = (volatile uint32_t *) GPIOB_ODR; volatile uint32_t * afioMapr = (volatile uint32_t *) AFIO_MAPR; *rccApb1enr |= (1<<2); //enable TIM4 from APB1 *rccApb2enr |= (1<<0); //enable AFIO from APB2 *rccApb2enr |= (1<<3); //enable IOPB from APB2 *afioMapr &= ~(1<<12); //set alternate function remap to 0 *gpiobCrL |= (3<<24); //PB6 Output Mode 50Mhz *gpiobCrL |= (2<<26); //PB6 Alternate function Push-Pull *gpiobCrL |= (3<<28); //Configuring PB7 to for test to see if i can flash it *gpiobCrL &= ~(3<<30); *tim4Cr1 |= 0x0000; //reseting it just in case *tim4Psc = 7; //calculated it thinking default clock speed is 8MHz *tim4Arr = 62; //I want to have PWM signal around 16kHz *tim4Ccr1 = 31; //and %50 duty cycle *tim4Ccmr1 |= 0x68; //configuring channel 1 *tim4Ccer |= (1<<0); //enabling channel 1 *tim4Cr1 |= (1<<0); //enable the timer *tim4Egr |= (1<<0); while (1){ *tim4Ccr1 = 31; *gpiobOdr |= (1<<7); } }
排查要点:
- TIM4 CCMR1配置错误:你用
*tim4Ccmr1 |= 0x68的方式配置通道1,可能因为寄存器默认值不为0,导致无关位干扰配置。正确的PWM模式1配置应该先清零对应位再设置:*tim4Ccmr1 = (6 << 4) | (1 << 3);(OC1M设为110启用PWM模式1,OC1PE设为1使能预装载)。 - ARR预装载未开启:需要设置TIM4_CR1的ARPE位(位7),即
*tim4Cr1 |= (1 << 7);,确保ARR寄存器的预装载生效,否则定时器参数可能无法正确更新。 - EGR触发时机不合理:建议先触发EGR的UG位更新所有寄存器,再开启定时器,调整顺序为:配置PSC/ARR/CCR1 → 触发EGR → 开启TIM4。
- 冗余代码清理:while循环里反复设置
*tim4Ccr1 = 31完全没必要,直接删除即可,避免占用CPU资源。
内容的提问来源于stack exchange,提问作者Rynxie
相关产品推荐
相关产品推荐

