0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

第四章-V1.5舵机 舵机角度控制 PWM控制红外对管和按键控制 STM32驱动舵机控制 SG90控制

dfhjgfg 来源:dfhjgfg 作者:dfhjgfg 2024-08-15 16:20 次阅读

功能介绍放开头, 使用便捷无需愁。

这是全网最详细、性价比最高的STM32实战项目入门教程,通过合理的硬件设计和详细的视频笔记介绍,硬件使用STM32F103主控资料多方便学习,通过3万字笔记、12多个小时视频、20多章节代码手把手教会你如何开发和调试。让你更快掌握嵌入式系统开发。

V1.5.0-STM32智能小车

V1.5.0:库函数开发。功能:循迹、避障、跟随、遥控、电池电压显示等。

视频合集链接推荐观看

[https://www.bilibili.com/video/BV1SY411L7rJ/?spm_id_from=333.337.search-card.all.click]

**V3.3.0-STM32智能小车 **

V3:HAL库开发、功能:PID速度控制、PID循迹、PID跟随、遥控、避障、PID角度控制、视觉控制、电磁循迹、RTOS等功能。

视频合集链接推荐观看

[https://www.bilibili.com/video/BV16x4y1M7EN/?spm_id_from=333.337.search-card.all.click]

舵机控制

查看原理图

在这里插入图片描述

芯片手册

在这里插入图片描述
使用上节移植的定时器三例程
在这里插入图片描述
不需要开启部分重映射,

//GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射
TIM3_CH2- >PB5

初始化函数为

//TIM3 PWM部分初始化
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM3_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
//使能对应时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
//使能GPIO外设和AFIO复用功能模块时钟
//GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射
TIM3_CH2- >PB5
//设置该引脚为复用输出功能,输出TIM3 CH1的PWM脉冲波形 GPIOA.6
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //TIM_CH1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
//初始化TIM1
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄
存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中
指定的参数初始化TIMx的时间基数单位
//初始化TIM3 Channel1 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调
制模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比
较极性高
TIM_OC1Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC1
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR1上的预装载寄
存器
TIM_Cmd(TIM3, ENABLE); //使能TIM3
}

让舵机摇摇头

调用初始化函数和改变占空比

TIM3_PWM_Init(999,1439); //时钟源为72MHZ 故72 000 000 /1439+1)/(999+1)=50HZ
TIM_SetCompare1(TIM3,32); //舵机向右
delay_ms(900);
TIM_SetCompare1(TIM3,80); //舵机向前
delay_ms(900);
TIM_SetCompare1(TIM3,130); //舵机向左
delay_ms(900);

然后

按键与红外对管

按键外部中断实验

让我们先实现按键控制灯的亮灭

查看原理图

这里发现翻车,呜呜呜
在这里插入图片描述
由于C8T6小板子的PA12接了上拉电阻,所以使用PA12的时候要注意。而且如果我们用Mrico USB供电
可能会影响PA11。
现在我们的原理图是这样的 KEY1-PA7 KEY2-PA12
在这里插入图片描述

配置按键端口模式

通过原理图知:KEY1(PA7)应该配置成下拉输入、上升沿触发。
KEY2(PA12)应该配置成上拉输入、下降沿触发。

//按键初始化函数
void KEY_Init(void) //IO初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能PORTA时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA7设置成输入,默认下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.7
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.12
}

配置中断线和配置外部通道

//KEY外部中断服务程序
void KEY_EXTIX_Init(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
KEY_Init(); // 按键端口初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟
//GPIOA.7 中断线以及中断初始化配置 上升沿触发 PA7 KEY_1
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource7); //选择GPIO引脚作为
中断线
EXTI_InitStructure.EXTI_Line=EXTI_Line7; //线路选择
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //事件选择
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //触发模式 上升沿触发
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设
EXTI寄存器
//GPIOA.5 中断线以及中断初始化配置 下降沿触发PA12 KEY_2
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource12);
EXTI_InitStructure.EXTI_Line=EXTI_Line12;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设
EXTI寄存器
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //使能按键KEY1所在
的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; //子
优先级1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设
NVIC寄存器
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //使能按键KEY0
所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; //子
优先级0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设
NVIC寄存器
}

相关宏定义 读取按键状态

#define KEY_1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)//读取按键KEY_1
#define KEY_2 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_12)//读取按键KEY_2

编写响应中断函数

void EXTI9_5_IRQHandler(void)//按键KEY_1 和KEY_2的中断服务函数
{
delay_ms(10);//消抖
if(KEY_1 == 1) //判断按键KEY_1 是否被按下
{
LED =! LED;
EXTI_ClearITPendingBit(EXTI_Line7); //清除LINE7上的中断标志位
}
}
void EXTI15_10_IRQHandler(void)//按键KEY_SW1 和KEY_SW2的中断服务函数
{
delay_ms(10);//消抖
if(KEY_2 == 0) //判断按键KEY_2 是否被按下
{
LED =! LED;
EXTI_ClearITPendingBit(EXTI_Line12); //清除LINE7上的中断标志位
}
}

调用初始化函数

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先
级,2位响应优先级
//如果没有设置中断优先级分组要先设置
KEY_EXTIX_Init(); //初始化外部中断输入

烧录调试

观察现象

红外对管硬件使用方法

详见:系统硬件设计->红外循迹模块
可以把红外对管看成'按键',当前面有黑色时候为高电平,前面白色低电平。

红外对管的驱动

红外对管这里使用查询的方式,通过GPIO_ReadInputDataBit(GPIO_TypeDef GPIOx, uint16_t *
GPIO_Pin)函数获得对应端口的电平
查看原理图 红外对管依次连接 PB5 、PB4 、PB3 、PA15
在这里插入图片描述

红外管GPIO初始化

注意:这里我们需要使用的PB3、PB4、PA15是单片机的'特殊引脚
我们打开数据手册:STM32F103x8B_DS_CH_V10,在引脚定义章节,说明了复位后的主功能和默认复
用功能以及重定义功能。
在这里插入图片描述
在参考手册:STM32中文参考手册_V10, 在8.3.5 JTAG/SWD复用功能重映射中,说明了引脚使用
在这里插入图片描述
所以我们需要关闭JTAG-DP 启用SW-DP ,我们重映射配置应写为

GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
//红外循迹TCRT5000初始化函数
void TCRT5000_Init(void) //IO初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);//使
能PORTA,PORTB时钟
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
//重映射配置关闭JTAG-DP 启用SW-DP从而可以使用PA15 PB3 PB4
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA15 设置成下拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.15
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_4|GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // 设置成下拉输入
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB 5 4 3
}

一些宏定义,利用函数读取电平

#define HW_1 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5)//读取 PB5 电平
#define HW_2 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_4)//读取 PB4
#define HW_3 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_3)//读取 PB3
#define HW_4 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)//读取 PA15

调用初始化函数

TCRT5000_Init();

红外对管控制小灯

while(1){
if(HW_1 == 1 && HW_2==0 && HW_3 == 1 && HW_4 == 0 )//当第一个和第三
个前面是黑色时候板子小灯亮,其他情况板子小灯灭
{
LED =0;
}
else{
LED =1;
}
}

练一练--红外对管循迹

while(1)
{
if(HW_1 == 0 && HW_2 == 0 && HW_3 == 0 && HW_4 == 0)
{
Forward();
delay_ms(50);
}
if(HW_1 == 0 && HW_2 == 1 && HW_3 == 0 && HW_4 == 0)
{
Rightward();
delay_ms(150);
}
if(HW_1 == 1 && HW_2 == 0 && HW_3 == 0 && HW_4 == 0)
{
Rightward();
delay_ms(250);
}
if(HW_1 == 1 && HW_2 == 1 && HW_3 == 0 && HW_4 == 0)
{
Rightward();
delay_ms(300);
}
if(HW_1 == 0 && HW_2 == 0 && HW_3 == 1 && HW_4 == 0)
{
Leftward();
delay_ms(150);
}
if(HW_1 == 0 && HW_2 == 0 && HW_3 == 0 && HW_4 == 1)
{
Leftward();
delay_ms(250);
}
if(HW_1 == 0 && HW_2 == 0 && HW_3 == 1 && HW_4 == 1)
{
Leftward();
delay_ms(300);
}
}

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • STM32
    +关注

    关注

    2253

    文章

    10751

    浏览量

    351433
  • PWM控制
    +关注

    关注

    7

    文章

    189

    浏览量

    26135
  • SG90
    +关注

    关注

    0

    文章

    9

    浏览量

    11477
收藏 人收藏

    评论

    相关推荐

    51控制SG90舵机的电源问题

    用51控制SG90舵机节干电池供电,出现电压不足问题,程序跑乱,请问这要怎么解决呀?
    发表于 04-14 11:54

    如何利用51单片机去控制SG90舵机

    SG90舵机是如何进行接线的?SG90舵机旋转的角度有哪几种?如何利用51单片机去控制
    发表于 07-29 07:50

    STM32 CubeIDE 模拟舵机sg90控制 精选资料分享

    ,比如sg90,不带限位,如果控制不合理,那么就会出现旋转360的结果。使用sg90舵机测试,这个舵机的三根线分别为:GND(棕色)、VCC
    发表于 08-10 06:15

    控制舵机SG90的教程

    目录前言一、SG90舵机二、CubeMax配置1.选型2.配置时钟树3.PWM相关定时器配置4.生成代码三、代码编写总结前言这是一篇基于STM32F429的保姆级入门的用CubeMAX
    发表于 08-10 06:05

    如何去实现基于STM32F103ZET的SG90舵机控制

    什么是SG90舵机?模拟舵机与数字舵机有哪些区别呢?如何去实现基于STM32F103ZET的SG90
    发表于 11-19 07:27

    如何使用stm32Cubemx软件配置PWM控制SG90舵机角度

    如何使用stm32Cubemx软件配置PWM控制SG90舵机角度
    发表于 12-02 06:45

    如何利用STM32F103控制SG90舵机

    如何利用STM32F103控制SG90舵机
    发表于 12-14 07:18

    如何使用stm32Cubemx软件配置PWM控制SG90舵机角度

    stm32Cubemx(一):PWM控制SG90舵机本章将介绍使用stm32Cubemx软件配置
    发表于 01-21 08:00

    STM32驱动SG90舵机的方法

    的,实际上在某宝购买的时候360°、180°、90°的SG90都叫这个名字,如果你真的不懂的话,选购之前最好是问问客服可以旋转多少度。杜邦线若干。2.接线方法主要是SG90舵机的三根线
    发表于 02-21 06:54

    STM32控制SG90舵机的方法步骤

    STM32控制SG90舵机 在这篇博客中,我讲解的是SG90的180°型号的舵机。其它型号的
    发表于 02-21 07:21

    STM32—TIM3输出PWM信号驱动MG996R舵机按键控制

    MG996R舵机按键控制。相关知识:TIM定时器基本原理,TIM输出PWM信号、MG996R舵机驱动原理二、MG996R
    发表于 11-23 18:21 57次下载
    <b class='flag-5'>STM32</b>—TIM3输出<b class='flag-5'>PWM</b>信号<b class='flag-5'>驱动</b>MG996R<b class='flag-5'>舵机</b>(<b class='flag-5'>按键控制</b>)

    STM32控制SG90舵机教程(180度和360度)

    规定的要求进行的速度进行转动。数字舵机在反应速度方面与模拟舵机相比是由优势的。因为数字舵机是拥有微处理器。下面我们介绍的SG90舵机就是模拟
    发表于 11-30 14:21 25次下载
    <b class='flag-5'>STM32</b><b class='flag-5'>控制</b><b class='flag-5'>SG90</b><b class='flag-5'>舵机</b>教程(180度和360度)

    STM32驱动SG90舵机

    的,实际上在某宝购买的时候360°、180°、90°的SG90都叫这个名字,如果你真的不懂的话,选购之前最好是问问客服可以旋转多少度。杜邦线若干。2.接线方法主要是SG90舵机的三根线
    发表于 12-24 19:24 47次下载
    <b class='flag-5'>STM32</b><b class='flag-5'>驱动</b><b class='flag-5'>SG90</b><b class='flag-5'>舵机</b>

    STM32控制舵机的方法及实例

    STM32控制SG90舵机 在这篇博客中,我讲解的是SG90的180°型号的舵机。其
    发表于 12-24 19:30 127次下载
    <b class='flag-5'>STM32</b><b class='flag-5'>控制</b><b class='flag-5'>舵机</b>的方法及实例

    pwm控制SG90舵机资料分享

    pwm控制SG90舵机资料分享
    发表于 07-10 09:22 30次下载