首页 > 其他分享 >基于STM32的铁路自动围栏系统设计

基于STM32的铁路自动围栏系统设计

时间:2023-06-17 10:32:35浏览次数:51  
标签:ResetBits 基于 PIN void STM32 围栏 GPIOA InitStructure GPIO

一、项目背景

随着城市规模的不断扩大和交通运输方式的日益发展,铁路与公路的交叉口已经成为常见的场景。然而,这些交叉口往往存在一定的安全隐患,因为有时不易发现列车行进的情况,导致公路上的车辆或行人可能会无意中闯入铁路区域,从而引发重大交通事故。

为了解决这个问题,当前开发了一款基于STM32的铁路自动围栏系统。该系统采用了STM32F103RCT6作为主控芯片,并使用步进电机来控制铁路围栏的开启和闭合。同时,系统还配备了红外感应器,以便能够及时监测到列车的通过情况。

当系统监测到有列车即将通过铁路交叉口时,公路信号灯会立刻变为红灯,蜂鸣器也会发出警报声音,以提醒行人和车辆注意安全。同时,铁路两侧的围栏也会自动关闭,在列车通过后再次打开。这样,就能有效地防止公路车辆和行人误闯铁路区域,保障了路人的安全。

基于STM32的铁路自动围栏系统设计_铁路自动围栏系统

二、系统设计

2.1 硬件部分

STM32F103RCT6主铁路自动围栏系统的硬件部分主要包括:STM32F103RCT6主控芯片、步进电机、红外感应器、信号灯、蜂鸣器。 【1】STM32F103RCT6主控芯片是整个系统的核心,负责控制围栏的开启和闭合、监测红外感应器的状态、控制信号灯的变化以及控制蜂鸣器的报警声音。

【2】步进电机是用来控制铁路围栏的开启和闭合的设备,其动力来源为驱动芯片ULN2003。

【3】红外感应器是用来监测列车的通过情况,当感应到列车时输出高电平信号,否则输出低电平信号。

【4】信号灯则用来提示道路行人和车辆当前状态,红灯表示停止,绿灯表示通行。

【5】蜂鸣器则是用来发出报警声音,提醒行人和车辆注意安全。

2.2 软件部分

程序主要分为四部分:系统初始化、红外感应器检测、铁路围栏控制和信号灯控制。

【1】系统初始化主要是对硬件进行初始化,包括设置STM32的时钟、GPIO口的初始化等。

【2】红外感应器检测部分则是对红外感应器进行监测,当感应到列车时输出高电平信号,程序通过读取该信号实现对铁路围栏的控制和信号灯的变化。

【3】铁路围栏控制部分主要是通过对步进电机的控制来实现围栏的开启和闭合。

【4】信号灯控制部分则是通过对GPIO口的控制来实现信号灯的变化,当感应到列车时,将信号灯变为红色,否则为绿色。

三、核心代码实现

3.1 28BYJ48步进电机代码

以下是使用STM32F103RCT6驱动28BYJ-48步进电机实现正反转控制并封装成子函数调用的完整代码实现过程。

首先,需要定义相关引脚和变量:

#include "stm32f10x.h"
 
 #define IN1_PIN GPIO_Pin_0
 #define IN2_PIN GPIO_Pin_1
 #define IN3_PIN GPIO_Pin_2
 #define IN4_PIN GPIO_Pin_3
 
 GPIO_InitTypeDef GPIO_InitStructure;
 
 uint8_t step = 0;

然后,编写初始化GPIO的代码:

void init_GPIO(void)
 {
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
 
     GPIO_InitStructure.GPIO_Pin = IN1_PIN | IN2_PIN | IN3_PIN | IN4_PIN;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOA, &GPIO_InitStructure);
 }

接着,编写正转和反转函数的代码:

void forward(void)
 {
     switch(step)
     {
         case 0:
             GPIO_SetBits(GPIOA, IN1_PIN);
             GPIO_ResetBits(GPIOA, IN2_PIN | IN3_PIN | IN4_PIN);
             break;
         case 1:
             GPIO_SetBits(GPIOA, IN1_PIN | IN2_PIN);
             GPIO_ResetBits(GPIOA, IN3_PIN | IN4_PIN);
             break;
         case 2:
             GPIO_SetBits(GPIOA, IN2_PIN);
             GPIO_ResetBits(GPIOA, IN1_PIN | IN3_PIN | IN4_PIN);
             break;
         case 3:
             GPIO_SetBits(GPIOA, IN3_PIN | IN2_PIN);
             GPIO_ResetBits(GPIOA, IN1_PIN | IN4_PIN);
             break;
         case 4:
             GPIO_SetBits(GPIOA, IN3_PIN);
             GPIO_ResetBits(GPIOA, IN1_PIN | IN2_PIN | IN4_PIN);
             break;
         case 5:
             GPIO_SetBits(GPIOA, IN4_PIN | IN3_PIN);
             GPIO_ResetBits(GPIOA, IN1_PIN | IN2_PIN);
             break;
         case 6:
             GPIO_SetBits(GPIOA, IN4_PIN);
             GPIO_ResetBits(GPIOA, IN1_PIN | IN2_PIN | IN3_PIN);
             break;
         case 7:
             GPIO_SetBits(GPIOA, IN1_PIN | IN4_PIN);
             GPIO_ResetBits(GPIOA, IN2_PIN | IN3_PIN);
             break;
     }
     step++;
     if(step == 8)
     {
         step = 0;
     }
 }
 
 void backward(void)
 {
     switch(step)
     {
         case 0:
             GPIO_SetBits(GPIOA, IN1_PIN | IN4_PIN);
             GPIO_ResetBits(GPIOA, IN2_PIN | IN3_PIN);
             break;
         case 1:
             GPIO_SetBits(GPIOA, IN4_PIN);
             GPIO_ResetBits(GPIOA, IN1_PIN | IN2_PIN | IN3_PIN);
             break;
         case 2:
             GPIO_SetBits(GPIOA, IN3_PIN | IN4_PIN);
             GPIO_ResetBits(GPIOA, IN1_PIN | IN2_PIN);
             break;
         case 3:
             GPIO_SetBits(GPIOA, IN3_PIN);
             GPIO_ResetBits(GPIOA, IN1_PIN | IN2_PIN | IN4_PIN);
             break;
         case 4:
             GPIO_SetBits(GPIOA, IN2_PIN | IN3_PIN);
             GPIO_ResetBits(GPIOA, IN1_PIN | IN4_PIN);
             break;
         case 5:
             GPIO_SetBits(GPIOA, IN2_PIN);
             GPIO_ResetBits(GPIOA, IN1_PIN | IN3_PIN | IN4_PIN);
             break;
         case 6:
             GPIO_SetBits(GPIOA, IN1_PIN | IN2_PIN);
             GPIO_ResetBits(GPIOA, IN3_PIN | IN4_PIN);
             break;
         case 7:
             GPIO_SetBits(GPIOA, IN1_PIN);
             GPIO_ResetBits(GPIOA, IN2_PIN | IN3_PIN | IN4_PIN);
             break;
     }
     step--;
     if(step == -1)
     {
         step = 7;
     }
 }

最后,可以封装正转和反转函数成子函数:

void rotate_motor(int steps, int direction)
 {
     int i = 0;
     for(i = 0; i < steps; i++)
     {
         if(direction == 0)
         {
             forward();
         }
         else if(direction == 1)
     {
         backward();
     }
 }
 
 void motor_stop(void)
 {
     GPIO_ResetBits(GPIOA, IN1_PIN | IN2_PIN | IN3_PIN | IN4_PIN);
 }

最后,可以在主函数中使用这些封装好的子函数:

int main(void)
 {
     init_GPIO();
 
     // 正转200步
     rotate_motor(200, 0);
 
     // 反转100步
     rotate_motor(100, 1);
 
     // 停止电机
     motor_stop();
 
     while (1);
 }

3.2 蜂鸣器报警代码

#include "stm32f10x.h"
 #define BUZZER_GPIO_PIN GPIO_Pin_7 
 #define BUZZER_GPIO_PORT GPIOC
 
 void buzzer_init(void)
 {
     GPIO_InitTypeDef GPIO_InitStructure;
 
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
     GPIO_InitStructure.GPIO_Pin = BUZZER_GPIO_PIN;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出模式
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(BUZZER_GPIO_PORT, &GPIO_InitStructure);
 }
 
 void buzzer_on(void)
 {
     GPIO_SetBits(BUZZER_GPIO_PORT, BUZZER_GPIO_PIN); // Buzzer on
 }
 
 void buzzer_off(void)
 {
     GPIO_ResetBits(BUZZER_GPIO_PORT, BUZZER_GPIO_PIN); // Buzzer off
 }

3.3 红外感应器代码

#include "stm32f10x.h"
 #define IR_GPIO_PIN GPIO_Pin_1 
 #define IR_GPIO_PORT GPIOA
 
 void ir_init(void)
 {
     GPIO_InitTypeDef GPIO_InitStructure;
     EXTI_InitTypeDef EXTI_InitStructure;
     NVIC_InitTypeDef NVIC_InitStructure;
 
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
     GPIO_InitStructure.GPIO_Pin = IR_GPIO_PIN;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // 下拉输入模式
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(IR_GPIO_PORT, &GPIO_InitStructure);
 
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
     GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);
 
     EXTI_InitStructure.EXTI_Line = EXTI_Line1; // 对应中断线 EXTI1
     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; // 上升沿和下降沿触发
     EXTI_InitStructure.EXTI_LineCmd = ENABLE;
     EXTI_Init(&EXTI_InitStructure);
 
     NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; // 中断向量
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; // 抢占优先级2
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03; // 响应优先级3
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
     NVIC_Init(&NVIC_InitStructure);
 }
 
 void EXTI1_IRQHandler(void)
 {
     if (EXTI_GetITStatus(EXTI_Line1) != RESET)
     {
         // Do something when IR sensor detects the train
         EXTI_ClearITPendingBit(EXTI_Line1);
     }
 }

3.4 信号灯控制代码

#include "stm32f10x.h"
 #define LED_GREEN_GPIO_PIN GPIO_Pin_6 
 #define LED_GREEN_GPIO_PORT GPIOB
 #define LED_RED_GPIO_PIN GPIO_Pin_7 
 #define LED_RED_GPIO_PORT GPIOB
 
 void led_init(void)
 {
     GPIO_InitTypeDef GPIO_InitStructure;
 
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
     GPIO_InitStructure.GPIO_Pin = LED_GREEN_GPIO_PIN | LED_RED_GPIO_PIN;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出模式
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOB, &GPIO_InitStructure);
 }
 
 void led_green_on(void)
 {
     GPIO_SetBits(LED_GREEN_GPIO_PORT, LED_GREEN_GPIO_PIN); // Green LED on
 }
 
 void led_green_off(void)
 {
     GPIO_ResetBits(LED_GREEN_GPIO_PORT, LED_GREEN_GPIO_PIN); // Green LED off
 }
 
 void led_red_on(void)
 {
     GPIO_SetBits(LED_RED_GPIO_PORT, LED_RED_GPIO_PIN); // Red LED on
 }
 
 void led_red_off(void)
 {
     GPIO_ResetBits(LED_RED_GPIO_PORT, LED_RED_GPIO_PIN); // Red LED off
 }

四、总结

当前设计的这种基于STM32的铁路自动围栏系统,通过对铁路交叉口进行有效的监测和控制,实现了对过往车辆和行人的有效防护。该系统采用STM32F103RCT6作为主控芯片,使用步进电机控制铁路围栏的开启和闭合,使用红外感应器来监测列车的通过情况。在公路与铁路的交叉路口,若在远处感应到有列车即将通过,则公路信号灯变为红灯,蜂鸣器报警,铁路两侧围栏自动闭合;直至感应到列车彻底离开,公路信号灯变为绿灯,蜂鸣器关闭,围栏打开。系统具有结构简单、性能可靠等优点,在实际应用中取得了良好的效果。

标签:ResetBits,基于,PIN,void,STM32,围栏,GPIOA,InitStructure,GPIO
From: https://blog.51cto.com/u_11822586/6504582

相关文章

  • XY6762CA 4G 核心板—基于联发科MT6762(曦力 P22)平台
    XY6762CA 4G核心板采用沉金生产工艺,耐腐蚀抗干扰,支持-20℃-70℃环境下7x24小时稳定运行,尺寸仅为40.0*50.0*2.8mm,可嵌入到各种智能产品中,助力智能产品便携化及功能差异化。爆款核心板,八核智能调配采用台积电12nmFinFET制程工艺,8*Cortex-A53架构,搭载Android9.0操作系统,主频最......
  • 基于Session的认证方式
    认证流程基于Session认证方式的流程是,用户认证成功后,在服务端生成用户相关的数据保存在session(当前会话),而发给客户端的sesssion_id存放到cookie中,这样用客户端请求时带上session_id就可以验证服务器端是否存在session数据,以此完成用户的合法校验。当用户退出系统或sessi......
  • 基于uniapp+vite4+vue3搭建跨端项目|uni-app+uview-plus模板
    最近得空学习了下uniapp结合vue3搭建跨端项目。之前也有使用uniapp开发过几款聊天/仿抖音/后台管理等项目,但都是基于vue2开发。随着vite.js破局出圈,越来越多的项目偏向于vue3开发,就想着uniapp搭配vite4.x构建项目效果会如何?经过一番尝试果然真香~版本信息HBuilderX:3.8.4Vite......
  • 任务调度系统架构设计:基于缓存的改进
    目录1.引言2.技术原理及概念2.2.技术原理介绍3.实现步骤与流程4.示例与应用5.优化与改进随着互联网和信息技术的不断发展,任务调度系统已经成为了企业和个人使用的重要工具。一个高效的任务调度系统可以提高生产效率,降低人工成本,优化工作流程,提高企业竞争力。然而,传统的任务......
  • 人工智能创业投资项目案例:基于自然语言处理技术的社交媒体分析
    目录人工智能创业投资项目案例:基于自然语言处理技术的社交媒体分析随着社交媒体的不断发展和普及,越来越多的企业和个人开始通过社交媒体进行营销和宣传。社交媒体数据分析成为了现代商业中必不可少的一部分。然而,传统的方法很难精确地分析社交媒体上的用户行为和数据,而基于自......
  • 基于神经网络的大模型在图像识别中的应用
    目录1.引言2.技术原理及概念3.实现步骤与流程4.示例与应用5.优化与改进6.结论与展望随着深度学习技术的不断发展,特别是在计算机视觉领域,基于神经网络的大模型在图像识别中的应用越来越广泛。这些模型能够在处理大量图像数据的同时,准确地识别出各种物体和场景,取得了令人瞩目......
  • 基于MFCC特征提取和神经网络的语音信号识别算法matlab仿真
    1.算法仿真效果matlab2022a仿真结果如下:     2.算法涉及理论知识概要        在语音识别(SpeechRecognition)和话者识别(SpeakerRecognition)方面,最常用到的语音特征就是梅尔倒谱系数(Mel-scaleFrequencyCepstralCoefficients,简称MFCC)。根据人耳听觉机理......
  • 基于瑞丽多径信道的无线通信信道均衡算法matlab仿真,对比MMSE,ZF-DFE,MMSE-DFE
    1.算法仿真效果matlab2022a仿真结果如下: 2.算法涉及理论知识概要        信道均衡(Channelequalization)是指为了提高衰落信道中的通信系统的传输性能而采取的一种抗衰落措施。它主要是为了消除或者是减弱宽带通信时的多径时延带来的码间串扰(ISI)问题。其机理是对信道......
  • 【图像压缩】基于小波结合spiht实现图像压缩附matlab代码
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......
  • 【端点检测】基于matlab实现语音预处理+短时能量+过零率分析+端点检测
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......