这个pwm几天前就搞出来了,但是觉得不是很难,就没有写
今天jlink固件坏了,修了半天没有修好,现在就先扔着吧,先借大黄的用用,下面闲着木事,就把pwm写下吧
好吧,开始今天的pwm
还是老话,先附上一段代码:(由于stm的pwm有多个,每个又有多个通道,我们今天选TIM2_CH1来产生)
/*
* TIM2_CH1
*/
int pwm_init(u16 arr,u16 psc)
{
RCC->APB1ENR = 1<<0; //enable timer2
RCC->APB2ENR = 1<<2; //enable GPIOA
GPIOA->CRL &= ~(0xF<<0); //Clear bit0 Control Register
GPIOA->CRL |= 0xb<<0; //Set Bit0 Control Register
// GPIOA->ODR |= 1<<0; //Enable Bit0
TIM2->ARR = arr;
TIM2->PSC = psc;
TIM2->CCMR1 |= 7<<4;
TIM2->CCMR1 |= 1<<3;
TIM2->CCER |= 1<<0;
TIM2->CR1 |= 1<<0;
return 0;
}
前5句,现在大家都应该懂了吧,TIMER时钟配置,管脚时钟配置,管脚模式配置,这里肯定要配置称输出模式
由于咱们选用的是TIMER2,那我们就用TIM2
先设置自动装载寄存器ARR和预分频寄存器PSC,这两个寄存器一起来设置分频的频率
举个例子:
PCLK = 72M = 72000KHz,设置ARR = 900,PSC = 1;
则输出的PWM周期为:72 000 /(900*(1+1) ) = 40KHz
至于CCMR比较/捕获模式寄存器
他有 两个功能,当选择比较寄存器的时候,看上面一栏,捕获模式时看下面一栏
输出比较模式,他有两种输出模式,OC1和OC2,其实总共有4组,他有4路输出,CCMR1,CCMR2分别控制两组;
我们这里用的是CH1通道,所以我们需要配置0~7bit的数据。
首先我们来了解下pwm输出模式:
根据这段描述,这里的无效电平,会导致OCxREF为低电平,从而管脚输出电压即为低电平。
所以,011:在把低电平换位高电平,高电平换成低电平
100:输出全部为低电平
101:输出全为高电平
110:先输出高电平,再输出低电平,之类的CCR1比较/捕获寄存器是用来区分什么时候发生电平跳变的,CCRx寄存器也有4组,我们用的是CH1通道,估大家都懂,我们应该用CCR1
111:跟上一组相反
int main()
{
sys_init(9);
pwm_init(900,3); //Set Period
RCC->APB2ENR |= 1<<6;
GPIOE->CRL &= ~(0xf<<0);
GPIOE->CRL |= 0xb<<0;
GPIOE->ODR |= 1<<0;
TIM2->CCR1 = 0;
sw5_config();
while(1)
{
if(!(GPIOE->IDR & GPIO_Pin_14))
{
delay_ms(20);
if(!(GPIOE->IDR & GPIO_Pin_14))
{
TIM2->CCR1 += 10;
}
while(!(GPIOE->IDR & GPIO_Pin_14));
}
}
}
这里ARR = 900,PSC = 3
所以: F = 72000KHz/(900*(3+1)) = 20KHz
基本上跟示波器上的一样
关于pwm的配置是相对比较简单的,大家不要被他寄存器的数量吓到了,那么多寄存器,是因为他有多路,所以,他会有那么多,学会了一路,其他都是非常easy的!