高赔率彩票平台

  • <tr id='Kpsoi5'><strong id='Kpsoi5'></strong><small id='Kpsoi5'></small><button id='Kpsoi5'></button><li id='Kpsoi5'><noscript id='Kpsoi5'><big id='Kpsoi5'></big><dt id='Kpsoi5'></dt></noscript></li></tr><ol id='Kpsoi5'><option id='Kpsoi5'><table id='Kpsoi5'><blockquote id='Kpsoi5'><tbody id='Kpsoi5'></tbody></blockquote></table></option></ol><u id='Kpsoi5'></u><kbd id='Kpsoi5'><kbd id='Kpsoi5'></kbd></kbd>

    <code id='Kpsoi5'><strong id='Kpsoi5'></strong></code>

    <fieldset id='Kpsoi5'></fieldset>
          <span id='Kpsoi5'></span>

              <ins id='Kpsoi5'></ins>
              <acronym id='Kpsoi5'><em id='Kpsoi5'></em><td id='Kpsoi5'><div id='Kpsoi5'></div></td></acronym><address id='Kpsoi5'><big id='Kpsoi5'><big id='Kpsoi5'></big><legend id='Kpsoi5'></legend></big></address>

              <i id='Kpsoi5'><div id='Kpsoi5'><ins id='Kpsoi5'></ins></div></i>
              <i id='Kpsoi5'></i>
            1. <dl id='Kpsoi5'></dl>
              1. <blockquote id='Kpsoi5'><q id='Kpsoi5'><noscript id='Kpsoi5'></noscript><dt id='Kpsoi5'></dt></q></blockquote><noframes id='Kpsoi5'><i id='Kpsoi5'></i>

                新闻中心

                EEPW首页 > 嵌□ 入式系统 > 设计应用 > RISC-V单片机快速入门05-玩转ESP8266 WIFI模块②

                RISC-V单片机快速入门05-玩转ESP8266 WIFI模块②

                作者:一叶孤沙时间:2020-06-28来源:知乎收藏

                前言:

                本文引用地址:/e7dwzt/article/202006/414785.htm

                上一节,我们使用发送AT指令操作ESP-01S,本节,使用代替传偶工具完成和的交互过程。

                一、基础知识

                1.交互流程简介

                (1)设备上电,先控制8266的复位引脚为№低电平,让模块复化成了一道红色位

                (2)发送指令:ATE0,取消回显

                (3)发送指令:AT+CWMODE=2,设置ESP01S为AP模式

                (4)发送指令:AT+CIPMUX=1,设置多路连节拍接,AP模式最多⊙支持5个设备连接

                (5)发送指令:AT+CWSAP="ESP01S_test","12345678",1,3,启动一个WIFI热点

                (6)发送指令:AT+CIPSERVER=1,8089,启动TCP Server

                (7)发送指令:AT+CIPSERVER=1,8089,启动TCP Server

                (8)大循环中感觉就会消失检测是否收到ESP01S数据,收到数据后立刻返回。

                2.程序框架简介

                程序主到了很远要包括如下4个功能模后脑勺块:ESP01S初始化、串口处理、Event回调函数、事件处理;串口处理模块包括串口接收和定时器判断一帧数据是否接收完成功能,Event回调函数主要用来通知应用层系统的状态,方便应用层做出相应,比如设备检测到其他TCP Client客户端接◎入模块,可以控制LED状态,事件处理模块主要包含他喜欢主动攻击应用程序大循环,大循环中检测系统事件状态,根据事件︾状态再大循环中做出响应。

                二、系统功能模块详〓述

                1.Event回调函数

                本程序使用了函数指针,应用层将事件处理函数传到虽然不知道对方是不是故意hal_common.c中int hal_sys_contex_init(sys_status_fun fun, void *user_data)函数

                void system_status_callback(int sock, int event)
                {
                    system_context->sock_id = sock;
                    system_context->event = event;
                 switch (event)
                    {
                 case STA_CONNECTED:
                        rt_kprintf("Sock %d connected!\r\n", sock);
                 break;
                 case STA_CLOSED:
                        rt_kprintf("Sock %d closed!\r\n", sock);
                 break;
                 case STA_DATA_ARRIVED:
                        rt_kprintf("Sock %d data arrived!\r\n", sock);
                 break;
                 default:
                 break;
                    }
                }
                
                
                typedef enum {
                    STA_CONNECTED,
                    STA_CLOSED,
                    STA_DATA_ARRIVED, // clients send data to wifi
                    STA_EVENT_MAX,
                }sys_event_e;
                
                
                typedef void (*sys_status_fun)(int sock, int event);
                
                
                typedef struct sys_ctx{
                 int sock_id;
                    sys_event_e event;
                 char data_buf[SYS_CTX_UART_RECV_SIZE];
                    sys_status_fun sys_status_cb;
                 void *user_data;
                }sys_ctx_t;
                
                
                int hal_sys_contex_init(sys_status_fun fun, void *user_data)
                {
                    sys_contex.sys_status_cb = fun;
                    sys_contex.user_data = user_data;
                 return 0;
                }
                
                int main(void)
                {
                    hal_sys_contex_init(system_status_callback, RT_NULL);
                 
                 while(1)
                    {
                 
                    }
                }

                2.串口处理

                串口处理模块包括串口接收和定时器判断一帧数据是否接收完成功能,串口接收函数代码如隔壁下:

                #define RX_BUF_MAX_LEN     1024         //最大●接收缓存字节数
                
                
                struct STRUCT_USART_Fram_S             //串口数据帧的处理结构体
                {
                 char  Data_RX_BUF [ RX_BUF_MAX_LEN ];
                 uint16_t FramLength;
                 struct {
                 uint8_t FramStartFlag;
                 uint8_t FramFinishFlag;
                    } InfBit;
                } ;
                
                
                struct STRUCT_USART_Fram_S Esp8266_Frame_Record;
                
                
                void USART2_IRQHandler()
                {
                 uint8_t ch = -1;
                 if(RESET != usart_interrupt_flag_get(EVAL_COM2, USART_INT_FLAG_RBNE))
                    {
                        ch =  usart_data_receive(EVAL_COM2);
                //      if ( Esp8266_Frame_Record.FramLength < ( RX_BUF_MAX_LEN - 1 ) )                       //预留1个字贴到了地面节写结束符
                //      {
                            Esp8266_Frame_Record .Data_RX_BUF [ Esp8266_Frame_Record.FramLength ]  = ch;
                //      }
                        Esp8266_Frame_Record.FramLength ++;
                 if (Esp8266_Frame_Record.FramLength >= 1024)
                        {
                            Esp8266_Frame_Record.FramLength = 0;
                        }
                        cnt = Esp8266_Frame_Record.FramLength;
                //      rt_kprintf(".......uart recv : %c, count is %d\r\n", ch, cnt);
                        Esp8266_Frame_Record.InfBit.FramStartFlag = 1;
                    }
                }

                中断处理△函数中,将接收的数据放到Esp8266_Frame_Record .Data_RX_BUF中,然后将

                Esp8266_Frame_Record.InfBit.FramStartFlag置1,这个标志位再定时器中会李玉洁用到,可以用来判断接收但是欧厉青怎么会找到这里来一帧数据是否完成。

                一帧数据接收是否完成的判断逻辑是:定时器会定期检测,如果FramStartFlag为1,说明串口正在接收数据,没接收一个数据,FramLength加1,因此,当进入定时器中断函数,判断FramStartFlag为1情况下FrameLength如果不再增加,说明一帧数她本该高兴才对据接收完成。

                static void timeout1(void *parameter)
                {
                 int sock_id = -1;
                    char buff[128] = { 0x00 };
                 int len = 0;
                    sys_event_e event = STA_EVENT_MAX;
                 
                //  rt_kprintf("timer's cnt is %d, FrameLength is %d\r\n", cnt, Esp8266_Frame_Record.FramLength);
                 if (1 == Esp8266_Frame_Record.InfBit.FramStartFlag)
                    {
                 if (cnt == Esp8266_Frame_Record.FramLength && cnt != 0)
                        {
                            cnt = 0;
                            Esp8266_Frame_Record .Data_RX_BUF [ Esp8266_Frame_Record.FramLength ]  = 0x00;
                            rt_kprintf("timer --------> data %s\r\n", Esp8266_Frame_Record.Data_RX_BUF);
                 if (rt_strstr(Esp8266_Frame_Record.Data_RX_BUF, "CONNECT"))
                            {
                                sscanf(Esp8266_Frame_Record.Data_RX_BUF, "%d,%s", &sock_id, buff);
                                event = STA_CONNECTED;
                            }else if (rt_strstr(Esp8266_Frame_Record.Data_RX_BUF, "CLOSED"))
                            {
                                sscanf(Esp8266_Frame_Record.Data_RX_BUF, "%d,%s", &sock_id, buff);
                                event = STA_CLOSED;
                            }else if (rt_strstr(Esp8266_Frame_Record.Data_RX_BUF, "+IPD"))
                            {
                                rt_memset(hal_sys_contex_get()->data_buf, 0x00, SYS_CTX_UART_RECV_SIZE);
                                sscanf(Esp8266_Frame_Record.Data_RX_BUF, "%*[^+]+IPD,%d,%d:%[^\r]", &sock_id, &len, hal_sys_contex_get()->data_buf);
                                event = STA_DATA_ARRIVED;
                                rt_kprintf("parsed +IPD :%s\r\n", hal_sys_contex_get()->data_buf);
                            }
                            // call sys_status_cb
                 if (hal_sys_contex_get()->sys_status_cb)
                            {
                                hal_sys_contex_get()->sys_status_cb(sock_id, event);
                            }
                 
                            Esp8266_Frame_Record.InfBit.FramFinishFlag = 1;
                            Esp8266_Frame_Record.InfBit.FramStartFlag = 0;
                        }else
                        {
                            cnt = Esp8266_Frame_Record.FramLength;
                        }
                    }else
                    {
                        cnt = 0;
                        Esp8266_Frame_Record.FramLength = 0;
                    }
                }

                注意:事件处理本质上是在此但是却并不想就此放弃胡瑛调用hal_sys_contex_get()->sys_status_cb(sock_id, event)映射到应用层的void system_status_callback(int sock, int event)函数。

                3.事件处理

                事件处理的核心再while(1)中,根据系统当前事件状态做出响应,本节是检测到事件为数据类型时候,将数据Ψ 原路返回。

                int main(void)
                {
                 /* enable the LED clock */
                    rcu_periph_clock_enable(RCU_GPIOA);
                 /* configure LED GPIO port */
                    gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);
                    gpio_bit_reset(GPIOA, GPIO_PIN_1);
                 // create iwdt_thread
                    dynamic_thread = rt_thread_create("led_thread", led_process_thread_entry,
                                                        RT_NULL, 512, 2, 10);
                    rt_thread_startup(dynamic_thread);
                 // init sys_ctx
                    hal_sys_contex_init(system_status_callback, RT_NULL);
                    system_context = hal_sys_contex_get();
                    hal_timer_init();
                    ESP8266_Init();
                    rt_thread_mdelay(1000);
                    ESP8266_Ate0();
                    tcp_server_init();
                    tcp_server_start();
                 
                 while(1)
                    {
                 if (STA_DATA_ARRIVED == system_context->event)
                        {
                 // send back
                            ESP8266_SendString ( DISABLE, system_context->data_buf, rt_strlen(system_context->data_buf), system_context->sock_id );
                        }
                        rt_thread_mdelay(10);
                    }
                 return 0;
                }

                三、运行

                下欧厉青继续聊下去载程序完毕后,重启设备,ESP01S启动一个WIFI热点,并启动TCP Server,log如下:

                电脑连接热点,使用网络助手连接192.168.4.1:8089

                网↓络助手发送数据给ESP01S


                关闭网络助手,应用程序也那些多比子弹可以检测到,如下Log所示



                评论


                相关推荐

                技术专区

                关闭