1.使用的软件和硬件
软件:
使用的KEIL 和STM32CUBE MX
STM32CUBE MX简直是小白福音,如果是为了STM如果32配置不是很清楚,想试试STM如果开发32芯片,可以尝试使用这个软件,可以成功配置图形相同的点。
硬件:
STM32F103ZET6.开发板,单刀单掷继电器,双刀双掷继电器,红外感应模块,光电开关
上图缺少红外模块和光电开关web
2.硬件的使用
单刀单掷继电器:用作电机电源的开关。电机一旦上电,就会一直转动,容易形成堵转。因此,需要一个电源开关
双刀双掷继电器:用于电源反转,达到电机反转的目的
开发板:作为处理器
电机:一上电就会一直转动,所以要断电,防止堵转太久,烧坏svg
3.编写和整理代码
引脚说明:
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 如果直接在处理函数处理开关操作 有可能会错过一些传感器的信号ui
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) ///接收到红外感应并进入中断
{
if(GPIO_Pin == GPIO_PIN_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;
}
4、后面的优化思路
1.电机的正反转由继电器控制,接线非常繁琐,可以使用电机驱动器和使用PWM输出控制可以达到正反转和控制电机的速度
2.这里的延迟是HAL_DELAY,延迟堵塞,正常代码通常不使用这个,因为它消耗了太多的资源,如何实现延迟而不堵塞,然后代码延迟,可以执行其他线程,可以添加freeRTOS该系统通常用于项目。
我已经组装并编写了这两个代码。我必须能够重新发送它们。这是一个非常简单的电路,适合刚开始尝试水的人。spa