esp8266的STM32驱动

原文地址:http://m.codes51.com/article/detail_318577.html

esp8266的STM32驱动,数据发送接收由DMA完成,释放CPU。

  目前只能发送返回消息为成功或失败的AT命令,并判断是否成功,详见esp8266_cmd();其它返回消息不可预知的命令(如查看AP,IP等)未实现,也用不着。以查询的方式判断有无消息,是什么样的消息,返回消息类型,如果是收到了数据,则会保存在指定的地址,并给出长度,详见esp8266_parse();当连接建立后,给远程发送数据用esp8266_send(),它会在数据实际发送成功前返回,剩下的活由DMA完成,然后请耐心地等待消息,想知道结果就调用esp8266_parse(),它会根据返回的消息判断发送有无成功,并返回。

  文中的“消息”是指ESP8266发的指示状态的,“数据”指通过网络收发的。

头文件

#ifndef ESP8266_H
#define ESP8266_H
#include "main.h"#define RXBUFFERSIZE 1024
#define HEADER_LENGTH 19
//pos : current postion, pos_end: right side of the last received characterexternint pos, pos_end;
externchar aRxBuffer[RXBUFFERSIZE]; // DAM receiving, no interrupt,
// this var is set in esp8266_send(), and reset in esp8266_parse if sent ok, you don't need to set/reset it, just read it;externbool esp8266_sending;

typedef enum {
    NO_EVENT,
    LINK,
    UNLINK,
    PAYLOAD,
    SEND_OK,
    SEND_ERROR,
    RST
}esp8266_event_t;

//send "AT\r\n" to test whether it exist and then reset it, if both action is succeed, return true;bool esp8266_init(void);

// check whether there is new data come, if not ,return NO_EVENT; else parse the type of the new message;
// if there is a payload, the first parameter is used to store payload it received, the second is the length;esp8266_event_t esp8266_parse( uint8_t *payload, int *payload_length );

//return how many characters have been received and update pos_endint update_length(void);
// if len = -6, means copy the last 6 charsvoid copy_buffer(uint8_t *tmp, int len);

//cmd is sent, echo is the last chars means OK.  if received extra chars after "OK\r\n" and the task is interrupted, it maybe fail, but this seldom happensbool esp8266_cmd(char *cmd, char *echo, int timeout);

// cmd send in blocking mode, data is send in DMA mode, return before send ok; it will check esp8266_sending, you don't need to check;bool esp8266_send(int socket, uint8_t *data, int length);

//not implemented
//bool esp8266_list_AP(void);#endif

主文件

#include "esp8266.h"extern UART_HandleTypeDef UartHandle;
externchar aRxBuffer[RXBUFFERSIZE];
extern __IO ITStatus UartReady;

char aRxBuffer[RXBUFFERSIZE];
int pos=0, pos_end;
bool esp8266_sending = false;

bool esp8266_init(){
    int length;
    // if the mcu and esp8266 are powered up at the same time, mcu will receive some info, have to ignore it.while(1){ // waiting until the receive buffer stop increase;        HAL_Delay(100);
        length = update_length();
        if( length > 0 ){
            pos += length;
            pos %= RXBUFFERSIZE;
            continue;
        }else{
            break;
        }
    }
    if( esp8266_cmd("AT\r\n", "\r\nOK\r\n", 100) ){
        if( esp8266_cmd("AT+RST\r\n", "\r\nready\r\n", 2000) ){
            returntrue;
        }else{
            returnfalse;
        }
    }else{
        returnfalse;
    }
}
// in order to avoid push & pop and easy to debug, put the big data outsidestaticchar cmd_echo[16];
bool esp8266_cmd(char *cmd, char *echo, int timeout){
    int time, length=0, compare_length = strlen(echo);
    while(!UartReady);
    HAL_UART_Transmit( &UartHandle, (uint8_t *)cmd, strlen(cmd), 0xffff);
    time = HAL_GetTick();
    while( HAL_GetTick() - time < timeout ){ // waiting "xxx\r\nOK\r\n        length = update_length();
        if( length > compare_length ){
            copy_buffer((uint8_t *)cmd_echo, -1*compare_length);
            if( 0 == strncmp(cmd_echo, echo, compare_length) ){
                pos += length;
                pos %= RXBUFFERSIZE;
                returntrue;
            }
        }
    }
    // should move pos to the end, maybe the response is "no changed" which is the same as "OK", if you don't move it, the next cmd maybe fail    pos += length;
    pos %= RXBUFFERSIZE;
    returnfalse;
}

bool esp8266_send(int socket, uint8_t *data, int length){
    char cmd[20];
    if( esp8266_sending ){
        returnfalse;
    }
    sprintf(cmd, "AT+CIPSEND=%d,%d\r\n", socket, length);
    if( esp8266_cmd(cmd, "\r\n> ", 200) ){
        while(!UartReady);
        HAL_UART_Transmit_DMA(&UartHandle, (uint8_t *)data, length);
        UartReady = RESET;
        esp8266_sending = true;
        returntrue;
    }else{
        //while(1); // convenient to debugreturnfalse;
    }
}

int update_length(){
    int length;
    pos_end = RXBUFFERSIZE - __HAL_DMA_GET_COUNTER( UartHandle.hdmarx );
    if( pos_end >= pos ){
        length = pos_end - pos;
    }else{
        length = (RXBUFFERSIZE + pos_end) - pos;
    }
    //p1 = aRxBuffer + pos;
    //p2 = aRxBuffer + pos_end;return length;
}
void copy_buffer(uint8_t *tmp, int length){
    int pos_tmp;
    char *p1;
    if( length > 0){
        pos_tmp = (pos + length) % RXBUFFERSIZE;
        p1 = aRxBuffer + pos;
        if( pos_tmp > pos ){
            memcpy(tmp, p1, length);
        }else{
            memcpy( tmp, p1, RXBUFFERSIZE-pos );
            memcpy( tmp + RXBUFFERSIZE-pos, aRxBuffer, pos_tmp );
        }
    }else{
        length *= -1;
        pos_tmp = ( pos_end - length );
        if( pos_tmp < 0 ){
            pos_tmp += RXBUFFERSIZE;
        }
        p1 = aRxBuffer + pos_tmp;
        if( pos_end > pos_tmp ){
            memcpy(tmp, p1, length);
        }else{
            memcpy( tmp, p1, RXBUFFERSIZE-pos_tmp );
            memcpy( tmp + RXBUFFERSIZE-pos_tmp, aRxBuffer, pos_end );
        }
    }
}

staticchar header[16];
esp8266_event_t esp8266_parse(uint8_t *payload, int *payload_length){
    int length, length_expected; 
    int pos_tmp, pos_end2;
    char *p3, *p4;
    copy_buffer((uint8_t *)header, 6);
    length = update_length();
    if( length < 6 ){
        return NO_EVENT;
    }
    if( esp8266_sending ){ // sendingif( length >= 11 ){
            pos_end2 = pos_end;
            if( pos_end2 < pos ){
                pos_end2 += RXBUFFERSIZE;
            }
            for( pos_tmp = pos; pos_tmp <= pos_end2 - 10; pos_tmp++ ){ //"\r\nSEND OK\r\n"if( aRxBuffer[ pos_tmp%RXBUFFERSIZE ] == '\n' ){
                    if( aRxBuffer[ (pos_tmp + 7)%RXBUFFERSIZE ] == 'K' ){
                        pos += pos_tmp-pos+10;
                        pos %= RXBUFFERSIZE;
                        esp8266_sending = false;
                        return SEND_OK;
                    }else{
                        return SEND_ERROR;
                    }
                }
            }
            return NO_EVENT;
        }else{            
            return NO_EVENT;
        }
    }
    if( length >=6 && (0 == strncmp(header, "Link", 4)) ){  // link        pos += 6;
        pos %= RXBUFFERSIZE;
        return LINK;
    }elseif( length >=8 && (0 == strncmp(header, "Unlink", 6)) ){ // unlink        pos += 8;
        pos %= RXBUFFERSIZE;
        return UNLINK;
    }elseif( length > HEADER_LENGTH && (0 == strncmp(header, "\r\n+IPD", 6)) ){ // "\r\n+IPD=0,478:xxx\r\nOK\r\n"        copy_buffer((uint8_t *)header, 16);
        p3 = header+9;
        p4 = strchr( (char *)p3, ':' );
        *p4 = '\0';
        *payload_length = atoi(p3);
        length_expected = *payload_length + HEADER_LENGTH - 3 + strlen(p3);
        *(payload + *payload_length) = '\0';
        if( length < length_expected ){ //HEADER_LENGTH include "478", but the lenght is variablereturn NO_EVENT;
        }
        // now we have got a payload        pos += (10 + strlen(p3));
        pos %= RXBUFFERSIZE;
        copy_buffer( payload, *payload_length);
        pos += *payload_length + 6 ;
        pos %= RXBUFFERSIZE;
        return PAYLOAD;
    }else{
        return NO_EVENT;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值