打印
[STM32F1]

STM32——基础篇 PWM实验

[复制链接]
1158|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
上次我们学习了STM32 的通用定时器 TIM3,用该定时器来定时控制LED 循环点亮的实验,这次我们将利用 TIM3 的通道 2,把通道 2 完全重映射到 PC7管脚, 产生 PWM 来控制LED灯的亮度。本次实验目标:
1、学会配置 STM32 的定时器。
2、学会配置定时器输出 PWM。

沙发
aizaixiyuanqian|  楼主 | 2017-12-10 22:09 | 只看该作者
1  PWM 简介
脉冲宽度调制(PWM),是英文“ Pulse Width Modulation” 的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一非常有效的技术。简单一点,就是对脉冲宽度的控制。

使用特权

评论回复
板凳
aizaixiyuanqian|  楼主 | 2017-12-10 22:11 | 只看该作者
STM32 的定时器除了 TIM6 和 7。其他的定时器都可以用来产生 PWM 输出。其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路PWM 输出。而通用定时器也能同时产生多达 4路的 PWM 输出,这样, STM32 最多可以同时产生 30 路 PWM 输出!这里我们仅利用TIM3CH2产生一路 PWM 输出。如果要产生多路输出,可以根据我们的代码稍作修改即可。了解了定时器 TIM3 的 PWM原理之后,我们来学习使库函数产生 PWM 输出。

使用特权

评论回复
地板
aizaixiyuanqian|  楼主 | 2017-12-10 22:14 | 只看该作者
我们要利用 TIM3 的 CH2 输出 PWM 来控制 LED 的亮度,但是 TIM3_CH2 默认是接在PA7 上面的,而我们的 LED 接在 PC7 上面,如果普通MCU,可能就只能用飞线把 PA7 飞到 PC7上来实现了,不过,我们用的是 STM32,它比较高级,可以通过重映射功能,把 TIM3_CH2映射到 PC7 上。STM32 的重映射控制是由复用重映射和调试 IO 配置寄存器( AFIO_MAPR)控制的,该寄存器的各位描述如图所示:


使用特权

评论回复
5
aizaixiyuanqian|  楼主 | 2017-12-10 22:16 | 只看该作者
默认条件下, TIM3_REMAP[1:0]为 00,是没有重映射的,所以 TIM3_CH1~TIM3_CH4 分别是接在 PA6、 PA7、 PB0 和 PB1 上的,而们想让 TIM3_CH2 映射到 PC7 上, 则需要设置 TIM3_REMAP[1:0]=11,即完全重映射,此时 TIM3_CH1 也被映射到 PC6了要实现通过重映射 TIM3_CH2到 PC7 上,由 TIM3_CH2 输出 PWM 来控制LED 的亮度。下面我们通过库函数来配置该功能。




使用特权

评论回复
6
aizaixiyuanqian|  楼主 | 2017-12-10 22:19 | 只看该作者
PWM 库函数配置步骤
1) 开启 TIM3  时钟以及复用功能时钟,配置 PC7  为复用输出 。
2)  设置 TIM3_CH2  重映射到 PB5  上 。
3)  初始化 TIM3, 设置 TIM3  的 ARR  和 PSC 。
4) 设置 TIM3_CH2  的 PWM  模式,使能 TIM3  的 CH2  输出。
5)   使能 TIM3 。
6)  修改 TIM3_CCR2  来控制占空比 。




使用特权

评论回复
7
aizaixiyuanqian|  楼主 | 2017-12-10 22:21 | 只看该作者
1) pwm初始化函数
void pwm_init()
{
GPIO_InitTypeDef GPIO_InitStructure; //初始化 GPIO
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//初始化定时器
TIM_OCInitTypeDef TIM_OCInitStructure;//根据 TIM_OCInitStruct 中指定的参数初始化外设 TIMx
/* 开启时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
/* 配置 GPIO 的模式和 IO 口 */
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
GPIO_Init(GPIOC,&GPIO_InitStructure);//TIM3 定时器初始化
TIM_TimeBaseInitStructure.TIM_Period = 899; //设置自动重装载寄存器周期的值
TIM_TimeBaseInitStructure.TIM_Prescaler = 0;//设置用来作为 TIMx 时钟频率预分频值,100Khz 计数频率
TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;//设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM 向上计数模式
TIM_TimeBaseInit(TIM3, & TIM_TimeBaseInitStructure);
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);//改变指定管脚的映射
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//PWM输出使能
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;
TIM_OC2Init(TIM3,&TIM_OCInitStructure);//注意此处初始化时 TIM_OC2Init
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能或者失能
TIMx 在 CCR2 上的预装载寄存器
TIM_Cmd(TIM3,ENABLE);//使能或者失能 TIMx 外设
}

使用特权

评论回复
8
aizaixiyuanqian|  楼主 | 2017-12-10 22:25 | 只看该作者
本帖最后由 aizaixiyuanqian 于 2017-12-10 22:26 编辑

主函数呼吸灯调用部分。
int main()
{
u8 fu=1;u32 time=0;
pwm_init();  //PWM 初始化
while(1)
{
delay_ms(10);
if(fu==1)
{
time++;
if(time>300)
{
fu=0;
}
}
else
{
time--;
if(time==0)
{
fu=1;
}
}
TIM_SetCompare2(TIM3, ti);//设置 TIMx 捕获比较 2 寄存器值
}
}

使用特权

评论回复
9
aizaixiyuanqian|  楼主 | 2017-12-10 22:27 | 只看该作者
pwm就先到了这里吧,到了后面综合实验我们在拿来研究。

使用特权

评论回复
10
aizaixiyuanqian|  楼主 | 2017-12-10 22:27 | 只看该作者
欢迎大家来学习指正。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

62

主题

1353

帖子

6

粉丝