IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 【STM32】 两个F103通过HC-08蓝牙模块传送数据 -> 正文阅读

[嵌入式]【STM32】 两个F103通过HC-08蓝牙模块传送数据


一、HC08重要参数

  • 蓝牙4.0,BLE,主从一体;
  • 模块上电后,启动需要150ms;
  • 默认波特率:9600;
  • 模块未连接时,为AT指令模式,连接后为串口透传模式;
  • 空中速率:1Mbps;? (与HC05, HC06等不同, 不能直接与之通信);
  • 通信距离:80米; (空旷);
  • 工作电流:主机未连21mA,已连9mA; 从机未连8.5mA, 已连9mA; 睡眠0.4uA;?
  • 主从关系:两模块必须一主一从,才能连接;

二、AT命令解释

  • 指令结尾,无需添加换行符;
  • 指令修改,立即生效,掉电不丢失;
  • 指令修改,成功时,统一返回OK,查看信息类指令除外;
  • 指令修改,不成功,不返回任何信息;


三、STM32代码操作

1.操作重点

  1. ?开发板用杜邦线连接HC-08,4线:VCC, GND, TX, RX;
  2. 使用UART与HC08通信, 波特率使用HC08默认的9600;
  3. 发送AT指令,无需换行符结尾;
  4. 只要一条AT指令,设置HC08为主、从机模式,就能自动连接;
  5. 模块名称不重要,也不用密码;
  6. ?连接前:AT模式,蓝灯闪烁;连接后:数据透传模式,不再接受AT命令,蓝灯常亮;
  7. 主机和从机的代码一样的,只是一个设置为主机,一个设置为从机;

2.头文件配置

/*****************************************************************************
 ** 移植配置
****************************************************************************/
#define HC08_UARTx       USART3
#define HC08_ROLE        0             // 主从模式,0=slave, 1=master;与手机APP互连必须配置为从机模式



/*****************************************************************************
 ** 全局变量 
****************************************************************************/
typedef struct 
{
    uint8_t  flag_UARTConnect;         // 标记:与开发板间的通信是否正常; 0=失败, 1=成功
    uint8_t  flag_TargetConnect;       // 标记:与目标设备通信是否正常;0=失败, 1=成功
}xHC08_TypeDef;
extern xHC08_TypeDef xHC08;            // 声明为全局变量,方便记录信息、状态
    


/*****************************************************************************
 ** 声明全局函数
****************************************************************************/
void  HC08_Init(void);                             // 初始化串口及中断优先、AT参数配置级;
void  HC08_SendData(uint8_t* data, uint16_t cnt);  // 发送指定长度的数据;
void  HC08_SendString(char* strTemp);              // 发送字符串;

3.GPIO初始化代码

  GPIO_InitTypeDef  GPIO_InitStructure;    
    // 时钟使能
    RCC->APB1ENR |= RCC_APB1ENR_USART3EN;                           // 使能USART1时钟
    RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;                             // 使能GPIOA时钟
    // GPIO_TX引脚配置
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;                // TX引脚,配置为复用推挽工作模式
    GPIO_Init (GPIOB, &GPIO_InitStructure);
    // GPIO_RX引脚配置
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING ;         // RX引脚,配置为浮空输入工作模式
    GPIO_Init (GPIOB, &GPIO_InitStructure);

4.UART初始化代码

    NVIC_InitTypeDef  NVIC_InitStructure;
    USART_InitTypeDef USART_InitStructure; 
  // 中断配置
    NVIC_InitStructure .NVIC_IRQChannel = USART3_IRQn;
    NVIC_InitStructure .NVIC_IRQChannelPreemptionPriority=2 ;       // 抢占优先级
    NVIC_InitStructure .NVIC_IRQChannelSubPriority = 2;             // 子优先级
    NVIC_InitStructure .NVIC_IRQChannelCmd = ENABLE;                // IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);                              
    
    //USART 初始化设置
    USART_DeInit(USART3); 
    USART_InitStructure.USART_BaudRate   = baudrate;                // 串口波特率
    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);                       // 初始化串口
    
    USART_ITConfig(USART3, USART_IT_TXE , DISABLE );
    USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);                  // 使能接受中断
    USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);                  // 使能空闲中断
    
    USART_Cmd(USART3, ENABLE);                                      // 使能串口, 开始工作  
    

5.HC08发送数据代码

// 发送AT指令,或字符串
void  HC08_SendString(char* strTemp)          
{
    HC08_SendData((uint8_t *)strTemp, strlen(strTemp));                  
}


// 发送指定长度的数据
void  HC08_SendData(uint8_t* dataBuf, uint16_t cnt)  
{
    while(cnt--)
    {
        while((HC08_UARTx->SR & 0X40)==0);  // 等待上一次串口数据发送完成 
        HC08_UARTx->DR = *dataBuf;          // 写DR,串口将的发送数据 
        dataBuf++;
    }
}

6.HC08接收数据代码

void USART3_IRQHandler(void)           
{     
    static uint8_t cnt=0;
    static uint8_t RxTemp[256];
    
    // 接收中断
    if(USART3->SR & (1<<5))
    {
        RxTemp[cnt++] = USART3->DR ;                        // 读取数据寄存器值;注意:读取DR时自动清零中断位;
    }
    
    // 空闲中断, 用于配合接收中断,可判断一帧数据接收完成
    if(USART3->SR & (1<<4))                                 // 检查IDLE中断标志
    {         
        memcpy(xUSART.USART3RecivedBuffer , RxTemp , 256);  // 临时数据转存为全局数据, 等待处理,注意:复制的是整个数组,包括0值,以方便字符串数据
        xUSART.USART3RecivedFlag = 1;                       // 标记;外部程序通过检查xUSARTFlag.USART_2_Recived是否等于1, 可判断是否有新一帧数据   
        xUSART.USART3RecivedCNT  = cnt;
        cnt=0;  
        memset(RxTemp ,0, 256);                             // 临时数据空零,准备下一次的接收   
        USART3 ->SR;  USART3 ->DR;                          // 清零IDLE中断标志位!! 序列清零,顺序不能错!! 
        
        /********************************************************************************
         方式1:可在这里调用外部函数,处理接收到数据(不推荐)
         方式2:可在外部判断USARTxRecivedFla==1,然后处理数据区xUSART.USARTxRecivedBuffer  
         禁 止:不可在中断里调用printf等不可重入函数!!!
         示 例: 下面这一行代码, 只作示例, 输出到上位机以观察所收到的最新一帧数据, 可删除
        *********************************************************************************/
        USART1_printf((char*)xUSART.USART3RecivedBuffer);   // 这行代码只作示例,输出USART3收到的最新一帧数据,可删除  
     }  
}  

7.数据处理

    // 本函数为main函数中的while函数
    while(1)                                 // while函数死循环,不能让main函数运行结束,否则会产生硬件错误
    {    
        // Scheduler_Run();                  // 任务轮询器; 如要使用, 清除while中其它函数(移到Scheduler文件中去), 以保证计时的准确
        System_DelayMS(100);                 // 上面已初始化SysTick, 可直接使用delay_ms()、delay_us()
        LED_RED_TOGGLE;                      // 红色LED 每0.5秒闪灭一次,以监察系统正常工作   
                    
        if(xUSART.USART1RecivedFlag==1)                                  // 判断上位机(USART1)是否收到新的数据
        {
            HC08_SendString((char *)xUSART.USART1RecivedBuffer);         // 如果收到新数据,就从蓝牙发送出去
            xUSART.USART1RecivedFlag=0;                                  // 处理完了,标记清0,不然下一个while循环又会重复操作
        }                        
        
        // 处理HC08收到的数据
        if(xUSART.USART3RecivedFlag==1)                                  // 判断蓝牙HC08(USART3)是否收到新的数据
        {
            if(xUSART.USART3RecivedBuffer[0]=='0')   { LED_BLUE_OFF;}    // 判断收到的数据
            if(xUSART.USART3RecivedBuffer[0]=='1')   { LED_BLUE_ON;}   
            if(xUSART.USART3RecivedBuffer[0]=='3')   { LED_BLUE_TOGGLE;}             
            xUSART.USART3RecivedFlag=0;                                  // 处理完了,标记清0,不然下一个while循环又会重复操作
        }   
    }  

四、源代码下载

需要代码的兄弟,可通过以下方式下载代码:

1:CSDN资源https://download.csdn.net/download/zhouml_msn/20664466

2:Q群文件夹:887199504

互相学习,欢迎指正!~

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-01 14:40:08  更:2021-08-01 14:41:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 18:53:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码