在此之前我们学习stm32单片机时一般就初始化一下舵机的模块,根据设置PWM的占空比就可以控制舵机的转动,
但是在移植完UCOSIII后再用以前直接控制PWM占空比的方法显然行不通,所以以下便是我利用 “信号量” 的方法控制舵机的转动
首先初始化PWM引脚的初始化和定时器的相关初始化(与之前学习相关的模块的初始化是一样的)
static TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
static TIM_OCInitTypeDef TIM_OCInitStructure; //配置占空比
static uint32_t g_pwm_cnt=0;
void Init_PA6_LED_PWD_init(void)//PWM引脚连接初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 1.使能对应GPIO的RCC时钟 */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* 2.配置GPIO并初始化(PF9) */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //引脚号
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //输出速率(功耗)
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//无上下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 将定时器连接到复用引脚 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3); //PA6连接到定时器3
}
//定时器相关初始化
void tim3_pwm_init(void)
{
//使能定时器3时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
//配置定时器3分频值、计数值等
TIM_TimeBaseStructure.TIM_Period = (10000/50)-1; //计数值0~199 ,决定定时时间 当前输出频率为200HZ //(20000/100)-1
TIM_TimeBaseStructure.TIM_Prescaler = 8400-1; //预分频值 8400-1+1 = 8400 进行8400的预分频值 //4200-1
//TIM_TimeBaseStructure.TIM_ClockDivision = 0; //时钟分频 在f407中不支持
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数模式 -->向上计数
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
g_pwm_cnt = TIM_TimeBaseStructure.TIM_Period;
//配置引脚通道(通道1工作在PWM1模式)
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //打开/关闭脉冲输出
//TIM_OCInitStructure.TIM_Pulse = 50; //比较值 (0~99,占空比为50高电平50低电平,为90,则0~90高电平,91到99为低电平)
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //有效状态为高电平,无效状态为低电平
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
/* 使能定时器14 */
TIM_Cmd(TIM3, ENABLE);
}
//舵机旋转角度封装
void sg_angle(uint32_t angle)
{
if(angle==0)
TIM_SetCompare1(TIM3,(uint32_t)(0.5 * g_pwm_cnt/20)); //设置占空比
if(angle==45)
TIM_SetCompare1(TIM3,(uint32_t)(g_pwm_cnt/20));
if(angle==90)
TIM_SetCompare1(TIM3,(uint32_t)(1.5*g_pwm_cnt/20));
if(angle==135)
TIM_SetCompare1(TIM3,(uint32_t)(2*g_pwm_cnt/20));
if(angle==180)
TIM_SetCompare1(TIM3,(uint32_t)(2.5*g_pwm_cnt/20));
}
然后再初始化各功能模块的时候再创建一个信号量如下图
我是暂时利用一个全局变量接收到串口发送过来的数据,然后再根据串口发送过来的数据根据信号量申请共享资源设置相关的舵机旋转角度的
释放完资源后要重新给这个全局变量赋初值为0,“临界区”一般适合用来给变量赋值操作还有看门狗相关操作
最后下面给一个小延时,1S钟,否则舵机转动不起来
可能会有一些问题欢迎大家改错