🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
这个pwm几天前就搞出来了,但是觉得不是很难,就没有写 今天jlink固件坏了,修了半天没有修好,现在就先扔着吧,先借大黄的用用,下面闲着木事,就把pwm写下吧 ![](https://box.kancloud.cn/2016-06-21_576915b397e1c.jpg) ![](https://box.kancloud.cn/2016-06-21_576915b3bc73f.jpg) 好吧,开始今天的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比较/捕获模式寄存器 ![](https://box.kancloud.cn/2016-06-21_576915b3dd83f.jpg) 他有 两个功能,当选择比较寄存器的时候,看上面一栏,捕获模式时看下面一栏 输出比较模式,他有两种输出模式,OC1和OC2,其实总共有4组,他有4路输出,CCMR1,CCMR2分别控制两组; 我们这里用的是CH1通道,所以我们需要配置0~7bit的数据。 首先我们来了解下pwm输出模式: ![](https://box.kancloud.cn/2016-06-21_576915b3f33f4.jpg) 根据这段描述,这里的无效电平,会导致OCxREF为低电平,从而管脚输出电压即为低电平。 所以,011:在把低电平换位高电平,高电平换成低电平 100:输出全部为低电平 101:输出全为高电平 110:先输出高电平,再输出低电平,之类的CCR1比较/捕获寄存器是用来区分什么时候发生电平跳变的,CCRx寄存器也有4组,我们用的是CH1通道,估大家都懂,我们应该用CCR1 111:跟上一组相反 ![](https://box.kancloud.cn/2016-06-21_576915b4287f6.jpg) ~~~ 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)); } } } ~~~ ![](https://box.kancloud.cn/2016-06-21_576915b44966a.jpg) 这里ARR = 900,PSC = 3 所以: F = 72000KHz/(900*(3+1)) = 20KHz 基本上跟示波器上的一样 关于pwm的配置是相对比较简单的,大家不要被他寄存器的数量吓到了,那么多寄存器,是因为他有多路,所以,他会有那么多,学会了一路,其他都是非常easy的!