STM32 控制超声波 舵机

本文详细介绍了如何使用GPIO初始化超声波测距和舵机控制。通过设置GPIO模式,初始化TIM定时器,实现超声波发送触发信号、接收回波并计算距离。同时,利用PWM信号控制舵机角度,通过TIM4定时器设置高电平和低电平时间来调整舵机转动。内容涵盖了嵌入式硬件和控制技术的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.初始化GPIO

设置Trig引脚GPIO的输出模式为推挽输出
设置Echo引脚GPIO的输入模式为浮空输入
并打开相应GPIO的时钟
	GPIO_InitTypeDef GPIO_InitStructure;
	
  /* Configure TRIG Button */
  RCC_APB2PeriphClockCmd(RCC_TRIG, ENABLE);

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //设置成推挽输出
  GPIO_InitStructure.GPIO_Pin = GPIO_TRIG_Pin;      //配置TRIG 的引脚是1
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	  
  GPIO_Init(GPIO_TRIG_PORT, &GPIO_InitStructure);   //端口  B
 
  /* Configure ECHO Button */
  RCC_APB2PeriphClockCmd(RCC_ECHO, ENABLE);

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   //模式设置成浮空输入
  GPIO_InitStructure.GPIO_Pin = GPIO_ECHO_Pin;
  GPIO_Init(GPIO_ECHO_PORT, &GPIO_InitStructure);

2.初始化TIM定时器

使用定时器进行超声波时间的取值 距离等于时间✖速度
初始化完成TIM定时器后,先不使用定时器 在进行超声波进行测量距离的时候进行使用

  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

  /* 开启定时器3的时钟*/
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);   
  
  //定时时间 1us   计数一次
  /* Time base configuration */
  //这个就是自动装载的计数值,计数器的值从零开始
  TIM_TimeBaseStructure.TIM_Period = 65535;  //计数值记一次 1us
  // 这个就是预分频系数,当由于为0时表示不分频所以要减1
  TIM_TimeBaseStructure.TIM_Prescaler = (72 - 1);
  // 高级应用本次不涉及。定义在定时器时钟(CK_INT)频率与数字滤波器(ETR,TIx)
  // 使用的采样频率之间的分频比例
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  //向上计数
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  //初始化定时器3
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

  TIM_ClearFlag(TIM3, TIM_FLAG_Update);							    		/* 清除溢出中断标志 */
  //  TIM_Cmd(TIM3, ENABLE);  //计数器使能,开始工作  先关闭时钟  等待使用

3.超声波的使用

首先使用Trig发送10us的触发信号 高电平
然后等待Echo 当产生高电平的时候打开计数器开始计数
继续等待Echo 当产生低电平的时候关闭定时器
使用TIM_GetCounter(TIM3)得到定时器的计数值 记了多少个数 一个数是1us
通过使用记录多少个数 进行计算

void ChaoShengBo_Dis(void)
{
  GPIO_SetBits(GPIO_TRIG_PORT,GPIO_TRIG_Pin); 		  //送>10US的高电平
  DelayTime_us(20);		                      //延时20US 也可以是10us
  GPIO_ResetBits(GPIO_TRIG_PORT,GPIO_TRIG_Pin);
  //*************************************************************
	//我们等待的是高电平   因此最开始一直是低电平  当高电平到来时  不满足==reset
  while(GPIO_ReadInputDataBit(GPIO_ECHO_PORT,GPIO_ECHO_Pin) ==RESET);	             //等待高电平
  TIM_Cmd(TIM3, ENABLE);                                             //开启时钟
	//我们等待的是低电平  检测电平  不是低电平  满足  是低电平不满足  等待
  while(GPIO_ReadInputDataBit(GPIO_ECHO_PORT,GPIO_ECHO_Pin) !=RESET);	                 //等待低电平
  TIM_Cmd(TIM3, DISABLE);			                                 //定时器2失能
  UltrasonicWave_Distance=TIM_GetCounter(TIM3)*170/10000;		     //计算距离					 //计算距离
  TIM_SetCounter(TIM3,0);
}

舵机的使用

舵机通过使用PWM信号进行角度的控制
我们使用定时器4进行舵机时间的控制
使用定时器4 的通道1 PB6
将PB6的设置成推挽输出 进行PWM的控制
介绍定时器的使用

	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	
	//开时钟    打开定时器4的时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
	//设置的是一个周期计数20000次
	TIM_TimeBaseStructure.TIM_Period = 20000-1;
	//设置技术一次使用1us
	TIM_TimeBaseStructure.TIM_Prescaler = 72-1;
	//设置计数方式为向上计数
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	//时钟分频因子 默认
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	//重复计数值   只存在于高级定时器 
	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
	//初始化时基结构体
	TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);
  /*        输出比较结构体初始化                */
	TIM_OCInitTypeDef TIM_OCInitStructure;
	//设置输出模式为PWM1模式   PWM1
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	//配置输出使能
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	//设置输出极性的极性   PWM1模式下一般设置输出极性为高
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OC1Init(TIM4,&TIM_OCInitStructure);
	//使能通道1  *****
	TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable);
	
	//使能定时器
	TIM_Cmd(TIM4,ENABLE);

使用PWM进行生成
舵机旋转
使用TIM_SetCompare1()函数 设置高电平和低电平的时间
void TIM_SetCompare1(TIM_TypeDef* TIMx, u16 Compare1)
函数的第二个值表示的是前面一段的时间 最开始的时间
当使用的是低电平有效的时候看到的图是 先低电平后高电平
当使用的是高电平有效的时候看到的图 先高电平然后低电平
我们使用 设置低电平有效 使用函数 将Compare设置成19000
计算的出低电平和高电平之比为0.95
换算19000/20000 等于0.95
在这里插入图片描述
因此进行设计 自行输入旋转多少度
舵机旋转的时候高电平有效 通过控制高电平的时间进行控制

void duoji_angle_Init(float angle)
{
	uint16_t i;
	if(angle<5){
		angle=5;
	}
	if(angle>175){
		angle=175;
	}
	i=(uint16_t)(11.111*angle);
	TIM_SetCompare1(TIM4,500+i);
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值