赞
踩
不少做物联网毕设的同学可能会遇到用STM32做控制ESP8266做联网的设计,但在实现两者的通信方面犯了难。本文针对该问题,提供了数据通信的方案,并成功实现两者间的数据通信。
该函数实现ESP8266从自定义串口上接收来自STM32的数据并通过ESP8266的硬件串口上输出数据
#include <SoftwareSerial.h> //自定义串口 (RX, TX) # D6接TX D7接RX SoftwareSerial MySerial(D6, D7); String data1; // 接受外部数据 String receive1() { // 接受外部数据 String data; if (MySerial.available()) { data = (char)MySerial.read(); data += receive1(); } return data; } void setup() { Serial.begin(115200); //内部串口初始化 MySerial.begin(115200); //外部串口初始化 } void loop() { data1 = receive1(); if (data1 != "") { Serial.println(data1); //接受的外部数据内部打印 } MySerial.println("i am fine"); delay(1000); }
其中MySerial.println(“i am fine”); 可以实现ESP8266向STM32发送 I am fine
ESP8266数据输出非常简单,利用函数
MySerial.println(data1);
即可实现数据传输。
本文采用STM32的硬件串口三实现数据传输
usart3.c文件代码
#include "sys.h" #include "usart.h" #include "string.h" #include "delay.h" #include "stdarg.h" #include "stdio.h" u8 USART3_RX_BUF[USART3_MAX_RECV_LEN]; //接收缓冲,最大USART2_MAX_RECV_LEN个字节. u8 USART3_TX_BUF[USART3_MAX_SEND_LEN]; //发送缓冲,最大USART2_MAX_SEND_LEN字节 u16 USART3_RX_STA; //接收数据状态 u8* temp[4]; int i = 0; void usart3_Init(u32 bound) { NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // GPIOA时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); //串口3时钟使能 USART_DeInit(USART3); //复位串口2 //USART2_TX PB10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB10 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB11 //USART2_RX PB11 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB11 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); //初始化串口2 USART_Cmd(USART3, ENABLE); //使能串口 //使能接收中断 USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启中断 //设置中断优先级 NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1 ; //抢占优先级3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 USART3_RX_STA = 0; //清零 } void USART3_IRQHandler(void) { u8 res; if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)//接收到数据 { res = USART_ReceiveData(USART3); if((USART3_RX_STA & 0x8000) == 0) //接收未完成 { if(USART3_RX_STA & 0x4000) //接收到了0x0d { if(res != 0x0a)USART3_RX_STA = 0; //接收错误,重新开始 else USART3_RX_STA |= 0x8000; //接收完成了 } else //还没收到0X0D { if(res == 0x0d)USART3_RX_STA |= 0x4000; else { USART3_RX_BUF[USART3_RX_STA & 0X3FFF] = res ; USART3_RX_STA++; if(USART3_RX_STA > (USART3_MAX_RECV_LEN - 1))USART3_RX_STA = 0; //接收数据错误,重新开始接收 } } } } if(USART3_RX_STA & 0x8000) { //原始串口三数据 printf("%s\r\n", USART3_RX_BUF); USART3_RX_STA = 0; } } /***************************************************** * 函数:串口二发送字节 * 参数:byte---要发送的字节 * 功能: * 备注: *****************************************************/ void usart3_Send_Byte(uint8_t byte) //串口发送一个字节 { while(USART_GetFlagStatus(USART3, USART_FLAG_TC) != SET); //等待发送完成 检测 USART_FLAG_TC 是否置1 USART_SendData(USART3, byte); //通过库函数发送数据 USART_ClearITPendingBit(USART3, USART_IT_TC);//清除串口3发送完成中断线路挂起位 } /***************************************************** * 函数:串口二发送字符串函数 * 参数:string---要发送的字符串 length--要发送字符串的长度 * 功能: * 备注: *****************************************************/ void usart3_Send_String(uint8_t* string, uint8_t length) { uint8_t i; for(i = 0; i < length; i++) usart3_Send_Byte(*string++);//发送一个字节 }
usart3.h文件代码
#ifndef __USART3_H #define __USART3_H #include "stdio.h" #include "sys.h" #define USART3_MAX_RECV_LEN 400 //最大接收缓存字节数 #define USART3_MAX_SEND_LEN 400 //最大发送缓存字节数 #define USART3_RX_EN 1 //0,不接收;1,接收. extern u8 USART3_RX_BUF[USART3_MAX_RECV_LEN]; //接收缓冲,最大USART2_MAX_RECV_LEN字节 extern u8 USART3_TX_BUF[USART3_MAX_SEND_LEN]; //发送缓冲,最大USART2_MAX_SEND_LEN字节 extern u16 USART3_RX_STA; //接收数据状态 void usart3_Init(u32 bound); void usart3_Send_Byte(uint8_t byte); void usart3_Send_String(uint8_t *string, uint8_t length); #endif
其中接收来自ESP8266串口数据的代码在usart3.husart3的中断里
printf("%s\r\n", USART3_RX_BUF);
STM32串口3输出通过
void usart3_Send_String(uint8_t *string, uint8_t length);
函数实现。其中string为幺传输的字符串,length为输出的字符串长度。
其中main函数可以写成
int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级 delay_init(); //延时初始化 uart_init(115200); //串口1初始化,发送日志信息 usart3_Init(115200); //串口3初始化,用来与ESP8266通信 LED_Init(); //内置LED初始化 printf("stm32 is ok\r\n"); while(1) { usart3_Send_String("hello_word", 10); delay_ms(1000); } }
可以实现STM32向ESP8266发送hello_world
其中hello_world为STM32向ESP32发送的数据,I am fine 为ESP8266向STM32发送的数据
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。