uart配网,led灯显示联网状态

uart配网,led灯显示联网状态

例程详细讲解
// uart对esp32配网,led显示联网状态:led常亮即为连接成功,灭反之
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "lwip/err.h"
#include "lwip/sys.h"

//gpio头文件
#include <stdio.h>
#include "driver/gpio.h"
#include "sdkconfig.h"
//gpio头文件结尾

//uart头文件
#include "driver/uart.h"
#include "esp_log.h"
//uart头文件结束

#define EXAMPLE_ESP_MAXIMUM_RETRY  CONFIG_ESP_MAXIMUM_RETRY

//uart宏定义
#define ECHO_TEST_TXD  4 
#define ECHO_TEST_RXD  5 
#define ECHO_TEST_RTS (UART_PIN_NO_CHANGE )         
#define ECHO_TEST_CTS (UART_PIN_NO_CHANGE )         
#define ECHO_UART_PORT_NUM     2
#define ECHO_UART_BAUD_RATE    115200
#define ECHO_TASK_STACK_SIZE   4096
//串口的测试
static const char *TAG = "UART TEST";  
//给定存储的大小   
#define BUF_SIZE (4096)          
//uart宏定义结束

static EventGroupHandle_t s_wifi_event_group;
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT      BIT1
//gpio宏定义
#define LED_R 2
//gpio宏定义结束

    //gpio开始配置
void Led_Init(void)
{
    //选择 IO
    gpio_pad_select_gpio(LED_R);
    //设置 IO 为输出
    gpio_set_direction(LED_R, GPIO_MODE_OUTPUT);
}

//gpio结束配置

static int s_retry_num = 0;
                            //在调度事件时调用处理函数程序
static void event_handler(void* arg, esp_event_base_t event_base,   
                                int32_t event_id, void* event_data)//在事件发布到队列时调用的函数  
{
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
        esp_wifi_connect();//WiFi连接
    } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
        wifi_event_sta_disconnected_t *disconnected = (wifi_event_sta_disconnected_t *)event_data;
        ESP_LOGI(TAG, "STA disconnect reason %d", disconnected->reason);
        if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {
            esp_wifi_connect();
            s_retry_num++;
            ESP_LOGI(TAG, "retry to connect to the AP");  //重新尝试连接AP
        } else {
            xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
        }
        ESP_LOGI(TAG,"connect to the AP fail");//连接AP失败
        //led初始化
        Led_Init();
        //连接失败时电平拉低,led不亮
        gpio_set_level(LED_R, 0);
    } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {  //工作站从连接的AP获取IP
        ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
        ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
        s_retry_num = 0;
        xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
        //连接成功后把led电平拉高,led亮
        gpio_set_level(LED_R, 1);
    }
}
                //将处理好的字符串信息发给WiFi
void wifi_init_sta(char* ssid,char* pwd)
{
    //创建一个新的事件组
    s_wifi_event_group = xEventGroupCreate();  
    //创建一个 LwIP 核心任务,并初始化 LwIP 相关工作。   
    ESP_ERROR_CHECK(esp_netif_init());       
     //事件初始化    
    ESP_ERROR_CHECK(esp_event_loop_create_default()); 
     //创建有 TCP/IP 堆栈的默认网络接口实例绑定 station 
    esp_netif_create_default_wifi_sta();        
    //将配置初始化为默认的值,确保下面的函数不出错
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();   
    //创建 Wi-Fi 驱动程序任务,并初始化 Wi-Fi 驱动程序。
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));           
    esp_event_handler_instance_t instance_any_id;
    esp_event_handler_instance_t instance_got_ip;
                    //将事件处理程序的实例注册到默认循环。
    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
                                                        ESP_EVENT_ANY_ID,  //注册处理程序的事件id
                                                        &event_handler,
                                                        NULL,
                                                        &instance_any_id));
    ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
                                                        IP_EVENT_STA_GOT_IP,  //工作站从连接的AP获取IP
                                                        &event_handler,
                                                        NULL,
                                                        &instance_got_ip));
    wifi_config_t wifi_config = {
        .sta = {
            //设置模式为WPA2
	     .threshold.authmode = WIFI_AUTH_WPA2_PSK,  
        },
    };
    //将读取到的ssid和password复制给WiFi初始化
    memcpy(wifi_config.sta.ssid,ssid,strlen(ssid));
    memcpy(wifi_config.sta.password,pwd,strlen(pwd));
    //打印出ssid和pwd的信息
    printf("ssid:%s,pwd:%s\n",ssid,pwd);
    //设置WiFi的模式为station
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );    
    //调用已经设置好的WiFi id和密码   
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );  
     //开始启动 
    ESP_ERROR_CHECK(esp_wifi_start() );                    
}
   //uart开始配置
static void echo_task(void *arg)
{
    uart_config_t uart_config = {
        .baud_rate = ECHO_UART_BAUD_RATE,    //波特率大小
        .data_bits = UART_DATA_8_BITS,       //数据位
        .parity    = UART_PARITY_DISABLE,    //禁用奇偶效验位
        .stop_bits = UART_STOP_BITS_1,      //停止位
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,  //禁用硬件流控模式
        .source_clk = UART_SCLK_APB,            //设置时钟源为SCLK_APB            
    }; 
    int intr_alloc_flags = 0;                  //分配中断的标志

#if CONFIG_UART_ISR_IN_IRAM
    intr_alloc_flags = ESP_INTR_FLAG_IRAM;
#endif
    //端口号、tx和rx的环形缓冲区大小
    ESP_ERROR_CHECK(uart_driver_install(ECHO_UART_PORT_NUM, BUF_SIZE * 2, 0, 0, NULL, intr_alloc_flags));
    //调用已经配置好数据的函数uart_config
    ESP_ERROR_CHECK(uart_param_config(ECHO_UART_PORT_NUM, &uart_config));        
    //设置引脚
    ESP_ERROR_CHECK(uart_set_pin(ECHO_UART_PORT_NUM, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, ECHO_TEST_CTS));  
    //给data分配一个空间,便于存数据,空间大小为BUF_SIZE
    uint8_t *data = (uint8_t *) malloc(BUF_SIZE);  
    //给ssid数组分配一个空间,便于存储数据
    char ssid[32] = {0};
    //给pwd数组分配一个空间,便于存储数据
    char pwd [64] = {0};
    // int i =0;
    while (1) {
        //将外界读取到的数据存到data中
        int len = uart_read_bytes(ECHO_UART_PORT_NUM, data, (BUF_SIZE - 1), 20 / portTICK_RATE_MS); 
        //读取存到data的数据,长度为int len读取到的长度
        uart_write_bytes(ECHO_UART_PORT_NUM, (const char *) data, len); 
        if (len) {
            //data大于0即读进下面的程序
            data[len] = '\0';    
    //将读入的data用.分开传输,strtok为分解字符串;char *strtok(char *str, const char *delim),delim为分隔符,在这里指的是.
             char *p = strtok((char *)data,".");
            //复制指针p内.前面所有的值,strlen意为计算字符串p中的长度,直到空结束字符,不包括空,在这里意为到.结束
            memcpy(ssid,p,strlen(p));
            printf("ssid:%s\r\n",ssid);
            p = strtok(NULL,".");
            //复制指针p内.后面所有的值
            memcpy(pwd,p,strlen(p));
            printf("password:%s\r\n",pwd);
            //以.结尾,避免出现错误
            p = strtok(NULL,".");
            break;
        }
    }
    wifi_init_sta(ssid,pwd);
    vTaskDelete(NULL);
}
//uart配置结束
void app_main(void)
{
    //uart主函数
     xTaskCreate(echo_task, "uart_echo_task", ECHO_TASK_STACK_SIZE, NULL, 10, NULL);//创建一个事件,设置事件大小,
    //uart结束 
     //初始化默认的NVS分区
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
      ESP_ERROR_CHECK(nvs_flash_erase());      //清除默认的nvs内容
      ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);
}

总结

本人也是一个学习的过程,在这段程序中收益良多,在此发文既跟大家分享,也是我自己记录的一个学习过程,中间若有不足还见谅。
在这段程序中大多都是用的idf官方例程,其中有uart和station的例程,还包含了一些简单的gpio的介绍,因为其中的gpio只是为了点灯,中断并没有用到,所有介绍的会相对少一些,在这些官方例程中花费最多时间的是uart,在实现通讯时卡了很久,不过好在还是做出来了,从中也学到很多东西,后续还要继续加油!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值