程序员

STM32F103 串口1和串口3对发数据 配合蓝牙模块 实现手机和单片机

作者:admin 2021-07-14 我要评论

目录 前言 接线 USB转TTL 蓝牙 效果图 USB转TTL 蓝牙 手机收 电脑发 手机发 电脑收 蓝牙的连接/断开 参考用图 STM32F103 蓝牙模块相关 核心代码 main.c usart1.c...

在说正事之前,我要推荐一个福利:你还在原价购买阿里云、腾讯云、华为云服务器吗?那太亏啦!来这里,新购、升级、续费都打折,能够为您省60%的钱呢!2核4G企业级云服务器低至69元/年,点击进去看看吧>>>)

前言

开发板:正点原子 STM32F103 精英版
语言:C语言
开发环境:Keil5
使用了 KEY LED USART USB转TTL模块 智向的蓝牙模块(ps:电脑安装驱动CH340)
代码下载码云 GitHub
在这里插入图片描述

代码参考:正点原子 源码 串口实验例程
功能介绍
1、LED的0.2秒一闪,表示程序正在运行。
2、串口1收到的数据会发给串口3,串口3收到的数据会发给串口1。
3、按键KEY1按下会向串口1发送数据‘1’,按键KEY0按下会向串口3发送数据‘3’。

接线

USB转TTL

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

蓝牙

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

效果图

USB转TTL

在这里插入图片描述

蓝牙

使用的手机软件(安卓)为 BLE调试助手
在这里插入图片描述
打开软件、蓝牙、给予权限等
扫描到我们的蓝牙模块,然后连接
在这里插入图片描述
连接成功后
在这里插入图片描述
点击最下面的 Unkonwn Service,展开,有接收 和 发送 按钮
在这里插入图片描述

手机收 电脑发

在这里插入图片描述
在这里插入图片描述

手机发 电脑收

在这里插入图片描述
在这里插入图片描述

蓝牙的连接/断开

蓝牙收到了手机发来的 连接 和 断开 信息
在这里插入图片描述

参考用图

STM32F103

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

蓝牙模块相关

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

核心代码

完整代码下载码云 GitHub

main.c

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart1.h"
#include "usart3.h"

// 串口收发函数 type为1,串口1收,发往串口3  type不为1,串口3,发往串口1
void usart_recv_send(u8 type);

int main(void)
{
    vu8 key = 0;
    delay_init();												 // 延时函数初始化
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    usart1_init(115200);									 // USART1初始化 波特率115200 默认数据位8 停止位1 校验位none
    usart3_init(115200);									 // USART3初始化 波特率115200 默认数据位8 停止位1 校验位none
    LED_Init();												 // LED端口初始化
    KEY_Init();										  	 	 // 初始化与按键连接的硬件接口
    while (1)
    {
        // 串口收发
        usart_recv_send(1);
        usart_recv_send(3);

        // 得到键值
        key = KEY_Scan(0);
        if (key)
        {
            switch (key)
            {
                case KEY1_PRES: // 向串口1发送'1'
                    usart1_send_byte(0x31);
                    break;
                case KEY0_PRES: // 向串口3发送'3'
                    usart3_send_byte(0x33);
                    break;
            }
        }

        LED0 = !LED0; //闪烁LED,提示系统正在运行.
        delay_ms(100);
    }
}

// 串口收发函数 type为1,串口1收,发往串口3  type不为1,串口3,发往串口1
void usart_recv_send(u8 type)
{
    u8 i = 0;
    u8 tmp_len = 0;
    // 数据缓存
    static u8 buf[255] = {0};
    // 数据长度
    u8 buf_len = 0;

    // 返回缓存区数据的个数
    if(1 == type)
        tmp_len = usart1_getdata_count();
    else
        tmp_len = usart3_getdata_count();

    for(i=0; i<tmp_len; i++)
    {
        // 返回缓存区当前指针所指数据
        if(1 == type)
            buf[i] = usart1_receive_data();
        else
            buf[i] = usart3_receive_data();

        buf_len++;
        // 超过约定的上限长度
        if(buf_len >= 250)
        {
            buf_len=0;
            break;
        }
    }

    // 数据不为空
    if(0 != buf_len)
    {
        // 串口数据发送
        if(1 == type)
            usart3_send_bytes(buf, buf_len);
        else
            usart1_send_bytes(buf, buf_len);
    }
}

usart1.c

#include "usart1.h"
#include "stdio.h"

static uint8_t usart1_buffer[255];
static uint8_t usart1_index;
static uint8_t usart1_count;

// USART1初始化 默认数据位8 停止位1 校验位none
void usart1_init(u32 bound)
{
    // GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    /* config USART1 clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // 使能USART1,GPIOA时钟

    /* USART1 GPIO config */
    /* Configure USART1 Tx (PA.09) as alternate function push-pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化GPIOA.9
    /* Configure USART1 Rx (PA.10) as input floating */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA.10

    // Usart1 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		//子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器

    USART_InitStructure.USART_BaudRate = bound; // 串口波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 字长为8位数据格式
    USART_InitStructure.USART_StopBits = USART_StopBits_1; // 一个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No; // 无奇偶校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件数据流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 收发模式
    USART_Init(USART1, &USART_InitStructure); // 初始化串口1
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 开启串口接受中断

    USART_Cmd(USART1, ENABLE); // 使能串口1

    usart1_index=0;
    usart1_count=0;
}

// 中断服务函数
void USART1_IRQHandler(void)
{
    // 接收中断
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        if(usart1_count==usart1_index)
        {
            // 缓存区无数据,回到起点开始存储
            usart1_count=0;
            usart1_index=0;
        }
        usart1_buffer[usart1_count]=USART1->DR;
        usart1_count++;
        if(usart1_count>=250)
        {
            // 没有及时取出数据,导致存储位置到达末尾,回到起点
            usart1_count=0;
            usart1_index=0;
        }
    }
}

/*返回缓存区数据的个数*/
uint8_t usart1_getdata_count(void)
{
    return usart1_count-usart1_index;
}

/*返回缓存区当前指针所指数据*/
uint8_t usart1_receive_data(void)
{
    return usart1_buffer[usart1_index++];
}

/*串口数据发送函数
data_send:发送数据
*/
void usart1_send_byte(uint8_t data_send)
{
    USART_SendData(USART1, data_send);
    while (!(USART1->SR & USART_FLAG_TXE));
}

/*串口数据发送函数
data_buffer:发送数据串的首地址
length:发送数据的长度
*/
void usart1_send_bytes(uint8_t* data_buffer,uint8_t length)
{
    uint8_t i;
    for(i=0; i<length; i++)
    {
        usart1_send_byte(data_buffer[i]);
    }
}

usart3.c

#include "usart3.h"
#include "stdio.h"

static uint8_t usart3_buffer[255];
static uint8_t usart3_index;
static uint8_t usart3_count;

// USART3初始化 默认 数据位8 停止位1 校验位none
void usart3_init(u32 bound)
{
	// GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    /* config USART3 clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); //使能USART3,GPIOB时钟

    /* USART3 GPIO config */
    /* Configure USART3 Tx (PB.10) as alternate function push-pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    /* Configure USART3 Rx (PB.11) as input floating */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		//子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器

    USART_InitStructure.USART_BaudRate = bound; // 串口波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 字长为8位数据格式
    USART_InitStructure.USART_StopBits = USART_StopBits_1; // 一个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No; // 无奇偶校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件数据流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 收发模式
    USART_Init(USART3, &USART_InitStructure); // 初始化串口3
    USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); // 开启串口接受中断

    USART_Cmd(USART3, ENABLE); // 使能串口3 

    usart3_index=0;
    usart3_count=0;
}

// 中断服务函数
void USART3_IRQHandler(void)
{
    if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
    {
        if(usart3_count==usart3_index)
        {
            //缓存区无数据,回到起点开始存储
            usart3_count=0;
            usart3_index=0;
        }
        usart3_buffer[usart3_count]=USART3->DR;
        usart3_count++;
        if(usart3_count>=250)
        {
            //没有及时取出数据,导致存储位置到达末尾,回到起点
            usart3_count=0;
            usart3_index=0;
        }
    }
}

/*返回缓存区数据的个数*/
uint8_t usart3_getdata_count(void)
{
    return usart3_count-usart3_index;
}

/*返回缓存区当前指针所指数据*/
uint8_t usart3_receive_data(void)
{
    return usart3_buffer[usart3_index++];
}

/*串口数据发送函数
data_send:发送数据
*/
void usart3_send_byte(uint8_t data_send)
{
    USART_SendData(USART3, data_send);
    while (!(USART3->SR & USART_FLAG_TXE));
}

/*串口数据发送函数
data_buffer:发送数据串的首地址
length:发送数据的长度
*/
void usart3_send_bytes(uint8_t* data_buffer,uint8_t length)
{
    uint8_t i;
    for(i=0; i<length; i++)
    {
        usart3_send_byte(data_buffer[i]);
    }
}

;原文链接:https://blog.csdn.net/Ikaros_521/article/details/115703625

版权声明:本文转载自网络,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本站转载出于传播更多优秀技术知识之目的,如有侵权请联系QQ/微信:153890879删除

相关文章
  • STM32F103 串口1和串口3对发数据 配合

    STM32F103 串口1和串口3对发数据 配合

  • Esp8266天猫精灵_RGB灯_非点灯平台

    Esp8266天猫精灵_RGB灯_非点灯平台

  • Zookeeper 完全分布安装(编写shell脚

    Zookeeper 完全分布安装(编写shell脚

  • 2020第十一届蓝桥杯第二场省赛JAVA A组

    2020第十一届蓝桥杯第二场省赛JAVA A组

腾讯云代理商
海外云服务器