STM32驱动BC26连接新版oneNET云平台
本次实验用到墨子号(移远)BC26连接OneNET云平台进行数据上传,在之前的文章已经介绍过了通过串口调试助手来实现BC26连接新版OneNET云平台,道理差不多,利用STM32驱动BC26连接云平台只不过是需要自己调用一些串口通信函数而已,网上资源丰富,当然也可以自己写。
一、硬件连接
SMT32F103VET6 | BC26 |
---|---|
5V | VIN |
GND | GND |
TX | RXD |
RX | TXD |
二、代码及介绍
- 串口初始化:程序中使用到串口1来打印出BC26模块返回的响应消息,串口2用来向BC26模块发送AT指令
usart.c
#include "usart.h"
#include "delay.h"
//C库
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
char RxCounter,RxBuffer[100]; //接收缓冲,最大USART_REC_LEN个字节.
//串口1初始化
void Usart1_Init(unsigned int baud)
{
GPIO_InitTypeDef gpio_initstruct;
USART_InitTypeDef usart_initstruct;
NVIC_InitTypeDef nvic_initstruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
//PA9 TXD
gpio_initstruct.GPIO_Mode = GPIO_Mode_AF_PP;
gpio_initstruct.GPIO_Pin = GPIO_Pin_9;
gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpio_initstruct);
//PA10 RXD
gpio_initstruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
gpio_initstruct.GPIO_Pin = GPIO_Pin_10;
gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpio_initstruct);
usart_initstruct.USART_BaudRate = baud;
usart_initstruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件流控
usart_initstruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //接收和发送
usart_initstruct.USART_Parity = USART_Parity_No; //无校验
usart_initstruct.USART_StopBits = USART_StopBits_1; //1位停止位
usart_initstruct.USART_WordLength = USART_WordLength_8b; //8位数据位
USART_Init(USART1, &usart_initstruct);
USART_Cmd(USART1, ENABLE); //使能串口
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //使能接收中断
nvic_initstruct.NVIC_IRQChannel = USART1_IRQn;
nvic_initstruct.NVIC_IRQChannelCmd = ENABLE;
nvic_initstruct.NVIC_IRQChannelPreemptionPriority = 0;
nvic_initstruct.NVIC_IRQChannelSubPriority = 2;
NVIC_Init(&nvic_initstruct);
}
//串口2初始化
void Usart2_Init(unsigned int baud)
{
GPIO_InitTypeDef gpio_initstruct;
USART_InitTypeDef usart_initstruct;
NVIC_InitTypeDef nvic_initstruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
//PA2 TXD
gpio_initstruct.GPIO_Mode = GPIO_Mode_AF_PP;
gpio_initstruct.GPIO_Pin = GPIO_Pin_2;
gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpio_initstruct);
//PA3 RXD
gpio_initstruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
gpio_initstruct.GPIO_Pin = GPIO_Pin_3;
gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpio_initstruct);
usart_initstruct.USART_BaudRate = baud;
usart_initstruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件流控
usart_initstruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //接收和发送
usart_initstruct.USART_Parity = USART_Parity_No; //无校验
usart_initstruct.USART_StopBits = USART_StopBits_1; //1位停止位
usart_initstruct.USART_WordLength = USART_WordLength_8b; //8位数据位
USART_Init(USART2, &usart_initstruct);
USART_Cmd(USART2, ENABLE); //使能串口
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //使能接收中断
nvic_initstruct.NVIC_IRQChannel = USART2_IRQn;
nvic_initstruct.NVIC_IRQChannelCmd = ENABLE;
nvic_initstruct.NVIC_IRQChannelPreemptionPriority = 0;
nvic_initstruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&nvic_initstruct);
}
/*
************************************************************
* 函数名称: Usart_SendString
*
* 函数功能: 串口数据发送
*
* 入口参数: USARTx:串口组
* str:要发送的数据
* len:数据长度
*
* 返回参数: 无
*
* 说明:
************************************************************
*/
void Usart_SendString(USART_TypeDef *USARTx, unsigned char *str, unsigned short len)
{
unsigned short count = 0;
for(; count < len; count++)
{
USART_SendData(USARTx, *str++); //发送数据
while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET); //等待发送完成
}
}
/*
************************************************************
* 函数名称: UsartPrintf
*
* 函数功能: 格式化打印
*
* 入口参数: USARTx:串口组
* fmt:不定长参
*
* 返回参数: 无
*
* 说明:
************************************************************
*/
void UsartPrintf(USART_TypeDef *USARTx, char *fmt,...)
{
unsigned char UsartPrintfBuf[296];
va_list ap;
unsigned char *pStr = UsartPrintfBuf;
va_start(ap, fmt);
vsnprintf((char *)UsartPrintfBuf, sizeof(UsartPrintfBuf), fmt, ap); //格式化
va_end(ap);
while(*pStr != 0)
{
USART_SendData(USARTx, *pStr++);
while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);
}
}
//串口1中断服务程序
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
{
USART_ClearFlag(USART1, USART_FLAG_RXNE);
}
}
//串口2中断服务程序
void USART2_IRQHandler(void)
{
char Res;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收模块返回的数据
{
Res=USART_ReceiveData(USART2);//接收模块的数据;
RxBuffer[RxCounter++] =USART_ReceiveData(USART2);//接收模块的数据
if(RxCounter>99)//长度自行设定
RxCounter=0;
}
}
//串口1打印数据
void Uart1_SendStr(char*SendBuf)
{
while(*SendBuf)
{
while((USART1->SR&0X40)==0);//等待发送完成
USART1->DR = (u8) *SendBuf;
SendBuf++;
}
}
- BC26初始化、MQTT初始化,以下代码中使用到的AT指令在之前的文章中已经介绍过了,在这里就不在做过多的介绍了,不太清除的朋友请看看前面的文章
strstr
()函数 是C/C++标准库中的一个字符串处理函数,用于在一个字符串中查找另一个子字符串的第一次出现位置。
bc26.c
#include "bc26.h"
#include "string.h"
#include "usart.h"
//C库
#include <string.h>
#include <stdio.h>
char *strx,*extstrx;
extern unsigned char RxBuffer[255],RxCounter;
void Clear_Buffer(void)//清空缓存
{
u8 i;
Uart1_SendStr((char*)RxBuffer);
for(i=0;i<255;i++)
RxBuffer[i]=0;//缓存
RxCounter=0;
}
//发送AT指令,
void BC26_SendCmd(char *cmd)
{
Usart_SendString(USART2, (unsigned char *)cmd, strlen((const char *)cmd));
}
void BC26_Init(void)
{
BC26_SendCmd("AT\r\n");
delay_ms(300);
strx=strstr((const char*)RxBuffer,(const char*)"OK");返回OK
Clear_Buffer(); //----------------------
while(strx==NULL)
{
Clear_Buffer(); //----------------------
BC26_SendCmd("AT\r\n");
delay_ms(300);
strx=strstr((const char*)RxBuffer,(const char*)"OK");//返回OK
}
BC26_SendCmd("AT+QSCLK=0\r\n"); //禁止休眠
delay_ms(300);
BC26_SendCmd("AT+CFUN=1\r\n"); //打开全功能模式
delay_ms(300);
BC26_SendCmd("AT+CIMI\r\n"); //获取卡号,类似是否存在卡的意思,比较重要
delay_ms(300);
strx=strstr((const char*)RxBuffer,(const char*)"460");//返460,表明识别到卡了
Clear_Buffer(); //----------------------
while(strx==NULL)
{
Clear_Buffer(); //----------------------
BC26_SendCmd("AT+CIMI\r\n");//获取卡号,类似是否存在卡的意思,比较重要。
delay_ms(300);
strx=strstr((const char*)RxBuffer,(const char*)"460");//返回OK,说明卡是存在的
}
BC26_SendCmd("AT+CGATT=1\r\n");//激活网络,PDP
delay_ms(300);
strx=strstr((const char*)RxBuffer,(const char*)"OK");//返OK
Clear_Buffer(); //----------------------
BC26_SendCmd("AT+CGATT?\r\n");//查询激活状态
delay_ms(300);
strx=strstr((const char*)RxBuffer,(const char*)"+CGATT: 1");//返1
Clear_Buffer(); //----------------------
while(strx==NULL)
{
Clear_Buffer(); //----------------------
BC26_SendCmd("AT+CGATT?\r\n");//获取激活状态
delay_ms(300);
strx=strstr((const char*)RxBuffer,(const char*)"+CGATT: 1");//返回1,表明注网成功
}
BC26_SendCmd("AT+CSQ\r\n");//查看获取CSQ值
delay_ms(300);
Clear_Buffer(); //----------------------
}
void MQTT_Init(void)
{
BC26_SendCmd("AT+QMTCFG=\"version\",0,4\r\n"); //设备版本
delay_ms(500);
BC26_SendCmd("AT+QMTCLOSE=0\r\n");//断开与MQTT服务器的连接
delay_ms(500);
Clear_Buffer(); //----------------------
BC26_SendCmd("AT+QMTOPEN=0,\"mqtts.heclouds.com\",1883\r\n");//连接MQTT服务器
delay_ms(500);
strx=strstr((const char*)RxBuffer,(const char*)"+QMTOPEN: 0,0");//看下返回状态
Uart1_SendStr("服务器连接中...\r\n");
while(strx==NULL)
{
strx=strstr((const char*)RxBuffer,(const char*)"+QMTOPEN: 0,0");//通过TCP方式去连接MQTT服务器
}
Uart1_SendStr("服务器连接成功!\r\n");
Clear_Buffer(); //----------------------
BC26_SendCmd("AT+QMTCONN=0,\"nbtest\",\"8F6MqH1dJG\",\"version=2018-10-31&res=products%2F8F6MqH1dJG%2Fdevices%2Fnbtest&et=1758687893&method=md5&sign=Ds8P1chJlCxyIO6%2BkPpL9Q%3D%3D\"\r\n");
delay_ms(500);
strx=strstr((const char*)RxBuffer,(const char*)"+QMTCONN: 0,0,0");//看下返回状态
while(strx==NULL)
{
strx=strstr((const char*)RxBuffer,(const char*)"+QMTCONN: 0,0,0");//看下返回状态
}
Clear_Buffer();
}
- 主函数的while中实现数据的发布,这只是数据发布的一种格式,还有多种格式可以发布数据,可以自己尝试哦
main.c
#include "sys.h"
#include "usart.h"
#include "bc26.h"
#include "delay.h"
// 初始化参数
int lux=45
;
int main(void)
{
unsigned short timeCount = 0; //发送间隔变量
delay_init(); //延时函数初始化
Usart1_Init(9600); //串口1初始化为9600
Usart2_Init(9600); //串口2初始化为9600
UsartPrintf(USART_DEBUG, " Hardware init OK\r\n");
BC26_Init();//对设备初始化
MQTT_Init();
while(1)
{
delay_ms(100);
if(++timeCount >= 500) 发送间隔5s
{
UsartPrintf(USART2,"AT+QMTPUB=0,0,0,0,\"$sys/8F6MqH1dJG/nbtest/dp/post/json\",{\"id\":111,\"dp\":{\"lux\":[{\"v\":%d}]}}\"\r\n",lux);
delay_ms(300);
Clear_Buffer();
}
}
}
-
结果显示
-
连接服务器成功
-
数据发送成功
-
云平台数据显示
-