如何使用STM32开发板做一个自动感应垃圾桶

一、所用到的软件和硬件

软件:
使用的KEIL 和STM32CUBE MX
STM32CUBE MX简直小白福音,如果对于STM32配置不是很清楚的话,又想尝试STM32芯片的开发的话,可以尝试使用这一个软件,这个可以想图形一样的点点就配置成功了。
硬件:
STM32F103ZET6的开发板、一个单刀单掷的继电器、一个双刀双掷的继电器、一个红外线感应模块、一个光电开关
少了一个红外线感应模块
上图少了红外线模块和光电开关

二、硬件的用途

单刀单掷的继电器:用来做一个电机电源的开关,电机一旦上电就会一直转,容易造成堵转,所以需要一个电源的开关
双刀双掷的继电器:用用来做一个电源的反转,达到电机反转的目的
红外线感应器:作为一个传感器,感应物体接近
开发板:作为处理器
电机:一上电就会一直转,所以需要断电,防止堵转太久,烧坏了

三、代码的编写和整理

引脚说明:
PA4 引脚输出 如果是高电平,单刀单掷的继电器闭合,电机电源导通
PA3 引脚输出 如果是高电平,双刀双掷的继电器闭合,电机电源反转
PA5 引脚中断 如果是高电平,进入中断
PA7 引脚中断 如果是高电平,进入中断

主函数程序

初始化完毕,在while(1)里,一直检测是否有信号输入,有信号,进入中断标志位置1。

int main(void)
{
  
  HAL_Init();

  SystemClock_Config();
  
  MX_GPIO_Init();
 
  while (1)
  {
		
		
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); //程序运行,电源打开A
		My_Delay_us(50);

		if(INR == 1) //判断有没有红外线感应,如果有,进入Deal_Infared函数,进行开关门动作
		{
			Deal_Infared();
		}
		if(SW_STA == 1) //判断有没有合上,如果合上,进去Deal_Switch,关闭电源
		{
			Deal_Switch();
		}
  
}

中断处理程序函数

在中断处理函数里,尽量不要放太多语句处理,尽量简洁一点,我这边的话是设置一个标志位,如果有信号进入就把标志位置1 如果直接在处理函数处理开门关门的操作 有可能会错过一些传感器的信号

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) //一接收到红外线感应,进入中断
{
	
	if(GPIO_Pin == GPIO_PIN_5) //判断是不是5口 红外线
 {

		My_Delay_us(10);  //延迟10us
		if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5) == SET)
		{
			INR = 1;
		}
 }
	if(GPIO_Pin == GPIO_PIN_7) //判断是不是7口  光电开关
 {

		My_Delay_us(10);  //延迟10us
		if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_7) == RESET)
		{
			SW_STA = 1;
		}
 }
}

红外线感应到的处理函数

void Deal_Infared() 			//处理红外线的函数
{
	//完成开门动作
	while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_7) == RESET ) // 这个是防止门没开起来,因为光电开关检测到位就会断电
	{
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET); 
		My_Delay_us(50);
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); //电源开启,一直开门

	}

//	INR = 0; //标志位置0,等待下次进入中断
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //电源关闭
	My_Delay_us(50);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET); 	//如果收到红外线感应模块的反馈,就电机反转,打开垃圾桶
	My_Delay_us(50);

	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); //电源开启
	HAL_Delay(3000);
	
	while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5) == SET)		//判断红外线有没有再次感应到,如果有,电源继续开着,直到没有感应到
	{
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); //电源开启			
	}
	//完成关门动作
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //电源关闭
	//My_Delay_us(50);
	HAL_Delay(500);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); 	//完成关门动作
	INR = 0; //标志位置0,等待下次进入中断

	
}

关门断电函数

void Deal_Switch(void) //定义开关函数
{
	
	while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_7) == RESET & INR != 1) //这个是检测如果关门到位,就关闭电源,防止电机堵转烧坏
	{
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); //电源开启,关门到位
		My_Delay_us(100);
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //电源关闭

	}
	SW_STA = 0;

}

四、后面的优化思路

1.这个电机正转反转是用继电器控制,接线十分繁琐,可以使用电机驱动器,使用PWM输出控制,能达到正反转的效果,也能达到控制电机的速度
2.这边的延时是HAL_DELAY,延迟就堵塞了,正常的代码一般不会使用这个,因为这样太消耗资源,如何达到延迟却不堵塞,再这个代码延迟的时候,可以去执行其他线程呢,可以加入freeRTOS系统,一般用在项目中的也是使用这个系统。
这两个我都有组装和写好代码,需要可以再发,很简易的电路,适合刚入门的人试试水。

  • 9
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值