STM32实现简单的智能停车场收费

以下是一个基于STM32的简单智能停车场收费系统的代码案例。本案例主要涉及到STM32的外设使用、中断处理以及串口通信等方面。

  1. 硬件准备:
  • STM32开发板(本案例以STM32F103为例)
  • 1602液晶显示屏模块
  • 红外传感器模块
  • 数码管显示模块
  • 扩展按键模块
  • 其他所需电子元件和线路连接
  1. 软件准备:
  • Keil MDK开发环境
  • STM32 HAL库
  1. 连接硬件: 将1602液晶显示屏模块、红外传感器模块、数码管显示模块和扩展按键模块与STM32开发板连接,具体连接方式可参考各个模块的datasheet。

  2. 编写代码: 下面是一个简单的智能停车场收费系统的代码案例:

#include "stm32f1xx_hal.h"
#include "stdio.h"

// 定义红外传感器GPIO口
#define IR_SENSOR_GPIO GPIOA
#define IR_SENSOR_PIN GPIO_PIN_0

// 定义数码管显示GPIO口
#define SEGMENT_DISPLAY_GPIO GPIOB
#define SEGMENT_DISPLAY_PIN1 GPIO_PIN_0
#define SEGMENT_DISPLAY_PIN2 GPIO_PIN_1
#define SEGMENT_DISPLAY_PIN3 GPIO_PIN_2
#define SEGMENT_DISPLAY_PIN4 GPIO_PIN_3

// 定义扩展按键GPIO口
#define EXT_KEY_GPIO GPIOC
#define EXT_KEY_PIN GPIO_PIN_13

// 定义液晶显示GPIO口
#define LCD_GPIO GPIOB
#define LCD_RS_PIN GPIO_PIN_4
#define LCD_EN_PIN GPIO_PIN_5
#define LCD_D4_PIN GPIO_PIN_6
#define LCD_D5_PIN GPIO_PIN_7
#define LCD_D6_PIN GPIO_PIN_8
#define LCD_D7_PIN GPIO_PIN_9

// 定义停车场收费参数
#define RATE 1.0 // 每分钟收费1元

// 定义全局变量
volatile uint8_t parking_status = 0; // 停车状态:0-未停车,1-已停车
volatile uint32_t start_time = 0; // 开始停车时间
volatile uint32_t end_time = 0; // 结束停车时间

// 定义函数原型
void GPIO_Init();
void Timer_Init();
void EXTI_Init();
void LCD_Init();
void LCD_WriteCommand(uint8_t command);
void LCD_WriteData(uint8_t data);
void LCD_WriteString(char* string);
void LCD_WriteNumber(uint32_t number);
void DisplayTime(uint32_t time);
void DisplayFee(uint32_t fee);

int main()
{
  // 初始化硬件
  GPIO_Init();
  Timer_Init();
  EXTI_Init();
  LCD_Init();
  
  while(1)
  {
    if(parking_status == 0)
    {
      LCD_WriteCommand(0x01); // 清屏
      LCD_WriteString("Welcome");
      
      if(HAL_GPIO_ReadPin(EXT_KEY_GPIO, EXT_KEY_PIN) == GPIO_PIN_SET)
      {
        HAL_Delay(20); // 延时去抖
        if(HAL_GPIO_ReadPin(EXT_KEY_GPIO, EXT_KEY_PIN) == GPIO_PIN_SET)
        {
          // 开始停车
          parking_status = 1;
          start_time = HAL_GetTick(); // 记录开始停车时间
        }
      }
    }
    else
    {
      uint32_t current_time = HAL_GetTick(); // 当前时间
      uint32_t parking_time = current_time - start_time; // 停车时长
      uint32_t fee = parking_time * RATE; // 收费金额
      
      LCD_WriteCommand(0x01); // 清屏
      LCD_WriteString("Parking Time:");
      DisplayTime(parking_time);
      LCD_WriteString("Fee:");
      DisplayFee(fee);
      
      if(HAL_GPIO_ReadPin(EXT_KEY_GPIO, EXT_KEY_PIN) == GPIO_PIN_SET)
      {
        HAL_Delay(20); // 延时去抖
        if(HAL_GPIO_ReadPin(EXT_KEY_GPIO, EXT_KEY_PIN) == GPIO_PIN_SET)
        {
          // 结束停车
          parking_status = 0;
          end_time = current_time; // 记录结束停车时间
        }
      }
    }
  }
}

void GPIO_Init()
{
  // 启用GPIOA、GPIOB、GPIOC时钟
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  
  // 初始化红外传感器GPIO口
  GPIO_InitTypeDef GPIO_InitStruct;
  GPIO_InitStruct.Pin = IR_SENSOR_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(IR_SENSOR_GPIO, &GPIO_InitStruct);
  
  // 初始化数码管显示GPIO口
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.Pin = SEGMENT_DISPLAY_PIN1 | SEGMENT_DISPLAY_PIN2 |
                         SEGMENT_DISPLAY_PIN3 | SEGMENT_DISPLAY_PIN4;
  HAL_GPIO_Init(SEGMENT_DISPLAY_GPIO, &GPIO_InitStruct);
  
  // 初始化扩展按键GPIO口
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Pin = EXT_KEY_PIN;
  HAL_GPIO_Init(EXT_KEY_GPIO, &GPIO_InitStruct);
  
  // 初始化液晶显示GPIO口
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.Pin = LCD_RS_PIN | LCD_EN_PIN |
                         LCD_D4_PIN | LCD_D5_PIN |
                         LCD_D6_PIN | LCD_D7_PIN;
  HAL_GPIO_Init(LCD_GPIO, &GPIO_InitStruct);
}

void Timer_Init()
{
  // 启用TIM2时钟
  __HAL_RCC_TIM2_CLK_ENABLE();
  
  // 配置TIM2为计数器
  TIM_HandleTypeDef htim2;
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = SystemCoreClock / 1000 - 1; // 设置预分频器,1ms为一个计时单位
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 0xFFFFFFFF; // 定时器溢出时间
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  HAL_TIM_Base_Init(&htim2);
  
  // 启动TIM2
  HAL_TIM_Base_Start(&htim2);
}

void EXTI_Init()
{
  // 启用EXTI时钟
  __HAL_RCC_AFIO_CLK_ENABLE();
  
  // 配置EXTI中断线
  HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0); // 设置中断优先级
  HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); // 使能中断
  
  // 配置EXTI中断触发方式(下降沿触发)
  EXTI_HandleTypeDef EXTI_InitStruct;
  EXTI_InitStruct.Line = EXTI_LINE_13;
  EXTI_InitStruct.Mode = EXTI_MODE_INTERRUPT;
  EXTI_InitStruct.Trigger = EXTI_TRIGGER_FALLING;
  EXTI_InitStruct.GPIOSel = EXTI_GPIOC;
  HAL_EXTI_SetConfigLine(&EXTI_InitStruct);
}

void LCD_Init()
{
  HAL_Delay(50); // 上电初始化延时
  
  // 4位数据线方式,DL=0
  LCD_WriteCommand(0x28);
  HAL_Delay(5);
  
  // 显示开关,D=1,C=0,B=0
  LCD_WriteCommand(0x0C);
  HAL_Delay(5);
  
  // 清屏
  LCD_WriteCommand(0x01);
  HAL_Delay(5);
  
  // 光标移动方向,I/D=1,S=0
  LCD_WriteCommand(0x06);
  HAL_Delay(5);
}

void LCD_WriteCommand(uint8_t command)
{
  HAL_GPIO_WritePin(LCD_GPIO, LCD_RS_PIN, GPIO_PIN_RESET); // 指令模式
  HAL_GPIO_WritePin(LCD_GPIO, LCD_EN_PIN, GPIO_PIN_RESET); // 使能拉低
  
  HAL_GPIO_WritePin(LCD_GPIO, LCD_D4_PIN, (command >> 4) & 0x01);
  HAL_GPIO_WritePin(LCD_GPIO, LCD_D5_PIN, (command >> 5) & 0x01);
  HAL_GPIO_WritePin(LCD_GPIO, LCD_D6_PIN, (command >> 6) & 0x01);
  HAL_GPIO_WritePin(LCD_GPIO, LCD_D7_PIN, (command >> 7) & 0x01);
  
  HAL_GPIO_WritePin(LCD_GPIO, LCD_EN_PIN, GPIO_PIN_SET); // 使能拉高
  HAL_Delay(1); // 持续时间
  HAL_GPIO_WritePin(LCD_GPIO, LCD_EN_PIN, GPIO_PIN_RESET); // 使能拉

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值