前言
- 本次示例为标准库的示例
- 记录ESP8266的透传和TCP CLient的示例
- 使用的芯片为 STM32F103VET6,开发板使用的野火指南者
- Clion开发STM32之驱动开发(ESP8266 WIFI通讯模块)
引脚说明
/*******************************************************************************
* @brief 引脚说明
* CH_PD----PB8
* RST-----PB9
* 通讯口--串口3
******************************************************************************/
标准库
串口3驱动
头文件
/********************************串口3**********************************************/
#define COM3_IT_RXNE BSP_IT_ENABLE /* 使能串口接收中断*/
#define COM3_IT_TXE BSP_IT_DISABLE /* 使能串口发送中断*/
#define COM3_IT_IDLE BSP_IT_ENABLE /* 使能串口总线空闲中断*/
#define COM3_IT_PreemptPriority (0) // 抢占优先级
#define COM3_IT_SubPriority (0) // 响应优先级
void bsp_Serial3_Init(uint32_t baud);
void bsp_COM3_Init(USART_InitTypeDef *cnf);
源文件
void bsp_COM3_Init(USART_InitTypeDef *cnf) {
// 打开串口外设的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
// 将USART Tx的GPIO配置为推挽复用模式
gpio_init(GPIOB, GPIO_Pin_10, GPIO_Mode_AF_PP, GPIO_Speed_50MHz);
// 将USART Rx的GPIO配置为浮空输入模式
gpio_init(GPIOB, GPIO_Pin_11, GPIO_Mode_IN_FLOATING, GPIO_Speed_50MHz);
// 完成串口的初始化配置
USART_Init(USART3, cnf);
#if COM3_IT_RXNE || COM3_IT_TXE || COM3_IT_IDLE
nvic_config_set(USART3_IRQn, COM3_IT_PreemptPriority, COM3_IT_SubPriority);
#endif
#if COM3_IT_RXNE // 使能串口接收中断
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
#endif
#if COM3_IT_TXE // 使能串口发送中断
USART_ITConfig(USART3, USART_IT_TXE, ENABLE);
#endif
#if COM3_IT_IDLE
USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);
#endif
// 使能串口
USART_Cmd(USART3, ENABLE);
}
esp8266接口实现
/*******************************************************************************
* Copyright (c) [scl]。保留所有权利。
* 本文仅供个人学习和研究使用,禁止用于商业用途。
* @brief 引脚说明
* CH_PD----PB8
* RST-----PB9
* 通讯口--串口3
******************************************************************************/
#include "module_esp8266.h"
#include "bsp_gpio.h"
#include "bsp_serial.h"
esp8266_frame_t esp8266_frame_obj = {0};
/*************************************************外部实现接口***************************************************/
/**
* @brief esp8266 驱动外设初始化
*/
void esp8266_driver_init() {
/*配置 CH_PD 引脚*/
gpio_init(GPIOB, GPIO_Pin_8, GPIO_Mode_Out_PP, GPIO_Speed_50MHz);
/* 配置 RST 引脚*/
gpio_init(GPIOB, GPIO_Pin_9, GPIO_Mode_Out_PP, GPIO_Speed_50MHz);
bsp_Serial3_Init(115200);
pin_high(GPIOB, GPIO_Pin_9);
pin_high(GPIOB, GPIO_Pin_8);
}
/**
* @brief esp8266 复位引脚
* @param flag true: 置高; false: 置低
*/
void esp8266_rst_pin(bool flag) {
if (flag) {
pin_high(GPIOB, GPIO_Pin_9);
} else {
pin_low(GPIOB, GPIO_Pin_9);
}
}
/**
* @brief esp8266 使能引脚
* @param flag true: 使能
*/
void esp8266_ch_enable(bool flag) {
if (flag) {
pin_high(GPIOB, GPIO_Pin_8);
} else {
pin_low(GPIOB, GPIO_Pin_8);
}
}
/**
* @brief esp8266 发送数据
* @param data
* @param len
*/
void esp8266_send(void *data, uint16_t len) {
bsp_SerialSend(COM3, data, len);
}
/**
* @brief esp8266 接收数据
* @return 接收数据
*/
char *esp8266_rec() {
if (esp8266_frame_obj.InfBit.frame_finished_flag != 0) {
esp8266_frame_obj.rx_buf[esp8266_frame_obj.InfBit.frame_len] = '\0';
esp8266_frame_obj.InfAll = 0;// 清除一次标志位
return esp8266_frame_obj.rx_buf;
}
return NULL;
}
void esp8266_clear_buf(void) {
esp8266_frame_obj.InfAll = 0;
}
char esp8266_buf[200] = {0};
char *esp8266_get_cmd_buf() {
return esp8266_buf;
}
esp8266示例(仿照RT-Thread)
/*******************************************************************************
* Copyright (c) [scl]。保留所有权利。
* 本文仅供个人学习和研究使用,禁止用于商业用途。
******************************************************************************/
#include "app_gb_conf.h"
#include "module_esp8266.h"
extern esp8266_frame_t esp8266_frame_obj;
static void invoke_before(void) {
esp8266_set_delay_call(sys_delay);
}
//#define ESP866_Base_Test
#ifdef ESP866_Base_Test
static void invoke(void) {
esp8266_driver_init();
}
static void invoke_after(void) {
esp8266_clear_buf();
esp8266_rst(true, -1);
sys_delay(1000);
esp8266_link_status flag = esp8266_read_link_status(500);
os_ps("esp8266_link_status :%d\r\n", flag);
while (true) {
char *rec_msg = esp8266_rec();
if (rec_msg != NULL) {
os_ps("rec_msg:%s", rec_msg);
}
sys_delay(10);
}
}
void USART3_IRQHandler(void) {
uint8_t ucTemp;
if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) {
ucTemp = (uint16_t) (USART3->DR & (uint16_t) 0x01FF);
if (esp8266_frame_obj.InfBit.frame_len < (RX_BUF_MAX_LEN - 1)) {
esp8266_frame_obj.rx_buf[esp8266_frame_obj.InfBit.frame_len++] = ucTemp;
}
}
//数据帧接收完毕
if (USART_GetITStatus(USART3, USART_IT_IDLE) == SET) {
esp8266_frame_obj.InfBit.frame_finished_flag = 1;
//由软件序列清除中断标志位(先读USART_SR,然后读USART_DR)
ucTemp = USART3->SR;
ucTemp = USART3->DR;
}
}
// 导出配置执行函数
CMD_EXPORT(esp_serial_test, invoke_before, invoke, invoke_after);
#else
#define WIFI_SSID "wifi ssid"
#define WIFI_PWD "wifi pwd"
#define TCP_SERVER_IP "192.168.199.194"
#define TCP_SERVER_PORT 8000
static volatile bool ucTcpClosedFlag = false;
static void invoke(void) {
esp8266_driver_init();
}
static void invoke_after(void) {
/*使能esp8266引脚*/
esp8266_ch_enable(true);
if (esp8266_at_cmd_test(10, 500)) {
os_ps("esp8266_at_cmd_test ok\r\n");
while (!esp8266_dhcp_cur_set(sta_mode, true, -1));
os_ps("esp8266_dhcp_cur_set ok\r\n");
/** 设置*/
while (!esp8266_mode_cur_set(sta_mode, -1));
os_ps("esp8266_mode_cur_set ok\r\n");
/*连接WiFi*/
while (!esp8266_joinAp_cur_set(WIFI_SSID, WIFI_PWD, NULL, -1));
os_ps("esp8266_joinAp_cur_set ok\r\n");
/*禁止多连接*/
while (!esp8266_multi_connect_set(false, -1));
os_ps("esp8266_multi_connect_set ok\r\n");
/*连接TCP服务器*/
while (!esp8266_link_tcp_server(single_id_0, TCP_SERVER_IP, TCP_SERVER_PORT, -1));
os_ps("esp8266_link_server ok\r\n");
/*设置透传模式*/
while (!esp8266_transmission_mode_set(true, -1));
os_ps("esp8266 config ok\r\n");
/*检测TCP连接状态*/
char *msg = "hello word\r\n";
while (true) {
while (true) {
char *rec_msg = esp8266_rec();
if (rec_msg != NULL) {
os_ps("%s", rec_msg);
esp8266_transmission_mode_send(rec_msg, -1);
}
sys_delay(10);
}
}
}
}
void USART3_IRQHandler(void) {
uint8_t ucTemp;
if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) {
ucTemp = (uint16_t) (USART3->DR & (uint16_t) 0x01FF);
if (esp8266_frame_obj.InfBit.frame_len < (RX_BUF_MAX_LEN - 1)) {
esp8266_frame_obj.rx_buf[esp8266_frame_obj.InfBit.frame_len++] = ucTemp;
}
}
//数据帧接收完毕
if (USART_GetITStatus(USART3, USART_IT_IDLE) == SET) {
esp8266_frame_obj.InfBit.frame_finished_flag = 1;
//由软件序列清除中断标志位(先读USART_SR,然后读USART_DR)
ucTemp = USART3->SR;
ucTemp = USART3->DR;
ucTcpClosedFlag = strstr(esp8266_frame_obj.rx_buf, ESP_CLOSED_MSG) != NULL;
}
}
// 导出配置执行函数
CMD_EXPORT(esp_serial_test, invoke_before, invoke, invoke_after);
#endif
串口1的中断函数(实现透传)
void USART1_IRQHandler(void) {
uint8_t ucTemp;
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
ucTemp = USART_ReceiveData(USART1);
USART3->DR = (ucTemp & (uint16_t) 0x01FF);
}
// if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET) {
// u8 sendData;
// size_t sz = lwrb_read(&rb_obj, &sendData, 1);
// if (sz == 0) {
// USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
// } else {
// USART_SendData(USART1, sendData);
// }
//
// }
}