【STM32单片机_(HAL库)】3-4-3【中断EXTI】【智能排队控制系统】排队系统代码框架搭建

3-4-2系统框图及硬件接线

3.软件

#include "sys.h"
#include "delay.h"
#include "led.h"
#include "tasks.h"
#include "gate.h"
#include "beep.h"
#include "exti.h"
#include "lcd1602.h"

int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
    stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟, 72Mhz */
    led_init();                         /* 初始化LED灯 */
    gate_init();                        /* 初始化继电器 */
    beep_init();                        /* 初始化蜂鸣器 */
    exti_init();                        /* 初始化红外传感器 */
    lcd1602_init();                     /* 初始化LCD1602 */
    
    lcd1602_show_line(1, 2, "HELLO");

    while(1)
    {         
//        if(ia_flag_get() == TRUE)
//        {
//            led1_on();
//            delay_ms(2000);
//            led1_off();
//        }
//        beep_on();
//        delay_ms(500);
//        beep_off();
//        delay_ms(500);
//        task1();
//        task2();
    }
}




  • exti.c程序
#include "exti.h"
#include "sys.h"
#include "delay.h"
#include "led.h"

uint8_t ia_flag = FALSE;                               // 检测到震动标志位

void exti_init(void)
{
    GPIO_InitTypeDef gpio_initstruct;
    //打开时钟
    __HAL_RCC_GPIOB_CLK_ENABLE();                           // 使能GPIOA时钟
    
    //调用GPIO初始化函数
    gpio_initstruct.Pin = GPIO_PIN_4;                       // 震动传感器对应的引脚
    gpio_initstruct.Mode = GPIO_MODE_IT_FALLING;            // 下降沿触发
    gpio_initstruct.Pull = GPIO_PULLUP;                     // 上拉
    HAL_GPIO_Init(GPIOB, &gpio_initstruct);
    
    HAL_NVIC_SetPriority(EXTI4_IRQn, 2, 0);                 // 设置EXTI0中断线的优先级
    HAL_NVIC_EnableIRQ(EXTI4_IRQn);                         // 使能中断
}

void EXTI4_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    delay_ms(20);
    if (GPIO_Pin == GPIO_PIN_4)
    {
        if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4) == GPIO_PIN_RESET)
            //led1_toggle();
            ia_flag = TRUE;
    }
}

uint8_t ia_flag_get(void)
{
    uint8_t temp = ia_flag;
    ia_flag = FALSE;
    return temp;
    
}

void ia_flag_set(uint8_t value)
{
    ia_flag = value;
}

  • exti.h程序
#ifndef __EXTI_H__
#define __EXTI_H__

#include "stdint.h"

#define TRUE    1
#define FALSE   0

void exti_init(void);
uint8_t ia_flag_get(void);
void ia_flag_set(uint8_t value);

#endif

  • gate.c
#include "gate.h"
#include "sys.h"

//初始化GPIO函数
void gate_init(void)
{
    GPIO_InitTypeDef gpio_initstruct;
    //打开时钟
    __HAL_RCC_GPIOB_CLK_ENABLE();                           // 使能GPIOB时钟
    
    //调用GPIO初始化函数
    gpio_initstruct.Pin = GPIO_PIN_6;                       // 继电器对应的引脚
    gpio_initstruct.Mode = GPIO_MODE_OUTPUT_PP;             // 推挽输出
    gpio_initstruct.Pull = GPIO_PULLUP;                     // 上拉
    gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;           // 高速
    HAL_GPIO_Init(GPIOB, &gpio_initstruct);
    //关闭LED
    gate_off();
}

//闭合继电器的函数
void gate_on(void)
{
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);   // 拉低LED1引脚,点亮LED1
}

//松开继电器的函数
void gate_off(void)
{
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);     // 拉高LED1引脚,熄灭LED1
}

//获取继电器状态的函数
uint8_t gate_status_get(void)
{
    return (uint8_t)HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6);
}

  • gate.h
#ifndef __GATE_H__
#define __GATE_H__

#include "stdint.h"

#define GATE_STATUS_ON     0
#define GATE_STATUS_OFF    1

void gate_init(void);
void gate_on(void);
void gate_off(void);
uint8_t gate_status_get(void);

#endif


  • beep.c
#include "beep.h"
#include "sys.h"

//初始化GPIO函数
void beep_init(void)
{
    GPIO_InitTypeDef gpio_initstruct;
    //打开时钟
    __HAL_RCC_GPIOB_CLK_ENABLE();                           // 使能GPIOB时钟
    
    //调用GPIO初始化函数
    gpio_initstruct.Pin = GPIO_PIN_5;                       // 蜂鸣器对应的引脚
    gpio_initstruct.Mode = GPIO_MODE_OUTPUT_PP;             // 推挽输出
    gpio_initstruct.Pull = GPIO_PULLUP;                     // 上拉
    gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;           // 高速
    HAL_GPIO_Init(GPIOB, &gpio_initstruct);
    //关闭蜂鸣器
    beep_off();
}

//打开蜂鸣器的函数
void beep_on(void)
{
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);   // 拉低蜂鸣器引脚,打开蜂鸣器
}

//关闭蜂鸣器的函数
void beep_off(void)
{
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);     // 拉高蜂鸣器引脚,关闭蜂鸣器
}

  • beep.h
#ifndef __BEEP_H__
#define __BEEP_H__

void beep_init(void);
void beep_on(void);
void beep_off(void);

#endif

  • led.c
#include "led.h"
#include "sys.h"

//初始化GPIO函数
void led_init(void)
{
    GPIO_InitTypeDef gpio_initstruct;
    //打开时钟
    __HAL_RCC_GPIOB_CLK_ENABLE();                           // 使能GPIOB时钟
    
    //调用GPIO初始化函数
    gpio_initstruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;          // 两个LED对应的引脚
    gpio_initstruct.Mode = GPIO_MODE_OUTPUT_PP;             // 推挽输出
    gpio_initstruct.Pull = GPIO_PULLUP;                     // 上拉
    gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;           // 高速
    HAL_GPIO_Init(GPIOB, &gpio_initstruct);
    //关闭LED
    led1_off();
    led2_off();
}

//点亮LED1的函数
void led1_on(void)
{
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);   // 拉低LED1引脚,点亮LED1
}

//熄灭LED1的函数
void led1_off(void)
{
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);     // 拉高LED1引脚,熄灭LED1
}

//翻转LED1状态的函数
void led1_toggle(void)
{
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);
}

//点亮LED2的函数
void led2_on(void)
{
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET);   // 拉低LED2引脚,点亮LED2
}

//熄灭LED2的函数
void led2_off(void)
{
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET);     // 拉高LED2引脚,熄灭LED2
}

//翻转LED2状态的函数
void led2_toggle(void)
{
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_9);
}

  • led.h
#ifndef __LED_H__
#define __LED_H__

void led_init(void);
void led1_on(void);
void led1_off(void);
void led1_toggle(void);
void led2_on(void);
void led2_off(void);
void led2_toggle(void);

#endif

  • tasks.c
#include "tasks.h"
#include "led.h"

uint32_t task1_cnt = 0;
uint32_t task2_cnt = 0;

uint8_t task1_flag = 0;
uint8_t task2_flag = 0;

void systick_isr(void)
{
    if (task1_cnt < 1000)
        task1_cnt++;
    else
    {
        task1_flag = 1;
        task1_cnt = 0;
    }

    if (task2_cnt < 500)
        task2_cnt++;
    else
    {
        task2_flag = 1;
        task2_cnt = 0;
    }
}

void task1(void)
{
    if(task1_flag == 0)
        return;
    
    task1_flag = 0;
    
    led1_toggle();
}

void task2(void)
{
    if(task2_flag == 0)
        return;
    
    task2_flag = 0;
    
    led2_toggle();
}

  • tasks.h
#ifndef __TASKS_H__
#define __TASKS_H__

#include "sys.h"

void systick_isr(void);
void task1(void);
void task2(void);

#endif

  • lcd1602.c
#include "lcd1602.h"
#include "string.h"
#include <stdarg.h>
#include "delay.h"

// RS引脚定义
#define RS_GPIO_Port GPIOB
#define RS_GPIO_PIN GPIO_PIN_1
#define RS_HIGH     HAL_GPIO_WritePin(RS_GPIO_Port, RS_GPIO_PIN, GPIO_PIN_SET)
#define RS_LOW      HAL_GPIO_WritePin(RS_GPIO_Port, RS_GPIO_PIN, GPIO_PIN_RESET)

// RW引脚定义
#define RW_GPIO_Port GPIOB
#define RW_GPIO_PIN GPIO_PIN_2
#define RW_HIGH     HAL_GPIO_WritePin(RW_GPIO_Port, RW_GPIO_PIN, GPIO_PIN_SET)
#define RW_LOW      HAL_GPIO_WritePin(RW_GPIO_Port, RW_GPIO_PIN, GPIO_PIN_RESET)

// EN引脚定义
#define EN_GPIO_Port GPIOB
#define EN_GPIO_PIN GPIO_PIN_10
#define EN_HIGH     HAL_GPIO_WritePin(EN_GPIO_Port, EN_GPIO_PIN, GPIO_PIN_SET)
#define EN_LOW      HAL_GPIO_WritePin(EN_GPIO_Port, EN_GPIO_PIN, GPIO_PIN_RESET)

/**
 * @brief       LCD1602 GPIO初始化
 * @param       无
 * @retval      无
 */
void lcd1602_gpio_init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();


  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : PB1 PB2 PB10 */
  GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

/**
 * @brief       lcd开始工作
 * @param       无
 * @retval      无
 */
void lcd1602_start(void)
{
//(1)延时 15ms
    delay_ms(15);
//(2)写指令 38H(不检测忙信号) 
    lcd1602_write_cmd(0x38);
//(3)延时 5ms
    delay_ms(5);
//(4)检测忙信号(省略)
//(5)写指令 38H:显示模式设置
    lcd1602_write_cmd(0x38);
//(6)写指令 08H:显示关闭
    lcd1602_write_cmd(0x08);
//(7)写指令 01H:显示清屏
    lcd1602_write_cmd(0x01);
//(8)写指令 06H:显示光标移动设置
    lcd1602_write_cmd(0x06);
//(9)写指令 0CH:显示开及光标设置
    lcd1602_write_cmd(0x0c);
}

/**
 * @brief       LCD1602初始化
 * @param       无
 * @retval      无
 */
void lcd1602_init(void)
{
    lcd1602_gpio_init();
    lcd1602_start();
}

/**
 * @brief       写指令
* @param        cmd:指令
 * @retval      无
 */
void lcd1602_write_cmd(char cmd)
{
    RS_LOW;
    RW_LOW;
    EN_LOW;
    GPIOA->ODR = cmd;       //将一字节数据发到GPIOA 8个引脚
    delay_ms(5);
    EN_HIGH;
    delay_ms(5);
    EN_LOW;
}

/**
 * @brief       写数据
 * @param       dataShow:显示的字符
 * @retval      无
 */
void lcd1602_write_data(char dataShow)
{
    RS_HIGH;
    RW_LOW;
    EN_LOW;
    GPIOA->ODR = dataShow;   //将一字节数据发到GPIOA 8个引脚
    delay_ms(5);
    EN_HIGH;
    delay_ms(5);
    EN_LOW;
}

/**
 * @brief       画面右移
 * @param       无
 * @retval      无
 */
void lcd1602_right_move(void)
{
    for(int i=0;i < 16;i++){
        delay_ms(1000);
        lcd1602_write_cmd(0x18);            //画面右移一位 0x18
    }
}

/**
 * @brief       显示字符
 * @param       row: 显示行,col: 显示起始列,string:显示字符
 * @retval      无
 */
void lcd1602_show_line(char row, char col, char *string)
{
    switch(row){
    case 1:
        lcd1602_write_cmd(0x80+col);        //最高位 D7 为高电平
        while(*string){
            lcd1602_write_data(*string);
            string++;
        }
        break;
    
    case 2:
        lcd1602_write_cmd(0x80+0x40+col);
        while(*string){
            lcd1602_write_data(*string);
            string++;
        }
        break;
    }
}

  • lcd1602.h
#ifndef __LCD1602_H__
#define __LCD1602_H__

#include <stdint.h>


void lcd1602_init(void);
void lcd1602_write_cmd(char cmd);
void lcd1602_write_data(char dataShow);
void lcd1602_show_line(char row, char col, char *string);
void lcd1602_right_move(void);

#endif

在这里插入图片描述

智能排队控制系统项目代码框架

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值