前言
将数据通过蓝牙发送到手机上,是学生学习单片机的必备技能之一,它可以将手机作为简单的上位机,从而使数据直观地展现出来。
蓝牙的初始化、蓝牙接受数据以及蓝牙简单应用的介绍和代码记录,可以看一看下面的文章,这次就主要记录一下蓝牙发送数据的学习。

HC-05蓝牙模块的使用_hc05蓝牙调试助手_KAIs32的博客-CSDN博客

STM32学习记录——使用蓝牙点亮LED_stm32蓝牙点灯_KAIs32的博客-CSDN博客

Arduino学习记录——蓝牙控制舵机(含LED指示灯)_arduino蓝牙控制舵机_KAIs32的博客-CSDN博客

一、学习目的


我主要是想通过蓝牙发送数据,将单片机上烟雾传感器、光敏传感器、火焰传感器等模块检测到的数据实时显示在手机上,达到实时监控的目的。

至于传感器的初始化,这里就不重复记录了,可以看看下面的文章进行复习。

STM32学习记录——光敏传感器的使用_stm32光敏传感器_KAIs32的博客-CSDN博客

STM32学习记录——烟雾传感器的使用_mq2烟雾传感器stm32代码_KAIs32的博客-CSDN博客

二、代码记录
首先是各个传感器的初始化,我统一写在了同一个.c文件里。

adc.h

#ifndef __ADC_H
#define __ADC_H
#include "stm32f10x.h"

void ADC_Pin_Init(void);    //传感器引脚、ADC初始化
float ADC_Trans(void);      //烟雾传感器获取数据

#endif

adc.c

#include "adc.h"
#include "sys.h"
#include "stm32f10x_tim.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_adc.h"

void ADC_Pin_Init(void)         //传感器引脚、ADC初始化
{
    GPIO_InitTypeDef GPIO_InitStruct;
    ADC_InitTypeDef ADC_InitStruct;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOB,ENABLE);

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;     //烟雾传感器
    GPIO_Init(GPIOA,&GPIO_InitStruct);

    GPIO_InitStruct.GPIO_Pin =  GPIO_Pin_1;    //光敏传感器
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;  
    GPIO_Init(GPIOA, &GPIO_InitStruct); 

    GPIO_InitStruct.GPIO_Pin =  GPIO_Pin_0;    //火焰传感器
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;     
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;  
    GPIO_Init(GPIOB, &GPIO_InitStruct); 

    ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;
    ADC_InitStruct.ADC_NbrOfChannel = 1;
    ADC_InitStruct.ADC_ScanConvMode = DISABLE;
    ADC_Init(ADC1,&ADC_InitStruct);


    ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);    

    ADC_RegularChannelConfig(ADC1,ADC_Channel_8,1,ADC_SampleTime_239Cycles5);    

    ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);

    ADC_Cmd(ADC1,ENABLE);
}

float ADC_Trans (void)          //烟雾传感器获取数据
{
    float adc_value = 0;
    u8 i = 0;
    ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_239Cycles5);
    for(i = 0; i < 50; i++)
    { 
        ADC_SoftwareStartConvCmd(ADC1,ENABLE);    
        adc_value = adc_value + ADC_GetConversionValue(ADC1);
    }

    return adc_value / 50;
}

接下来就是蓝牙模块初始化的代码

hc05.h

#ifndef __HC05_H
#define __HC05_H
#include "sys.h"

void My_USART2_Init(void);            //串口初始化函数
//void USART2_IRQHandler(void);       //接受数据函数(这里不用,可以注释掉)
void Bluetooth_SendData(char* data);  //发送数据函数

#endif

hc05.c

代码中有注释,可以看一看

#include "hc05.h"
#include "usart.h"

//u8 res;              
void My_USART2_Init(void)  
{  
    GPIO_InitTypeDef GPIO_InitStrue;  
    USART_InitTypeDef USART_InitStrue;  
    NVIC_InitTypeDef NVIC_InitStrue;  

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE); 

//初始化RXD、TXD两个引脚
    GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;  
    GPIO_InitStrue.GPIO_Pin=GPIO_Pin_2;
    GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
    GPIO_Init(GPIOA,&GPIO_InitStrue);

    GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;
    GPIO_InitStrue.GPIO_Pin=GPIO_Pin_3;
    GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
    GPIO_Init(GPIOA,&GPIO_InitStrue); 

//设置串口参数
    USART_InitStrue.USART_BaudRate=9600;  
    USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;  
    USART_InitStrue.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;  
    USART_InitStrue.USART_Parity=USART_Parity_No;  
    USART_InitStrue.USART_StopBits=USART_StopBits_1;  
    USART_InitStrue.USART_WordLength=USART_WordLength_8b;  
    USART_Init(USART2,&USART_InitStrue);

    USART_Cmd(USART2,ENABLE);

    USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);

//优先级设置
    NVIC_InitStrue.NVIC_IRQChannel=USART2_IRQn;  
    NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;  
    NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=0;  
    NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;  
    NVIC_Init(&NVIC_InitStrue);  

}  

//void USART2_IRQHandler(void)  
//{  

//     if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET)  
// {  
//     res= USART_ReceiveData(USART2);      
     USART_SendData(USART2,res);  
//  }  
//}  

void Bluetooth_SendData(char* data) 
{
    while (*data) 
        {
        USART_SendData(USART2, *data++);
        while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
    }
}

最后是主函数

main.c

#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "adc.h"
#include "hc05.h"

#define BUFFER_SIZE 100

char buffer[BUFFER_SIZE];

int main(void)
{
    float ad = 0;
    My_USART2_Init();
    delay_init();
    uart_init(115200);
    ADC_Pin_Init();
    while(1)
    {
               if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0 && 0 == GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0))
        {
           ad = ADC_Trans();
           snprintf(buffer, BUFFER_SIZE, "ad0 Data: %f\r\nfire\r\nbright\r\n", ad);        
           Bluetooth_SendData(buffer);
           while(USART_GetFlagStatus(USART2,USART_FLAG_TC)!=SET);
           delay_ms(1000);
        }
            else if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==1 && 0 == GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0))
        {
           ad = ADC_Trans();
           snprintf(buffer, BUFFER_SIZE, "ad0 Data: %f\r\nfire\r\ndarkness\r\n", ad);        
           Bluetooth_SendData(buffer);
           while(USART_GetFlagStatus(USART2,USART_FLAG_TC)!=SET);
           delay_ms(1000);                    
        }
           else if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==1 && 1 == GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0))
        {
           ad = ADC_Trans();
           snprintf(buffer, BUFFER_SIZE, "ad0 Data: %f\r\nfireless\r\ndarkness\r\n", ad);        
           Bluetooth_SendData(buffer);
           while(USART_GetFlagStatus(USART2,USART_FLAG_TC)!=SET);
           delay_ms(1000);            
        }
           else if( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0 && 1 == GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0))
        {
           ad = ADC_Trans();
           snprintf(buffer, BUFFER_SIZE, "ad0 Data: %f\r\nfireless\r\nbright\r\n", ad);        
           Bluetooth_SendData(buffer);
           while(USART_GetFlagStatus(USART2,USART_FLAG_TC)!=SET);
           delay_ms(1000);            
        }            
        delay_ms(100);  
    }
}

主函数比较复杂,实现的功能主要是实时显示烟雾浓度、是否有光和是否有火,可以在这个基础上进行修改和删减。由于是写记录时稍加修改后的代码,可能有一定的小问题,如果遇到问题或者需要源码可以评论交流一下。