第四章-V1.5舵机 舵机角度控制 PWM控制红外对管和按键控制 STM32驱动舵机控制 SG90控制 超声波支架 STM32智能小车 舵机控制 江科大同款笔记单片机笔记嵌入式课程STM32嵌入式控制

当前视频版本V1.5.0
现在有两个版本小车
V1.5.0-STM32智能小车
视频链接:

[stm32入门教程][STM32实战项目]STM32智能小车V1.5-stm32f103c8t6-stm32最小系统-手把手入门教程-嵌入式开发-嵌入式学习

V3.3.0-STM32智能小车
视频链接

STM32智能小车V3-STM32入门教程-openmv与STM32循迹小车-stm32f103c8t6-电赛 嵌入式学习 PID控制算法 编码器电机 跟随

介绍:
V1.5.0:库函数开发。功能:循迹、避障、跟随、遥控、电池电压显示等。
V3:HAL库开发、功能:PID速度控制、PID循迹、PID跟随、遥控、避障、PID角度控制、视觉控制。

舵机控制

查看原理图

在这里插入图片描述

芯片手册

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

//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);
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值