这个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; }
由于咱们选用的是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的!