Clion开发STM32之ESP8266示例记录(一)

该文提供了一个使用STM32F103VET6芯片通过串口3与ESP8266进行通信的示例,包括ESP8266的驱动初始化、复位和使能功能,以及串口中断处理函数。此外,还展示了如何配置ESP8266作为TCP客户端连接到服务器并进行透传模式设置。
摘要由CSDN通过智能技术生成

前言

  1. 本次示例为标准库的示例
  2. 记录ESP8266的透传和TCP CLient的示例
  3. 使用的芯片为 STM32F103VET6,开发板使用的野火指南者
  4. 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);
//        }
//
//    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

詩不诉卿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值