目录
准备材料
步骤
stm32f103c8t6
在stm32clube里创建项目
先配置调试接口SYS(博主用的是stlink,选的是SW),配置外部时钟源RCC,总线时钟频数72
配置串口(波特率为115200)
编辑 看各自需要配置不同硬件的io口
esp8266
代码
订阅串口数据,在usart.h里,可以更改
先配置usart2中断函数,在main.c里
在main函数里配置中断优先级,和使能串口中断
再写按顺序发送AT指令来初始化esp8266函数,在esp8266.c里
我们在发送指令的同时,要判断它是否成功配置指令,在串口中断函数里有判断,来改变标志位,获取标志位来判断是否成功配置指令
构建发送到onenet的数据,最后的数据要json格式
发送onenet数据
main主函数
完整文件在标题下,博主的加了一些其他文件,你们要加到自己的文件里就把esp8266.c和esp8266.c拉到你们的项目中调用就好
准备材料
- stm32f103c8t6
- esp8266
- 各种器件,例如温湿度,烟雾,灯光,按钮什么都可以(只是让我们有信息可以传,没有就传数字来测试)
- onenet的配置请看前面发的文章物联网平台:网络调试助手+HTTP+上传数据到onenet-CSDN博客
步骤
stm32f103c8t6
在stm32clube里创建项目
先配置调试接口SYS(博主用的是stlink,选的是SW),配置外部时钟源RCC,总线时钟频数72
配置串口(波特率为115200)
看各自需要配置不同硬件的io口
esp8266
大家可以先学习一下AT指令,这里简单讲一下案例要用的(下面返回值空的是空行)
需要先配置好波特率,esp8266接线也是用ttl,用串口调试助手,选择厂家初始的波特率,然后就可以调试esp8266了 ,修改波特率指令是(记住勾选新行)
AT+UART=9600,8,1,0,0
代码
我们要用stm32的usart2来发送AT指令来控制esp8266来连接网络
订阅串口数据,在usart.h里,可以更改
//串口2
//串口接收缓存(1字节)
uint8_t buf1=0;
//定义最大接收字节数 200,可根据需求调整
#define UART2_REC_LEN 200
// 接收缓冲, 串口接收到的数据放在这个数组里,最大UART2_REC_LEN个字节
uint8_t UART2_RX_Buffer[UART2_REC_LEN];
// 接收状态bit15, 接收完成标志,bit14, 接收到0x0d,bit13~0, 接收到的有效字节数目
uint16_t UART2_RX_STA=0;
先配置usart2中断函数,在main.c里
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
// 判断中断是由哪个串口触发的
if(huart->Instance == USART2)
{
// 判断接收是否完成(UART1_RX_STA bit15 位是否为1)
if((UART2_RX_STA & 0x8000) == 0)
{
// 如果已经收到了 0x0d (回车),
if(UART2_RX_STA & 0x4000)
{
// 则接着判断是否收到 0x0a (换行)
if(buf1 == 0x0a)
{
// 如果 0x0a 和 0x0d 都收到,则将 bit15 位置为1
UART2_RX_STA |= 0x8000;
// 查看是否收到 WIFI GOT IP
if(!strcmp((char *)UART2_RX_Buffer, "WIFI GOT IP"))
AT_Connect_Net_Flag = 1;
// 查看是否收到 OK
if(!strcmp((char *)UART2_RX_Buffer, "OK"))
AT_OK_Flag = 1;
if(!strcmp((char *)UART2_RX_Buffer, ">"))
fuhao_Connect_Flag = 1;
// 查看是否收到 FAIL
if(!strcmp((char *)UART2_RX_Buffer, "CONNECT"))
Client_Connect_Flag = 1;
if(!strcmp((char *)UART2_RX_Buffer, "{\"errno\":0,\"error\":\"succ\""))
succ_Flag = 1;
memset(UART2_RX_Buffer, 0, UART2_REC_LEN);
UART2_RX_STA = 0;
}
else
// 否则认为接收错误,重新开始
UART2_RX_STA = 0;
}
else // 如果没有收到了 0x0d (回车)
{
//则先判断收到的这个字符是否是 0x0d (回车)
if(buf1 == 0x0d)
{
// 是的话则将 bit14 位置为1
UART2_RX_STA |= 0x4000;
}
else
{
// 否则将接收到的数据保存在缓存数组里
UART2_RX_Buffer[UART2_RX_STA & 0X3FFF] = buf1;
UART2_RX_STA++;
// 如果接收数据大于UART1_REC_LEN(200字节),则重新开始接收
if(UART2_RX_STA > UART2_REC_LEN - 1)
UART2_RX_STA = 0;
}
}
}
// 重新开启中断
HAL_UART_Receive_IT(&huart2, &buf1, 1);
}
}
在main函数里配置中断优先级,和使能串口中断
HAL_NVIC_SetPriority(SysTick_IRQn,0,0);//设置特定中断的优先级
HAL_UART_Receive_IT(&huart2, &buf1, 1);
再写按顺序发送AT指令来初始化esp8266函数,在esp8266.c里
#define ESP8266_WIFI_INFO "AT+CWJAP=\"Reds\",\"23333334\"\r\n"
#define ESP8266_ONENET_INFO "AT+CIPSTART=\"TCP\",\"183.230.40.33\",80\r\n"
//初始化ESP8266
void ESP8266_Init(void)
{
while(ESP8266_SendCmd("AT\r\n", 1))
HAL_Delay(1500);
HAL_Delay(2000);
while(ESP8266_SendCmd("AT+CWMODE=1\r\n", 1))
HAL_Delay(1500);
HAL_Delay(2000);
while(ESP8266_SendCmd(ESP8266_WIFI_INFO, 2))
HAL_Delay(1500);
HAL_Delay(2000);
while(ESP8266_SendCmd(ESP8266_ONENET_INFO, 3))
HAL_Delay(1500);
HAL_Delay(2000);
}
我们在发送指令的同时,要判断它是否成功配置指令,在串口中断函数里有判断,来改变标志位,获取标志位来判断是否成功配置指令
int AT_OK_Flag = 0; //OK返回值的标志位
int AT_Connect_Net_Flag = 0; //WIFI GOT IP返回值的标志位
int Client_Connect_Flag = 0; //连接tcp服务端标志位
int fuhao_Connect_Flag = 0; //进入发送数据标志位
int succ_Flag = 0; //发送成功标志位
//发送命令 cmd 命令 res要选择什么标志位
int ESP8266_SendCmd(char *cmd,int res)
{
unsigned char timeOut = 200;
HAL_UART_Transmit(&huart2, (unsigned char *)cmd, strlen((const char *)cmd), 0xffff);
if(res == 1)
{
while(!AT_OK_Flag&&timeOut--) HAL_Delay(50);
if(AT_OK_Flag)
{
AT_OK_Flag = 0;
return 0;
}
}
else if(res == 2)
{
while( ( !AT_OK_Flag || !AT_Connect_Net_Flag ) && timeOut--) HAL_Delay(50);
if(fuhao_Connect_Flag||AT_OK_Flag)
{
AT_OK_Flag = 0;
AT_Connect_Net_Flag = 0;
return 0;
}
}
else if(res == 3)
{
while(!Client_Connect_Flag&&timeOut--) HAL_Delay(50);
if(Client_Connect_Flag)
{
Client_Connect_Flag = 0;
return 0;
}
}
else if(res == 4)
{
while( ( !AT_OK_Flag || !fuhao_Connect_Flag ) && timeOut--) HAL_Delay(50);
if(fuhao_Connect_Flag||AT_OK_Flag)
{
AT_OK_Flag = 0;
fuhao_Connect_Flag = 0;
return 0;
}
}
return 1;
}
构建发送到onenet的数据,最后的数据要json格式
//设备id
#define DEVID "1026566033"
//密钥
#define APIKEY "C7elqJfUjB=ynk=fpdQVJZ7yTfY="
void OneNet_FillBuf(char *buf)
{
char data[24];
char json[128];
memset(data, 0, sizeof(data));
memset(json, 0, sizeof(json));
strcpy(json, "{");
memset(data, 0, sizeof(data));
sprintf(data, "\"Test1\":123,");
strcat(json, data);
memset(data, 0, sizeof(data));
sprintf(data, "\"Test2\":789,");
strcat(json, data);
strcat(json, "}");
sprintf(buf, "POST /devices/%s/datapoints?type=3 HTTP/1.1\r\napi-key:%s\r\nHost:api.heclouds.com\r\nConnection:close\r\n"
"Content-Length:%d\r\n\r\n",
DEVID, APIKEY, strlen(json));
strcat(buf, json);
}
发送onenet数据
void OneNet_SendData(void)
{
char buf[256];
memset(buf, 0, sizeof(buf));
OneNet_FillBuf(buf);
ESP8266_SendData((unsigned char *)buf, strlen(buf));
}
main主函数
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM2_Init();
MX_USART2_UART_Init();
MX_TIM4_Init();
/* USER CODE BEGIN 2 */
HAL_NVIC_SetPriority(SysTick_IRQn,0,0);//设置特定中断的优先级
HAL_UART_Receive_IT(&huart2, &buf1, 1);
int i=0;
int flag=0;
ESP8266_Init();
OneNet_SendData();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
i++;
if(i == 20)
{
i=0;
if(flag==0)
{
open_led();
flag =1;
}
else
{
close_led();
flag =0;
}
HAL_Delay(1000);
}
}
/* USER CODE END 3 */
}