我正在尝试让 PWM 在 STM32030R8T6 的两个引脚上运行,它位于 Nucleo 开发板上,并且我正在使用 Keil。为了学习,我主要关注 this website 上的 Material 。 ,但由于该站点使用不同的 MCU 而进行了调整。设置 PWM 确实没什么,所以我不太确定我做错了什么,我知道计时器正在工作,因为板载 LED 每秒闪烁 1.5 次,但是当我监控 Ch1 和我的示波器的 Ch2 输出引脚什么也没得到。我很确定引脚在备用功能推挽中设置正确,因为它们的设置与正在运行并显示 24 MHz 的 MCO 引脚相同(尽管我的廉价示波器在确定这一点方面存在一些问题......)。我已附上所有相关的甚至远程可能相关的代码。为了您的方便:
UM0360 Reference Manual (STM32F030...)
我也会发布 Nucleo 用户手册和设备数据表的链接,但我不能发布两个以上的链接,因为这是我的第一个问题,而我的声誉不到 10。
任何有关我可能做错的事情的帮助都会受到赞赏,我确信这是愚蠢的事情。
#include "stm32f0xx.h"
void Initializations(void);
int main(void)
{
Initializations();
while(1)
{
/* Toggle onboard LED whenever timer overflows */
if((TIM3->SR & TIM_SR_UIF))
{
TIM3->SR &= ~TIM_SR_UIF;
GPIOA->ODR ^= GPIO_ODR_5;
}
}
}
void Initializations(void)
{
/* CLK CONFIG */
RCC->CFGR |= RCC_CFGR_HPRE_DIV2 |
RCC_CFGR_PPRE_DIV16 |
RCC_CFGR_MCO_SYSCLK |
RCC_CFGR_PLLMUL6;
/* Activate PLL, wait */
RCC->CR |= RCC_CR_PLLON;
while(!(RCC->CR & RCC_CR_PLLRDY));
RCC->CFGR |= RCC_CFGR_SW_PLL;
/* Enable IO CLKs */
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
RCC->AHBENR |= RCC_AHBENR_GPIOCEN;
/* Enable peripheral CLKs */
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
/* PIN INITIALIZATIONS */
GPIOA->MODER |= GPIO_MODER_MODER5_0 | // Onboard LED (General output)
GPIO_MODER_MODER2_1 | // USART2 TX (Alternate function)
GPIO_MODER_MODER3_1 | // USART2 RX (Alternate function)
GPIO_MODER_MODER6_1 | // TIM3 CH1 (Alternate function)
GPIO_MODER_MODER7_1 | // TIM3 CH2 (Alternate function)
GPIO_MODER_MODER8_1 | // MCO (Alternate function)
GPIO_MODER_MODER9_1 | // USART1 TX (Alternate function)
GPIO_MODER_MODER10_1; // USART1 RX (Alternate function)
/* TIMER INITS */
TIM3->PSC = 7;
TIM3->ARR = 59999;
/* CCM1 */
TIM3->CCMR1 |= TIM_CCMR1_OC1M_0 |
TIM_CCMR1_OC1M_1;
TIM3->CCR1 |= 4499;
TIM3->CCER |= TIM_CCER_CC1E; // Enable Ch1
/* CCM2 */
TIM3->CCMR1 |= TIM_CCMR1_OC2M_0 |
TIM_CCMR1_OC2M_1;
TIM3->CCR2 |= 29999;
TIM3->CCER |= TIM_CCER_CC2E; // Enable Ch2
TIM3->CR1 |= TIM_CR1_CEN; // Enable TIM3
/* USART INITS */
RCC->CFGR3 |= RCC_CFGR3_USART1SW_0; // Clock USART1 from SYSCLK
}
最佳答案
除了将引脚设置为使用备用功能之外,您还必须设置要使用的备用功能。
您链接的文档的第 8.3.2 节(pdf 第 128 页)对此进行了描述。
这些是端口上的 AFRL(针对引脚 0-7)和 AFRH(针对引脚 8-15)寄存器。
例如,根据您的代码,如果 TIM3 使用备用功能 2 并且位于引脚 6 和 7 上(并假设备用代码当前为 0),您会这样做
GPIOA->AFRL |= (2 << (6 * 4)) | (2 << (7 * 4));
如果它不为 0 或者您想确定,请先屏蔽这些位(每个引脚获得 4 位)。
(注意,您的头文件中的寄存器名称可能与我的不同,您的备用函数也可能不同;我通常使用 STM32F407 或 STM32F334。要查找备用函数表以了解您需要哪一个,您将拥有在您正在使用的特定芯片的数据表中查找,而不是在上面链接的系列引用手册中查找)
更一般的形式是
mode << (pin * 4)
AFRL 和
mode << ((pin - 8) * 4)
对于 AFRH。
关于timer - STM32F030 PWM 设置问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28105532/