STM32与ESP8266实现串口通信

05-28 1434阅读

目录

  • 写在前面
  • ESP8266端数据接收与输出
    • ESP8266端数据接收
    • ESP8266端数据输出
    • STM32端数据接收与输出
      • STM32端数据接收
      • STM32端数据输出
      • 实现结果

        写在前面

        不少做物联网毕设的同学可能会遇到用STM32做控制ESP8266做联网的设计,但在实现两者的通信方面犯了难。本文针对该问题,提供了数据通信的方案,并成功实现两者间的数据通信。

        ESP8266端数据接收与输出

        ESP8266端数据接收

        该函数实现ESP8266从自定义串口上接收来自STM32的数据并通过ESP8266的硬件串口上输出数据

        #include 
        //自定义串口 (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端数据输出

        ESP8266数据输出非常简单,利用函数

        MySerial.println(data1);
        

        即可实现数据传输。

        STM32端数据接收与输出

        本文采用STM32的硬件串口三实现数据传输

        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  
        

        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端数据输出

        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

        实现结果

        STM32与ESP8266实现串口通信

        其中hello_world为STM32向ESP32发送的数据,I am fine 为ESP8266向STM32发送的数据

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]