這里簡單的記錄STM32+ESP8266配置
MCU:STM32F030R8
ESP8266模塊:ESP-01S
ESP8266工作模式:WIFI AP、TCP Client
MCU、ESP8266互連USART:USART1
MCU信息打印USART:USART2(下面有些代碼涉及USART2,可以忽略,因為現在是從項目代碼中復制出來的,處理干凈感覺麻煩)
以下只針對ESP8266相關代碼的
1. 在esp8266.h中增加如下代碼
1 #ifndef __ESP8266_H 2 #define __ESP8266_H 3 4 #include "stm32f0xx.h" 5 #include "stdio.h" 6 #include "string.h" 7 #include "stm32f0xx_it.h" 8 9 extern char esp8266_cmd[100]; //用於儲存ESP8266命令,這里沒有用到 10 extern char esp8266_buff[100]; //用於存儲ESP8266指令返回的信息 11 extern uint8_t i; //esp8266_buff索引變量 12 13 void USART1_GPIO_Config(void); //USART1用到的GPIO配置TX--PA9,RX--PA10 14 void USART1_Config(uint32_t BaudRate); //USART1配置 15 void ESP8266_Init(void); //ESP8266各項初始化 16 void USART1_Send_Byte(USART_TypeDef* pUSARTX, uint8_t Data); //USART1單個字節發送函數 17 void ESP8266_Printf(char* str); //向USART1發送多個字符 18 void ESP8266_Config(void); //ESP8266工作模式配置 19 void USART1_NVIC_Config(void); //USART1中斷優先級配置 20 void UART_DMA_Config(void); //USART1 DMA配置 21 void esp8266_send_cmd(char * cmd, char * ack); //ESP8266命令發送函數 22 void esp8266_exit_trans(void); //ESP8266退出透傳模式 23 24 #endif
2. 在esp8266.c中增加如下代碼
1 #include "esp8266.h" 2 3 4 char esp8266_cmd[100] = 0; 5 char esp8266_buff[100] = 0; 6 uint8_t i = 0; 7 8 9 void USART1_GPIO_Config(void) 10 { 11 12 13 14 GPIO_InitTypeDef Uart_GPIO_InitStructure; 15 16 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE); 17 GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1); //Tx 18 GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1); //Rx 19 Uart_GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; 20 21 Uart_GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 22 Uart_GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 23 Uart_GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; 24 Uart_GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 25 26 GPIO_Init(GPIOA, &Uart_GPIO_InitStructure); 27 28 29 30 31 32 33 34 } 35 36 37 void USART1_Config(uint32_t BaudRate) 38 { 39 40 USART_InitTypeDef Uart_Config_Struct; 41 42 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); 43 44 45 Uart_Config_Struct.USART_BaudRate = BaudRate; 46 Uart_Config_Struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 47 Uart_Config_Struct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 48 Uart_Config_Struct.USART_Parity = USART_Parity_No; 49 Uart_Config_Struct.USART_StopBits = USART_StopBits_1; 50 Uart_Config_Struct.USART_WordLength = USART_WordLength_8b; 51 52 53 USART_Init(USART1, &Uart_Config_Struct); 54 55 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); 56 57 USART_Cmd(USART1, ENABLE); 58 59 60 } 61 62 63 64 65 void ESP8266_Init(void) 66 { 67 USART1_GPIO_Config(); 68 69 USART1_Config(115200); 70 USART1_NVIC_Config(); 71 ESP8266_Config(); 72 UART_DMA_Config(); 73 74 } 75 76 77 78 79 void USART1_Send_Byte(USART_TypeDef* pUSARTX, uint8_t Data) 80 { 81 82 83 pUSARTX->TDR = (Data & (uint16_t)0x01FF); 84 85 while(USART_GetFlagStatus(pUSARTX, USART_FLAG_TXE) == RESET); 86 87 } 88 89 90 91 void ESP8266_Printf(char* str) 92 { 93 int i,temp; 94 95 temp = strlen(str) + 1; 96 97 98 for(i = 0; i < temp; i++) 99 { 100 USART1_Send_Byte(USART1, *(str + i)); 101 102 103 } 104 105 while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); 106 107 108 } 109 110 111 112 113 114 void ESP8266_Config(void) 115 { 116 117 esp8266_exit_trans(); //無論ESP8266是否處於透傳狀態,一概執行一下退出透傳指令, 118 //此語句實際上應該不需要,但調試時,若沒有此語句很麻煩,因為 119 //執行一次透傳后,后面會一直是這個狀態,需要重新上電才行 120 121 esp8266_send_cmd("AT+CWMODE=2\r\n","OK"); 122 esp8266_send_cmd("AT+RST\r\n","ready"); //這里沒有使用"OK"字符進行確認是因為esp8266_buff 123 //只存儲100個字符,一旦復位會有操作100個字符, 124 //“OK”會被沖掉,所以使用最后的“ready”來確認 125 126 esp8266_send_cmd("AT+CWSAP=\"HM_WIFI\",\"12345678\",1,4\r\n","OK"); 127 esp8266_send_cmd("AT+CIPMUX=0\r\n","OK"); 128 esp8266_send_cmd("AT+CIPSTART=\"TCP\",\"192.168.4.2\",8086\r\n","CONNECTED"); 129 esp8266_send_cmd("AT+CIPMODE=1\r\n","OK"); 130 esp8266_send_cmd("AT+CIPSEND\r\n","OK"); 131 132 133 134 135 } 136 137 138 void USART1_NVIC_Config(void) 139 { 140 NVIC_InitTypeDef NVIC_struct; 141 142 NVIC_struct.NVIC_IRQChannel = USART1_IRQn; 143 NVIC_struct.NVIC_IRQChannelCmd = ENABLE; 144 NVIC_struct.NVIC_IRQChannelPriority = 1; 145 146 147 NVIC_Init(&NVIC_struct); 148 149 } 150 151 152 153 void esp8266_send_cmd(char * cmd, char * ack) 154 { 155 while(1) 156 { 157 i = 0; 158 memset(esp8266_buff,0,sizeof(esp8266_buff)); 159 160 USART2_Printf(cmd); 161 ESP8266_Printf(cmd); 162 delay(5000000); 163 164 165 if(strstr(esp8266_buff, ack)) 166 break; 167 168 } 169 170 } 171 172 173 //退出透傳使用這種方式,ESP8266_Printf這個函數發送問題,無法退出,因為暫時不知道 174 void esp8266_exit_trans(void) 175 { 176 177 178 USART1_Send_Byte(USART1,'+'); 179 USART1_Send_Byte(USART1,'+'); 180 USART1_Send_Byte(USART1,'+'); 181 182 delay(5000000); 183 esp8266_send_cmd("AT\r\n","OK"); 184 185 }
3. 在stm32f0xx_it.h增加如下代碼
1 #include "esp8266.h" 2 #include "usart2.h" 3 #include "esp8266.h" 4 #include "stdio.h" 5 6 7 8 9 void USART1_IRQHandler(void); 10 void USART2_IRQHandler(void);
4. 在stm32f0xx_it.c增加如下代碼
1 void USART1_IRQHandler(void) 2 { 3 4 5 if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET) 6 { 7 esp8266_buff[i++] = USART_ReceiveData(USART1); 8 9 10 } 11 12 13 }
注意:切不可在中斷函數中給USART發消息,不然會進入死循環,因為在這里發送,中斷USART就會收到消息進入中斷,中斷中又繼續給自己發送消息,所以會進入死循環,至於為什么另外一種發送可以發送,我想因為是操作了一些寄存器的值,這里我沒有去研究,我只在下面這篇文章稍微記錄了下,算是給自己提個醒。
