先说一下实验原理:简单来说就是通过调节占空比,改变输出电压大小,从而实现控制小灯亮的程度。
在这里我用的是正点原子的精英板,通过复用重映射将PA7(时钟3的通道2:TIM3_CH2) 的引脚映射到PB5(LED0)上,下面说一下具体过程。
参考正点原子,如下图:
实验配置步骤:
1)开启 TIM3 时钟,配置 PB5 为复用输出。
①通过 RCC->APB1ENR (外设时钟使能寄存器)进行设置开启 TIM3 的时钟。
②通过GPIOB->CRL(端口配置低寄存器)将PB5 设置为复用推挽输出。
③使能GPIOB时钟。
因为要使用 TIM3,所以使能时钟3,因为 TIM3_CH2 通道将重映 射到 PB5 上,所以使能IO端口B时钟。
2)设置 TIM3_CH2 重映射到 PB5 上。
①通过AFIO->MAPR(复用重映射和调试I/O配置寄存器)将PA7部分重映射到PB5。
②通过RCC->APB2ENR(外设时钟使能寄存器)开启辅助时钟。
因为 TIM3_CH2 默认是接在 PA7 上的,所以我们需要设置 TIM3_REMAP 为部分重映射(通 过 AFIO_MAPR 配置),让 TIM3_CH2 重映射到 PB5 上面。
又因为使用了AFIO的重映射功能以及外部中断(EXTI)控制寄存器 所以要开启辅助时钟(两个使用了一个就要开启)。
重映射表:
3)设置 TIM3 的 ARR 和 PSC。
①通过TIM3->ARR(自动重装载寄存器),TIM3->PSC (预分频寄存器)配置。
公式:Tout= ((arr+1)*(psc+1))/Tclk
arr重装载值,psc预分频系数
这两个值的用法:
eg:arr=9999,psc=7199;9999是自动重新装载值,就是你要计数多少次,stm32真正计数次数需要加一,也就是9999+1=10000次,7199将TIM挂的时钟分频,这里7199一样要加一,预分频系数就是7200,那么你的分频时钟就是72MHz/7200 = 10KHz,计数次数是10000次,计数时间就是10000/10KHz = 1s会触发一次定时器溢出中断。
在开启了 TIM3 的时钟之后,我们要设置 ARR 和 PSC 两个寄存器的值来控制输出 PWM 的 周期。当 PWM 周期太慢(低于 50Hz)的时候,我们就会明显感觉到闪烁了。因此,PWM 周 期在这里不宜设置的太小。
4)设置 TIM3_CH2 的 PWM 模式。
①通过TIM3->CCMR1(比较/捕获模式寄存器)选择PWM模式。
②通过TIM3->CCER(捕获/比较使能寄存器)选择输入/捕获输出极性 。
(PS:OCxREF和CCXP共同决定引脚的输出电平,CC1P与REF相同则输出为1,反之输出为0。)
设置 TIM3_CH2 为 PWM 模式(默认是冻结的),因为 DS0 是低电 平亮,而我们希望当 CCR2 的值小的时候,DS0 就暗,CCR2 值大的时候,DS0 就亮,所以我 们要通过配置 TIM3_CCMR1 的相关位来控制 TIM3_CH2 的模式。
5)使能 TIM3 的 CH2 输出,使能 TIM3。
①通过TIM3->CCER(捕获/比较使能寄存器)配置。
②通过TIM3->CR1(控制寄存器)配置。
在完成以上设置了之后,我们需要开启 TIM3 的通道 2 输出以及 TIM3。前者通过 TIM3_CCER1 来设置,是单个通道的开关,而后者则通过 TIM3_CR1 来设置,是整个 TIM3 的 总开关。只有设置了这两个寄存器,这样我们才能在 TIM3 的通道 2 上看到 PWM 波输出。
6)修改 TIM3_CCR2 来控制占空比。
最后,在经过以上设置之后,PWM 其实已经开始输出了,只是其占空比和频率都是固定 的,而我们通过修改 TIM3_CCR2 则可以控制 CH2 的输出占空比。继而控制 DS0 的亮度。
配置代码:
头文件:
#ifndef __PWM_DSO_
#define __PWM_DSO_
//通过改变占空比来改变亮度
#define Pwm_value TIM3->CCR2
void Pwm_Dso_Init(void);
#endif
初始化:
#include "pwm_dso.h"
#include "sys.h"
void Pwm_Dso_Init(void) {
//1)
//开启TIM3时钟
RCC->APB1ENR |= 1<<1; //定时器3时钟使能
//配置PB5为复用输出 要先使能B时钟
RCC->APB2ENR = 1<<3; //IO端口B时钟使能
GPIOB->CRL &=0XFF0FFFFF;
GPIOB->CRL |=0X00B00000; //复用推挽输出
RCC->APB2ENR|=1<<0; //开启辅助时钟 使用了AFIO的重映射功能以及外部中断(EXTI)控制寄存器 所以要开启辅助时钟
//2)
//设置TIM3_CH2重映射到PB5上
AFIO->MAPR &= 0XFFFFFF3FF; //清除10和11位
AFIO->MAPR |= 2<<10; //FIO->MAPR|=1<<11; //部分重映像,TIM3_CH2->PB5
//3)
//设置TIM3的ARR和PSC
TIM3->ARR = 800; //重装载值
TIM3->PSC = 0; //分频系数
//4)
//设置TIM3_CH2的PWM模式
TIM3->CCER |= 1<<5;
TIM3->CCMR1&=0X8FFF;
TIM3->CCMR1|=6<<12; //CH2 PWM2模式
//5)
//使能TIM3的CH2输出,使能TIM3 CC2E:输入/捕获2输出使能
TIM3->CCER |= 1<<4; //TIM3->CCER |= 1<<4;
TIM3->CR1|= 1<<0; //使能定时器3
}
主函数:
int main(void)
{
u8 flag = 1;
u16 valus = 0;
Stm32_Clock_Init(9); //系统时钟初始化 系统时钟8MHz
uart_init(72,115200); //串口时钟初始化
LedInit();
Pwm_Dso_Init();
delay_init(72);
while(1) {
delay_ms(10);
if(flag) valus++;
else valus--;
if(valus>100) flag = 0;
if(valus == 0) flag = 1;
Pwm_value = valus;
}
}
补充:各寄存器缩写单词
PWM:Pulse Width Modulation 脉宽调制
TIMx_ARR:Automatic Reload Register 自动重装载寄存器
TIMx_CR1:Control Registor 控制寄存器1
TIMx_DIER:Interrupt Enable Register DMA/中断使能寄存器
TIMx_SR:Status Register 状态寄存器
TIMx_CCMR1/2:Capture Compare Mode Register 捕获/比较模式寄存器
TIMx_CCER:Capture Compare Enable Register 捕获/比较使能寄存器
TIMx_CCR1~4:Capture Compare Register 捕获/比较寄存器
RCC_APB1ENR:Advanced Periphery Bus Enable 外设时钟使能寄存器
AFIO_MAPR:复用重映射和调试I/O配置寄存器