[STM32]PWM驱动舵机
思路
1.用PB5输出脉冲信号 2. 了解PWM的原理 3. 了解舵机相关设置 4. 敲代码改bug
相关硬件
STM32C8T6最小系统板
SG90舵机
Jlink
杜邦线
相关知识
舵机
高电平时间对应舵机转动角度
t = 0.5ms——————-舵机会转到 0 ° t = 1.0ms——————-舵机会转到 45° t = 1.5ms——————-舵机会转到 90° t = 2.0ms——————-舵机会转到 135° t = 2.5ms——————-舵机会转到 180°
硬件
橙线:信号线 红线:电源,可以连接3.3V 棕线:地线 SG90舵机地线接32系统板地线,电源接单片机3V3 信号线接预设输出PWM的IO口
代码
file:main
#include "system.h"
#include "SysTick.h"
#include "pwm.h"
#include "../1127.h"
int main(void)
{
u8 fx=1;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
TIM3_CH2_PWM_Init(200-1,7200-1);
while(1)
{
if(fx==1)
{
i+=5;
}
else
{
i-=5;
}
if(i>=25) fx=0;
if(i==5) fx=1;
delay(1000);
LED=!LED;
TIM_SetCompare2(TIM3,i);
}
}
file pwm.c
1.头文件以及配置定时器中断服务
#include "pwm.h"
#include "../1127.h"
u8 i =5;
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update );
i++;
}
}
2.初始化函数
void TIM3_CH2_PWM_Init(u16 per,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOB,&GPIO_InitStructure);
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOC,&GPIO_InitStructure);
GPIO_ResetBits(GPIOC,GPIO_Pin_13);
TIM_TimeBaseInitStructure.TIM_Period=per;
TIM_TimeBaseInitStructure.TIM_Prescaler=psc;
TIM_TimeBaseInitStructure.TIM_ClockDivision=0;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
TIM_OC2Init(TIM3,&TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM3,ENABLE);
TIM_Cmd(TIM3,ENABLE);
}
file: 11.27.h
#ifndef __1127_H__
#define __1127_H__
void TIM3_CH2_PWM_Init(unsigned short per,unsigned short psc);
void SysTick_Init(unsigned char SYSCLK);
void delay(unsigned short nms);
extern unsigned char i;
#define LED PCout(13)
#endif
PWM模式相关函数(TIMx_OClnit)
结构体
typedef struct
{
uint16_t TIM_OCMode;
uint16_t TIM_OutputState;
uint32_t TIM_Pulse;
uint16_t TIM_OCPolarity;
}TIM_OCInitTypeDef;
解释: OCMode 输出模式: PWM1:ARR<CCRx,输出有效电平 PWM2:ARR<CCRx,输出无效电平
OCPolarity 输出极性: High:高电平有效 Low:低电平有效 [相关寄存器:TIMx_CCER:CCxP,x与CHx有关]
OCOutputState:比较输出使能 应该是为了用TIM_SetComparex(TIMx,i) Enable:输出使能 Disable:输出失能
OCPulse 占空比: 与设置TIM_SetComparex(TIMx,i)的i应该是一样的
【注释掉的是高级定时器才会用到的,这里不解释】
其他函数
复用功能相关函数
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState) ;
GPIO的复用功能与重映射功能
定时器复用功能对照表
其中部分重映像(比如TIM2)不同时,uint32_t GPIO_Remap会出现不同: PartialRemap1:01时的IO口 PartialRemap2:10时的IO口
void TIM_SetComparex(TIM_TypeDef* TIMx, uint32_t Compare1);
调某通道节占空比函数
对于其他通道,分别有对应的函数名(x=1、2、3、4)
1. void TIM_OCxPreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
使能 TIMx 在 CCRx 上的预装载寄存器
第一个参数用于选择定时器, 第二个参数用于选择使能还是失能输出比较预装载寄存器,可选择为 TIM_OCPreload_Enable、TIM_OCPreload_Disable。
1. void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
使能 TIMx 在 ARR 上的预装载寄存器允许位
第一个参数用于选择定时器, 第二个参数用于选择使能还是失能。
实验失败解决记录
1.复用特定IO口时无法输出:需要禁用(先看2)
《STM32F103禁用JTAG和SWD接口》
2.禁用特定IO口导致无法烧录
(自己的方法,有效但不知道哪一步有效) 将系统板的BOOT0由0变为1(boot1=0),就能检测到SWD,然后如图设置Erase Full Chip download一个正常的程序,加了一个 GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, DISABLE);【当时就是用了GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, DISABLE)导致无法下载,慎用!】 boot0=0,能够正常烧录!
3.ZET改C8T6
1.启动文件将.hd改为.md 2.Device:ZET->C8
3.C/C++:USE_STDPERIPH_DRIVER
参考
普中,正点原子,野火相关视频,ppt,代码
|