基于stm32的HAL库的蓝牙遥控插座项目(六 串口)

发布于:2024-10-15 ⋅ 阅读:(55) ⋅ 点赞:(0)

项目需求

手机通过蓝牙模块远程遥控风扇。

硬件接线

项目框图

1 plugin插座模块

1.1 plugin模块初始化

void plugin_init(void)
{
    GPIO_InitTypeDef gpio_initstruct;
    //打开时钟
    HAL_RCC_GPIOB_CLK_ENABLE();
    //调用GPIO初始化函数

    gpio_initstruct.Pin  = GPIO_PIN_6;         //选择PB6
    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);

    plugin1_off();
}

1.2 初始化GPIO函数

void plugin1_on(void)
{
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);
}

1.3 打开插座的函数

void plugin_off(void)
{
    //由电路图可知,将GPIO拉低
   HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET); 
}

1.4 获取继电器的状态  --为什么

uint8_t plugin_status_get(void)
{
    return (uint8_t)HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_6)
}

2 串口模块代码封装

2.1 头文件

#include "sys.h"
#include "uart1.h"
#include "string.h"
#include "stdio.h"

/* 错误代码 */
#define UART_EOK                     0      /* 没有错误 */
#define UART_ERROR                   1      /* 通用错误 */
#define UART_ETIMEOUT                2      /* 超时错误 */
#define UART_EINVAL                  3      /* 参数错误 */

/* UART收发缓冲大小 */
#define UART1_RX_BUF_SIZE            128
#define UART1_TX_BUF_SIZE            64


void uart1_init(uint32_t bound);            /* 串口初始化函数 */

UART_HandleTypeDef uart1_handle

uint8_t uart1_rx_buf[UART_RX_BUF_SIZE];
uint16_t uart1_rx_len = 0;
/**
 * @brief       重定义fputc函数
 * @note        printf函数最终会通过调用fputc输出字符串到串口
 */
int fputc(int ch, FILE *f)
{
    while ((USART1->SR & 0X40) == 0);                                       /* 等待上一个字符发送完成 */

    USART1->DR = (uint8_t)ch;                                               /* 将要发送的字符 ch 写入到DR寄存器 */
    return ch;
}

2.2UART初始化 

void uart1_init(uint32_t baudrate)
{
    /*UART1 初始化设置*/
    uart1_handle.Instance          = USART1;            /* USART1 */          
    uart1_handle.Init.BaudRate     = baudrate;          /* 波特率 */
    uart1_handle.Init.WordLength   = UART_WORDLENGTH_8B;/* 字长为8位数据格式 */
    uart1_handle.Init.StopBits     = UART_STOPBITS_1;   /* 一个停止位 */
    uart1_handle.Init.HwFlowCtl    = HWCONTROL_NONE;    /* 无硬件流控制 */
    UART1_handle.Init.Parity       = UART_PARITY_NONE;  /*无奇偶校验位*/
    uart1_handle.Init.Mode         = UART_MODE_TX_RX;   /*收发模式*/
    HAL_UART_Init(&uart1_handle);
}

2.3 UART底层代码初始化

            UART底层初始化函数
            huart: UART句柄类型指针
            此函数会被HAL_UART_Init()调用
            完成时钟使能,引脚配置,中断配置

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART1)
    {
    //GPIO,UART时钟使能
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_USART1_CLK_ENABLE();
    //GPIO配置串口 输入输出引脚  Tx
    GPIO_InitTypeDef gpio_init_struct;
    gpio_init_struct.Pin   = GPIO_PIN_9;
    gpio_init_struct.Mode  = GPIO_MODE_AF_PP;
    gpio_init_struct.Pull  = GPIO_PULLUP;
    gpio_ihit_struct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA,&gpio_init_struct);
    //RX配置
    gpio_init_struct.Pin   = GPIO_PIN_10;
    gpio_init_struct.Mode  = GPIO_MODE_AF_INPUT; 
    HAL_UART_Init(GPIOA,&gpio_init_struct);

    //NVIC配置
    HAL_NVIC_EnableIRQ(USART2_IRQn);
    HAL_NVIC_SetPriority(USART2_IRQn,3,3);
    //空闲中断输入
    __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
    __HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);   
    }
    //蓝牙模块串口通道
    else if(huart->Instance == USART2)
    {
       //GPIO,UART时钟使能
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_USART1_CLK_ENABLE();
    //GPIO配置串口 输入输出引脚  Tx
    GPIO_InitTypeDef gpio_init_struct;
    gpio_init_struct.Pin   = GPIO_PIN_2;
    gpio_init_struct.Mode  = GPIO_MODE_AF_PP;
    gpio_init_struct.Pull  = GPIO_PULLUP;
    gpio_ihit_struct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA,&gpio_init_struct);
    
    //RX配置
    gpio_init_struct.Pin   = GPIO_PIN_3;
    gpio_init_struct.Mode  = GPIO_MODE_AF_INPUT; 
    HAL_UART_Init(GPIOA,&gpio_init_struct);

    //NVIC配置
    HAL_NVIC_EnableIRQ(USART2_IRQn);
    HAL_NVIC_SetPriority(USART2_IRQn,3,3);
    
    //空闲中断输入
    __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
    __HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);   
    }
}

2.4UART1接收缓冲区清除

void uart1_rx_clear(void)
{
    memset(uart1_rx_buf,0,sizeof(uart1_rx_buf));
    uart1_rx_len = 0;
}

2.5 串口1中断服务函数

void USART1_IRQHandle(void)
{
    uint8_t receive_data = 0;
    if(__HAL_UART_GET_FLAG(&uart1_handle, UART_FLAG_RXNE) !=RESET)//非空判断
    {
        if(uart1_rx_len >= sizeof(uart1_rx_buf))
            uart_rx_len = 0;
    
        HAL_UART_Receive(&uart1_handle,&receive_data,1,1000);     //接收
        uart1_rx_buf[uart1_rx_len++] = receive_data;              //数据逐渐接收
}
    if(__HAL_UART_GET_FLAG(&uart1_handle,UART_FLAG_IDLE) != RESET)//空闲中断
    {
        printf("recv: %s\r\n", uart1_rx_buf);    //打印出接收的数据
        uart1_rx_clear();                        //清楚
        __HAL_UART_CLEAR_IDLEFLAG(&uart1_handle);//清楚空闲中断发送标志位
    }   
}

3蓝牙模块

3.5蓝牙模块头文件

#include "sys.h"
#include "bluetooth.h"
#include "string.h"
#include "stdarg.h"
#include "plugin.h"

/* UART收发缓冲大小 */
#define UART2_RX_BUF_SIZE            128
void bt_init(uint32_t bound);            /* 串口初始化函数 */
//void bt_send(char *send_buf,uint8_t size);
void bt_send(char * format,...);

UART_HandleTypeDef uart2_handle;

uint8_t uart2_rx_buf[UART2_RX_NIF_SIZE];
uint16_t uart2)rx_len = 0;

3.1蓝牙串口初始化

void bt_init(uint32_t bound)
{
    uart2_handle.Instance       = USART2;              /* USART1 */
    uart2_handle.Init.BaudRate  = bound;               /* 波特率 */
    uart2_handle.Init.WordLenght = UART_WORDLENGTH_8B; /* 字长为8位数据格式 */
    uart2_handle.Init.StopBits   = UART_STOPBITS_1;    /* 一个停止位 */
    uart2_handle.Init.Priaty     = UART_PRIATY_NONE;   /* 无奇偶校验位 */
    uart2_handle.Init.HwFlowCtl  = UART_HWCONTROL_NONE;/* 无硬件流控 */
    uart2_handle.Init.Mode       = UART_MODE_TX_RX;    /* 收发模式 */
    HAL_UART_Init(&uart2_handle);                      /* HAL_UART_Init()会使能uart2 */

}

3.2蓝牙串口数组数据清楚

void uart2_rx_clear(void)
{
    memset(uart2_rx_buf,0,sizeof(uart2_rx_buf));
    uart2_rx_len = 0;
}

3.3中断服务函数

void UART_IRQHandler(void)
{
    uint8_t receive_data = 0;
    if(__HAL_UART_GET_FLAG(&uart2_handle, UART_FLAG_RXNE) != RESET)//接收数据
    {
    if(uart2_rx_len >= sizeof(uart2_rx_buf))
    uart2_rx_len = 0;
    HAL_UART_Receive(&uart2_handle,&receive_data,1,1000);  接收一个字符
    uart2_rx_buf[uart2_rx_len++] = receive_data;
    
    }
    if(_HAL_UART_GET_FLAG(&uart2_handle,UART_FLAG_IDLE) != RESET)
    {
        printf("bt;recv: %s\r\n", uart2_rx_buf);
         //判断是否有某个字符串用strstr  字符串中首串的地址
        if(strstr(char *)uart2_rx_buf,"on" !=NULL)
        plugin1_on();
        if(strstr(char *)uart2_rx_buf,"off" !=NULL)
        plugin1_off();

        uart2_rx_clear();
        __HAL_UART_CLEAR_IDLEFLAG(&uart2_handle);
    }

}

3.4不定长传输

void bt_send(char * format,...)
{
    uint8_t send_buf[128] = {0};
    va_list arg;                //创建一个参数列表va_list
    va_start(arg,format);       //初始化发送的数组
    vsprintf((char *)send_buf,format,arg);
    va_end(arg);
    HAL_UART_Transmit(&uart2_handle,send_buf,sizeof(send_buf),100);
}


网站公告

今日签到

点亮在社区的每一天
去签到