本帖最后由 axbin 于 2017-11-28 16:20 编辑
正好有一个STM32F429的pwm驱动蜂鸣器的例子,一共就那么几个寄存器,一看就明白,变量是手动定义的
//PWM mode 1 - In upcounting, channel 1 is active as long as TIMx_CNTTIMx_CCR1 else active(OC1REF = 1).
#define def_TIM_OCMODE_PWM1 6
//PWM mode 2 - In upcounting, channel 1 is inactive as long as TIMx_CNTTIMx_CCR1 else inactive.
#define def_TIM_OCMODE_PWM2 7
static u32 g_Counter_Clock = 0;
void TIM2_Init(void)
{
// 禁用中断
NVIC_DisableIRQ(TIM2_IRQn);
// 开timer寄存器的读写clock
SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM2EN);
// 停止计数
CLEAR_BIT(TIM2->CR1, TIM_CR1_CEN);
// 默认Upcounter
// 默认UIE=0,禁用中断
// 默认Edge-aligned mode
// Select update request source
SET_BIT(TIM2->CR1, TIM_CR1_URS); // Only counter overflow/underflow generates an update interrupt
// 默认Master mode = Reset
//TIM2->CR2 |= 0;
// Slave mode disabled,禁止从模式,Timer的时钟来自内部时钟
WRITE_REG(TIM2->SMCR, 0);
// 设置Timer的分频,直接以CK_CNT运行,这里CK_CNT来自APB1 timer clock
WRITE_REG(TIM2->PSC, 0);
g_Counter_Clock = g_APB1TimerClock;
// 设置Channel3 以PWM1模式输出 TIMx_CNTCCMR2, (def_TIM_OCMODE_PWM1 CCER, TIM_CCER_CC3P);
// 启用以下两个Preload register的作用:如果重新设置分频和占空比不会立即加载,在一个周期结束后再起作用
// Preload register on TIMx_CCR3 enabled
SET_BIT(TIM2->CCMR2, TIM_CCMR2_OC3PE);
// TIMx_ARR register is buffered
SET_BIT(TIM2->CR1, TIM_CR1_ARPE);
}
// 决定PWM的频率
void TIM2_PWM_UpdateFrequency(u32 frequency)
{
if (frequency > 0)
{
// auto-reload value which decides PWM frequency
WRITE_REG(TIM2->ARR, g_Counter_Clock / frequency - 1);
}
}
// 决定PWM的占空比 duty: 0~100
void TIM2_PWM_UpdateDuty(u32 duty)
{
if (duty CCR3, duty * (TIM2->ARR + 1) / 100);
}
}
// duty: 0~100
void TIM2_PWM_Start(u32 frequency, u32 duty)
{
TIM2_PWM_UpdateFrequency(frequency);
TIM2_PWM_UpdateDuty(duty);
// 产生一次Update Event,把preload register的值更新shadow register
SET_BIT(TIM2->EGR, TIM_EGR_UG);
//IO port B clock enable
SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOBEN);
// PB10 as TIM2-CH3
SET_BIT(GPIOB->MODER, (def_PORT_MODE_AF AFR[1], (1 CR1, TIM_CR1_CEN);
// OC3 signal is output on the corresponding output pin
SET_BIT(TIM2->CCER, TIM_CCER_CC3E);
}
void TIM2_PWM_Stop(void)
{
CLEAR_BIT(TIM2->CR1, TIM_CR1_CEN);
// OC3 is not active
CLEAR_BIT(TIM2->CCER, TIM_CCER_CC3E);
// PB10恢复默认输入模式,保证三极管断开,使蜂鸣器断电
CLEAR_BIT(GPIOB->MODER, GPIO_MODER_MODE10_Msk);
}