本帖最后由 lvxinn2006 于 2019-1-22 17:15 编辑
本次活动测评开发板ST NUCLEO-G071RB由ST意法半导体提供,感谢意法半导体对EEWorld测评的支持!
【实验目的】
· 掌握PWM定时器的原理与使用
· 掌握PWM在控制LED亮度功能上的应用
【实验环境】
· NUCLEO-G071RB开发板
· 三色LED灯模块
· Keil MDK-ARM(Keil uVision 5.25.2.0)
· Keil.STM32G0xx_DFP.1.0.0.pack
【实验资料】
· NUCLEO-G071RB开发板原理图
· STM32G071x8/xB Data Sheet
· STM32G071芯片用户参考手册
【实验分析】
1、电气连接关系
红色R LED ——> PC9
绿色G LED ——> PC8
蓝色B LED ——> PC10
2、GPIO引脚配置
由上图可知,PC8、PC9、PC10三个引脚分别对应着TIM1_CH1、TIM1_CH2、TIM1_CH3,所以需要把三个引脚都配置成AF2模式。
所以需要把这三个引脚配置成响应的AF模式,即AF2。
3、启用TIM1定时器
如图设置,可以通过配置[11]位启用TIM1的时钟。
4、配置定时器
高级控制定时器(TIM1)由一个可编程的预分频器驱动的16位自动重装计数器组成,可用于多种用途,包括测量输入的脉冲长度。输入信号的捕获,或输出波形(包括输出比较,PWM,死区插入互补的PWM)。
脉冲长度和波形周期可以在几微秒内进行调制。通过设定定时器预分频器和RCC时钟控制器,可以将定时器的工作时钟周期控制在毫秒级别。高级控制定时器(TIM1)和通用定时器器是完全独立的,不共享任何资源。
高级控制定时器原理如下:
本实验主要使用该定时器产生PWM信号,通过控制PWM占空比,使用不同占空比的信号,驱动三个颜色的LED灯,以控制三个LED灯的亮度等级,就可以搭配出不同颜色。
在定时器输出PWM信号的应用中,最重要的寄存器有:
ARR ——计数重载寄存器,决定了PWM的周期;
CCRx ——比较匹配寄存器,决定了不同引脚的PWM占空比;
CNT ——定时器计数器,定时器计数器可以自增或自减,变化的过程中,不断与CCRx进行比较,一旦CNT达到CCRx的值时,就可以驱动响应的输出引脚发生电平的反转。
关于PWM相关配置的描述如下:
【实验代码】
- #include "stm32g0xx.h" // Device header
- #include <stdlib.h>
- void mdelay(int ms)
- {
- RCC->APBENR1 |= RCC_APBENR1_TIM6EN; //使能TIM6
- TIM6->PSC = SystemCoreClock / 1000 - 1; //预分频 定时器时钟为1000Hz
- TIM6->ARR = ms; //周期数
- TIM6->CR1 |= TIM_CR1_OPM; //单次脉冲模式
- TIM6->CR1 |= TIM_CR1_CEN; //启动定时器
- while(TIM6->CR1 & TIM_CR1_CEN); //等待定时器结束
- }
- void rgb_init(void)
- {
- /* 初始化IO引脚 */
- RCC->IOPENR |= RCC_IOPENR_GPIOCEN; //使能GPIOC
- GPIOC->MODER &= ~(0x3F<<16);
- GPIOC->MODER |= (0x2A<<16); //设置PC8 9 10为AF模式
- GPIOC->AFR[1] &= ~(0xFFF<<0);
- GPIOC->AFR[1] |= (0x222<<0);//设置PC8 9 10为AF2
-
- /* 初始化定时器TIM1 */
- RCC->APBENR2 |= RCC_APBENR2_TIM1EN; //启用TIM1时钟
- TIM1->CR1 = (1<<7); //允许auto-reload
- TIM1->CCMR1 = (0x6<<4) | (1<<3)
- | (0x6<<12) | (1<<11); //设置CH1 CH2为PWM模式
- TIM1->CCMR2 = (0x6<<4) | (1<<3); //设置CH3为PWM模式
- TIM1->CCER |= (1<<0) | (1<<4) | (1<<8); //使能CH1,2,3的输出功能
- TIM1->BDTR |= (1<<15); //使能定时器的主输出功能
- TIM1->PSC = 99; //分频值
- TIM1->ARR = 255; //计数最大值,决定PWM周期
- TIM1->CNT = 0; //重置定时器计数器
- TIM1->CR1 |= (1<<0); //启动定时器
- }
- int main(void)
- {
- int rgb;
- rgb_init();
- while(1){
- rgb = rand();
- TIM1->CCR1 = rgb&0xff; //CH1比较值,决定CH1占空比
- TIM1->CCR2 = (rgb>>8)&0xff; //CH2比较值,决定CH2占空比
- TIM1->CCR3 = (rgb>>16)&0xff; //CH3比较值,决定CH3占空比
- mdelay(100);
- }
- }
复制代码
【实验现象】
· 三色LED会不断的改变颜色
此内容由EEWORLD论坛网友lvxinn2006原创,如需转载或用于商业用途需征得作者同意并注明出处