上一篇: Clion开发STM32之ESP8266系列(三)
源码
/*******************************************************************************
* @author scl
* @email [email protected]
* @brief 实现esp8266的驱动
******************************************************************************/
#include "module_esp8266.h"
#include "bsp.h"
extern data_frame_t esp_rx_frame;
static void sys_delay(uint32_t ms) {
HAL_Delay(ms);
}
/**
* @brief esp8266 驱动外设初始化
*/
void esp8266_driver_init() {
/*设置系esp8266延时回调*/
esp8266_set_delay_call(sys_delay);
/*配置 CH_PD 引脚*/
gpio_init(GPIOB, GPIO_PIN_8, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_HIGH);
/* 配置 RST 引脚*/
gpio_init(GPIOB, GPIO_PIN_9, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_HIGH);
/*串口配置*/
com3_init(115200);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8 | GPIO_PIN_9, GPIO_PIN_SET);
/*开启串口中断*/
UART_ENABLE_IT(USART3, UART_IT_RXNE); /** 开启串口中断*/
UART_ENABLE_IT(USART3, UART_IT_IDLE); /** 开启串口空闲中断*/
}
/**
* @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_8);
}
}
/**
* @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) {
HAL_UART_Transmit(com_handle_get(com3), data, len, 1000);
}
/**
* @brief 清空接收缓冲区
*/
void esp8266_clear_buf(void) {
esp_rx_frame.InfAll = 0;
}
/**
* @brief esp8266 接收数据
* @return 接收数据
*/
char *esp8266_rec() {
if (esp_rx_frame.InfBit.frame_finished_flag != 0) {
/*添加结束符*/
esp_rx_frame.p_rx_buf[esp_rx_frame.InfBit.frame_len] = '\0';
esp_rx_frame.InfAll = 0;// 清除一次标志位
return esp_rx_frame.p_rx_buf;
}
return NULL;
}
/**
* @brief esp8266 构造指令的缓存区
* @return
*/
char *esp8266_get_cmd_buf() {
static char esp8266_buf[200] = {0};
return esp8266_buf;
}
对应的串口3中断函数的编写
extern data_frame_t esp_rx_frame;
static inline void esp8266_tcp_server_IRQHandler() {
uint8_t ucTemp;
if (UART_GET_FLAG(USART3, UART_FLAG_RXNE)) {
ucTemp = READ_REG(USART3->DR);// 读取数据
if (esp_rx_frame.InfBit.frame_len < (esp_rx_frame.rx_buf_len - 1)) {
esp_rx_frame.p_rx_buf[esp_rx_frame.InfBit.frame_len++] = ucTemp;
}
}
//数据帧接收完毕
if (UART_GET_FLAG(USART3, UART_FLAG_IDLE)) {
esp_rx_frame.InfBit.frame_finished_flag = 1;
// 添加结束符
esp_rx_frame.p_rx_buf[esp_rx_frame.InfBit.frame_len] = '\0';
//由软件序列清除中断标志位(先读USART_SR,然后读USART_DR)
_UART_CLEAR_PEFLAG(USART3);
}
}
void USART3_IRQHandler(void) {
/* HAL库中断处理函数*/
// HAL_UART_IRQHandler(&com3_handle);
/* 自定义中断处理函数*/
esp8266_tcp_server_IRQHandler();
}
/*******************************************************************************
* @author scl
* @email [email protected]
******************************************************************************/
#ifndef STM32F103VET6_ESP8266_ESP8266_SERVICE_H
#define STM32F103VET6_ESP8266_ESP8266_SERVICE_H
#include "service_include.h"
/*wifi 账号*/
#define WIFI_SSID "账号"
/*wifi 密码*/
#define WIFI_PWD "密码"
/*尝试执行次数*/
#define TRY_CNT 3
/*本地IP配置*/
#define LOCAL_SERVER_IP "192.168.199.12"
/*本地端口配置*/
#define LOCAL_SERVER_PORT 8000
/*宏定义调试日志*/
#define esp_ps(fmt, ...) os_ps(fmt,##__VA_ARGS__)
/*************************************ESP 服务端 STA模式**********************************************/
/**
* @brief esp8266 在sta模式下初始化 sever
* @return
*/
bool esp_sta_tcp_server_init(void);
/**
* @brief esp8266 在sta模式下获取ip
* @param dstIp 保存ip
* @param len dstIp的长度
* @return
*/
bool esp_sta_tcp_server_get_ip(char *dstIp, uint8_t len);
/**
* @brief esp8266 客户端请求处理
* @param data 接收的数据
* @param len 数据长度
* @return
*/
bool esp_sta_tcp_server_request_handle(char *data, uint16_t len);
#endif //STM32F103VET6_ESP8266_ESP8266_SERVICE_H
/*******************************************************************************
* @author scl
* @email [email protected]
******************************************************************************/
#include "esp8266_service.h"
#include "module_esp8266.h"
#include "bsp.h"
/**
* @brief 禁止接收数据(静态内联函数)
*/
sys_force_static_inline void esp_disable_rec() {
UART_DISABLE_IT(USART3, UART_IT_RXNE);
}
sys_force_static_inline void esp_enable_rec() {
UART_ENABLE_IT(USART3, UART_IT_RXNE);
}
bool esp_sta_tcp_server_init(void) {
esp_ps("--esp_sta_tcp_server_init start---\r\n");
/*使能信号*/
esp8266_ch_enable(true);
/*测试AT指令*/
try_cnt_run (esp8266_base_at_cmd_test(10, 500), 1);
esp_ps("esp8266_base_at_cmd_test ok\r\n");
/*动态分配IP地址*/
try_cnt_run(esp8266_dhcp_cur_set(sta_mode, true, -1), TRY_CNT);
/* 设置为STA模式 */
try_cnt_run(esp8266_wifi_mode_cur_set(sta_mode, -1), TRY_CNT);
esp_ps("esp8266_mode_cur_set ok\r\n");
/* 设备本地设备ip*/
try_cnt_run(esp8266_ip_sta_cur_set(LOCAL_SERVER_IP, NULL, NULL, -1), TRY_CNT);
esp_ps("esp8266_ip_sta_cur_set ok\r\n");
/*连接WiFi*/
try_cnt_run (esp8266_wifi_join_cur_set(WIFI_SSID, WIFI_PWD, NULL, -1), TRY_CNT);
esp_ps("esp8266_wifi_join_cur_set ok\r\n");
/*允许多连接*/
try_cnt_run (esp8266_mul_connect_set(true, -1), TRY_CNT);
esp_ps("esp8266_mul_connect_set ok\r\n");
/*开启服务器模式*/
try_cnt_run (esp8266_server_tcp_start(true, LOCAL_SERVER_PORT, -1), TRY_CNT);
esp_ps("esp8266_server_tcp_start ok\r\n");
/*设置服务器链接超时时间*/
try_cnt_run (esp8266_server_tcp_timeout_set(20, -1), TRY_CNT);
esp_ps("esp8266_server_tcp_timeout_set ok\r\n");
esp_ps("--esp_sta_tcp_server_init end---\r\n");
return true;
}
bool esp_sta_tcp_server_get_ip(char *dstIp, uint8_t len) {
esp_ps("--esp_sta_tcp_server_get_ip start---\r\n");
try_cnt_run (esp8266_ip_sta_inquire(dstIp, len, -1), TRY_CNT);
esp_ps("--esp_sta_tcp_server_get_ip end---\r\n");
return true;
}
/**
* @brief 解析接收的数据
* @param rec_data 接收的数据
* @param no_id socket id
* @param data_len 发送的数据长度
* @return 实际数据的位置
*/
sys_force_static_inline char *parse_rec_data(char *rec_data, uint8_t *no_id, uint16_t *data_len) {
static char *pre_str = "+IPD,";
char *p_data = strstr(rec_data, pre_str);
// 数据解析错误 +IPD,0,2:12
if (!p_data) return false;
/*跳过前缀*/
p_data += strlen(pre_str);
/*解析socket id 号*/
*no_id = strtol(p_data, &p_data, 10);
if (!*p_data) return false;
/*解析数据长度 */
*data_len = strtol(p_data + 1, &p_data, 10);
if (!*p_data) return false;
/*获取数据*/
p_data += 1;
return p_data;
}
bool esp_sta_tcp_server_request_handle(char *data, uint16_t len) {
/* 禁止esp多个客户端同时发送数据 */
uint16_t data_len = 0;/*实际客户端发送的数据长度*/
uint8_t socket_id;/*实际客户端连接的端口号*/
bool result_flag = true;
/*禁止接收,保证同一时间只只处理一个请求 */
esp_disable_rec();
/*实际客户端发送的数据位置*/
char *p_data = parse_rec_data(data, &socket_id, &data_len);
if (p_data) {
// todo 这里就是做业务逻辑控制的地方,目前只是回显
esp_ps("parse_rec_data:%d %d %s\r\n", socket_id, data_len, p_data);
if (esp8266_server_tcp_send_to(socket_id, p_data, data_len, -1)) {
esp_ps("response ok\r\n");
} else {
esp_ps("response error\r\n");
}
} else {
result_flag = false;
}
/*清除这次的请求数据,保证下次数据为最新的*/
esp8266_clear_buf();
/*开启请求,保证同一时间只只处理一个请求 */
esp_enable_rec();
return result_flag;
}
/*******************************************************************************
* @author scl
* @email [email protected]
******************************************************************************/
#include "app_conf.h"
#include "module_esp8266.h"
#include "service.h"
/*创建数据接收帧*/
static char rx_buf[1024] = {0};
data_frame_t esp_rx_frame = {.p_rx_buf=rx_buf, .rx_buf_len=1024};
static void driver_init(void) {
/*esp8266初始化*/
esp8266_driver_init();
}
/*这句话就是将驱动导出到段中*/
DRIVER_EXPORT(esp8266_driver, driver_init);
/**
* 测试阶段暂时使用此方法
* */
void app_run() {
if (esp_sta_tcp_server_init()) {
os_ps("--esp_sta_tcp_server_init ok--\r\n");
while (1) {
if (esp_rx_frame.InfBit.frame_finished_flag) {
esp_sta_tcp_server_request_handle(esp_rx_frame.p_rx_buf, esp_rx_frame.InfBit.frame_len);
}
}
} else {
os_ps("--esp_sta_tcp_server_init error--\r\n");
}
}
观察日志记录
用客户端去连接192.168.199.12:8000
客户端
查看串口