江科大 STM32入门教程 P16 PWM驱动LED&舵机&直流电机
2023-12-20 07:53:56
1 PWM驱动LED
1.1 接线图
1.2 PWM通路初始化步骤
- RCC开启时钟(打开TIM外设时钟和RCC外设时钟)
- 配置时基单元(时钟源原选择)
- 配置输出比较单元(ccr\输出比较模式、极性选择、输出使能)
- 配置GPIO(复用)
- 运行控制(启动计数器)
1.3 PWM库
void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
配置输出比较模块的库函数(oc:ouput compare)
void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);//
void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
//配置强制输出模式
void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
配置CCR寄存器的预装功能(也是影子寄存器,在写入不会立即生效,而是出发事件后才会生效)
void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
//配置快速使能的
void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
//外部事件时清除REF信号
void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
//单独设置输出比较的极性,带N就是高级定时器互补通道的配置
void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx);
void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN);
//单独修改输出使能参数
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);
//单独更改CCR寄存器值的函数
1.4 初始化代码实现
- PWM.C程序
#include "stm32f10x.h" // Device header
void PWM_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//GPIO复用功能推挽输出
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; //选择要调用的GPIOpin口
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
TIM_InternalClockConfig(TIM2);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period = 100-1;//周期的值ARR
TIM_TimeBaseInitStruct.TIM_Prescaler = 720-1;//预分频器的数值
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
//初始化输出比较单元
TIM_OCInitTypeDef IM_OCInitStruct;
TIM_OCStructInit(&IM_OCInitStruct);//给结构体变量成员赋初始值,再修改部分的结构体成员
IM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1 ;//设计输出比较的模式
IM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;//设置输出比较的极性
IM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;//设置输出使能
IM_OCInitStruct.TIM_Pulse = 0; //设置CCR捕获比较寄存器的数值
TIM_OC1Init(TIM2,&IM_OCInitStruct);
TIM_Cmd(TIM2,ENABLE);
}
void PWM_SetCompare1(uint16_t Compare)//设置CCR的数值由之前的固定值变成动态值 uint16 范围0到2^16;
{
TIM_SetCompare1(TIM2,Compare);
}
- PWM.h程序
#ifndef __PWM_H
#define __PWM_H
void PWM_Init(void);
void PWM_SetCompare1(uint16_t Compare);
#endif
3.main.程序
#include "stm32f10x.h" // Device header
#include "LED.h"
#include "PWM.h"
#include "OLED.h"
#include "Delay.h"
uint8_t i;
int main()
{
OLED_Init();
PWM_Init();
while(1)
{
for(i = 0;i<=100;i++)//IED由0到100,逐渐变亮
{
PWM_SetCompare1(i);//设置CCR寄存器的值
Delay_ms(10);
}
for(i = 0;i<=100;i++)//IED由100到0,逐渐变暗
{
PWM_SetCompare1(100-i);
Delay_ms(10);
}
}
}
效果:呼吸灯由亮变暗,由暗变亮;
这里输出的用PA1口的通道2
补充:引脚重映射功能
例子:TIM2_CH1_Enable的功能可以从PA0映射到PA15引脚上,这里需要使用GPIO的AFIO功能,如何使用AFIO功能?
- 开启AFIO寄存器挂载在总线上,开启总线时钟;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//AFIO是APB2的设备,
2.打开GPIO.h的库函数进行查找
void GPIO_PinRemapConfigure();//引脚重新配置映射函数
2 PWM驱动舵机
2.1 接线图
PWM输出通道接到PA1的引脚上;
在PB1接一个按键用来控制舵机;
2.2 代码实现
3 直流电机
include "stm32f10x.h" // Device header
void PWM_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//GPIO复用功能推挽输出
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2; //选择要调用的GPIOpin口
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
TIM_InternalClockConfig(TIM2);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period = 100-1;//周期的值ARR
TIM_TimeBaseInitStruct.TIM_Prescaler = 720-1;//预分频器的数值
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
//初始化输出比较单元
TIM_OCInitTypeDef IM_OCInitStruct;
TIM_OCStructInit(&IM_OCInitStruct);//给结构体变量成员赋初始值,再修改部分的结构体成员
IM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1 ;//设计输出比较的模式
IM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;//设置输出比较的极性
IM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;//设置输出使能
IM_OCInitStruct.TIM_Pulse = 0; //设置CCR捕获比较寄存器的数值
TIM_OC3Init(TIM2,&IM_OCInitStruct);
TIM_Cmd(TIM2,ENABLE);
}
void PWM_SetCompare3(uint16_t Compare)
{
TIM_SetCompare3(TIM2,Compare);
}
#ifndef __PWM_H
#define __PWM_H
void PWM_Init(void);
void PWM_SetCompare3(uint16_t Compare);
#endif
#include "stm32f10x.h" // Device header
#include "LED.h"
#include "Motor.h"
#include "OLED.h"
#include "Delay.h"
#include "Key.h"
uint8_t i;
uint8_t KeyNum;
int8_t speed;
int main()
{
OLED_Init();
Motor_Init();
Key_Init();
OLED_ShowString(1,1,"Speed:");
while(1)
{
KeyNum = Key_GetNum();
if(KeyNum == 1)
{
speed+=20;
if(speed > 100)
{
speed = -100;
}
}
Motor_SetSpeed(speed);
OLED_ShowSignedNum(1,7,speed,3);
}
}
文章来源:https://blog.csdn.net/CScodemini/article/details/134955914
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!