STM32F030 PWM 设置问题
STM32F030 PWM Setup Issues
我试图让我的 STM32030R8T6 的两个引脚上的 PWM 正常工作,它在 Nucleo 开发板上,我正在使用 Keil。为了学习,我主要关注 this website 上的资料,但随着该站点使用不同的 MCU 进行了改编。设置 PWM 真的没什么,所以我不太确定我做错了什么,我知道定时器正在工作,因为板载 LED 每秒闪烁 1.5 次,但是当我监控 Ch1 和我的示波器的 Ch2 输出引脚一无所获。我很确定这些引脚在备用功能推挽中设置正确,因为它们设置为与正在运行并显示 24 MHz 的 MCO 引脚相同(尽管我的廉价示波器在确定这一点时存在一些问题......)。我已经附上了我所有的相关代码,甚至可能相关的代码。为了您的方便:
UM0360 Reference Manual (STM32F030...)
我也会 post 链接到 Nucleo 用户手册和设备数据表,但我不能 post 超过两个链接,因为这是我的第一个问题而且我的声誉较低十个以上
感谢任何关于我可能做错的帮助,我确信这是愚蠢的事情。
#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 位)。
(注意,你的header可能和我的寄存器命名不一样,你的alternate functions也可能不一样;我一般用STM32F407或者STM32F334,要找alternate functions的table看看你用的是哪个需要,你必须在数据表中查找你正在使用的特定芯片,而不是你上面链接的家庭参考手册)
更一般的形式是
mode << (pin * 4)
AFRL 和
mode << ((pin - 8) * 4)
对于 AFRH。
我试图让我的 STM32030R8T6 的两个引脚上的 PWM 正常工作,它在 Nucleo 开发板上,我正在使用 Keil。为了学习,我主要关注 this website 上的资料,但随着该站点使用不同的 MCU 进行了改编。设置 PWM 真的没什么,所以我不太确定我做错了什么,我知道定时器正在工作,因为板载 LED 每秒闪烁 1.5 次,但是当我监控 Ch1 和我的示波器的 Ch2 输出引脚一无所获。我很确定这些引脚在备用功能推挽中设置正确,因为它们设置为与正在运行并显示 24 MHz 的 MCO 引脚相同(尽管我的廉价示波器在确定这一点时存在一些问题......)。我已经附上了我所有的相关代码,甚至可能相关的代码。为了您的方便:
UM0360 Reference Manual (STM32F030...)
我也会 post 链接到 Nucleo 用户手册和设备数据表,但我不能 post 超过两个链接,因为这是我的第一个问题而且我的声誉较低十个以上
感谢任何关于我可能做错的帮助,我确信这是愚蠢的事情。
#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 位)。
(注意,你的header可能和我的寄存器命名不一样,你的alternate functions也可能不一样;我一般用STM32F407或者STM32F334,要找alternate functions的table看看你用的是哪个需要,你必须在数据表中查找你正在使用的特定芯片,而不是你上面链接的家庭参考手册)
更一般的形式是
mode << (pin * 4)
AFRL 和
mode << ((pin - 8) * 4)
对于 AFRH。