2022/11/14 学习之路---day2
简介:
2022/11/14 学习之路---day2
2022/11/14 学习之路---day2
今日所遇问题
1.无线传感网络作业
1. 两个esp8266通过代码直接进行互相通信
- 首先先感谢一下谢xx和李xx同学提供给的源代码以及老师给予的帮助
2. 作为AP模式的esp8266代码
1. 主函数(AP)
2. ESP8266.c(AP)
#include <string.h>
#include "esp8266.h"
//#include "types.h"
/**************************************************************************
/ 功能:向ESP8266模块发测试指令"AT"(4次),检测其工作状态是否正常;
/
/ 返回值:如果收到"OK"则返回SUCCESS;如果未收到"OK"则返回FAILED。
**************************************************************************/
uint8 checkEsp8266(void)
{
extern char Rx1Buf[UART_MAX_SIZE]; // 关键字extern的作用:表明后面的变量是在别的.c模块中声明的全局变量
uint8 checkTimes = 4;
uart1SendStr(AT_AT);
while (checkTimes--)
{
delayMs(300);
uart0SendStr(Rx1Buf); // PC串口端打印AT指令的返回值
if(strstr((char const *)Rx1Buf,"OK")!=NULL) //Wi-Fi正常返回
{
clearRx1Buf();
return SUCCESS;
}
else //Wi-Fi模块没有返回"OK",异常
{
delayMs(300);
clearRx1Buf();
}
}
return FAILED; // 连续4条测试指令都没有回应。
}
/**************************************************************************
/ 功能:尝试结束ESP8266模块的透传模式并重启模块;
/
/ 返回值:无。
**************************************************************************/
void resetEsp8266(void)
{
uart1SendStr("+++");
delayMs(1500);
uart1SendStr(AT_RST);
delayMs(3000);
}
/****************************************************************************
* 功 能: 向Wi-Fi模块发AT指令来控制模块
* 参数说明:string为要发出的AT指令
* 检测Wi-Fi模块返回的数据中有没有OK 如果没有D1灯闪,提示用户检查硬件连接
****************************************************************************/
uchar sendAtCmd(char *cmdStr)
{
extern char Rx1Buf[UART_MAX_SIZE];
uchar time_out = 4;
char *pAddr;
char esp8266IpAddr[20];
char i=0;
clearRx1Buf();
uart1SendStr(cmdStr);
while(time_out--) //重复检测4次
{
delayMs(2000);
uart0SendStr(Rx1Buf); // PC串口打印AT指令的返回值
//CIFSR指令:查询并记录ESP8266的IP地址
if(strstr((char const *)Rx1Buf,"CIFSR") != NULL)
{
pAddr = strstr((char const *)Rx1Buf, "STAIP,\"") + 7;
while(*pAddr != '"')
{
esp8266IpAddr[i++] = *pAddr++;
}
uart0SendStr(esp8266IpAddr);
return SUCCESS;
}
// 其它AT指令
else if(strstr((char const *)Rx1Buf,"OK") == NULL)
{
//Wi-Fi模块没有返回"OK",异常
delayMs(300);
clearRx1Buf();
}
else
{
//Wi-Fi模块状态正常
delayMs(500);
clearRx1Buf();
return SUCCESS;
}
}
return FAILED;
}
/**************************************************************************
/
/ 功能:ESP8266模块通过AT指令连接OneNET服务器,并开启透传。
/
/ 返回值:无
**************************************************************************/
void connectOnenet(void)
{
sendAtCmd(AT_CWMODE); // 设置为AP/Station模式
delayMs(300);
//sendAtCmd(AT_CWLAP);
//delayMs(1000);
sendAtCmd(AT_CWJAP);
delayMs(1000);
//sendAtCmd(AT_CIFSR);
//delayMs(300);
sendAtCmd(AT_CIPSTART); // 连接OneNET服务器
delayMs(3000);
//sendAtCmd(AT_CIPMODE); // 透传模式
//delayMs(300);
sendAtCmd(AT_CIPSEND);
delayMs(500);
clearRx1Buf();
}
uint8 esp8266_JRTC(void) //客户端建立透传模式
{
extern int flag1;
extern char Rx1Buf[UART_MAX_SIZE];
if(strstr((char const *)Rx1Buf,"xxx"))
{
flag1=1;
clearRx1Buf();
return 1;
}
else return 0;
}
uint8 esp8266_TCTC(void) //服务端建立传输模式
{
extern int flag2;
extern char Rx1Buf[UART_MAX_SIZE];
if(strstr((char const *)Rx1Buf,"*"))
{
flag2=1;
clearRx1Buf();
return 1;
}
else return 0;
}
void esp8266_AP(void)
{
extern char Rx1Buf[UART_MAX_SIZE];
sendAtCmd(AT_RST); //复位
delayMs(3000);
if(checkEsp8266() == SUCCESS) // ESP8266工作状态正常
{
uart0SendStr("Check ESP8266 OK\r\n");
}
else uart0SendStr("esp8266初始化失败!!!"); // 丁:如果初始化失败,后续代码就不必执行了,应该直接返回-1。
sendAtCmd(AT_CWMODE); //设置为AP模式
delayMs(300);
sendAtCmd(AT_CWSAP); //配置其参数("YYY","1234567890",6,3)
delayMs(2000);
/*sendAtCmd(AT_CIFSR); //查询其IP地址
delayMs(5000);*/
sendAtCmd(AT_CIPMUX); //设置多连接模式
delayMs(2000);
sendAtCmd(AT_CIPSERVER); //设置端口号
delayMs(300);
clearRx1Buf();
}
3. ESP8266.h(AP)
//esp8266的配置参数以及函数库
#include "uart.h"
//ESP8266的AT命令
#define AT_AT "AT\r\n"
#define AT_RST "AT+RST\r\n"
#define AT_CWMODE "AT+CWMODE=2\r\n" // AP+STA
#define AT_CWLAP "AT+CWLAP\r\n"
#define AT_CWJAP "AT+CWJAP=\"xyy\",\"XYY1234567890\"\r\n" // 注意字符串中带""号,需要转义符
#define AT_CIPMUX "AT+CIPMUX=1\r\n"
#define AT_CIPSTART "AT+CIPSTART=\"TCP\",\"183.230.40.34\",80\r\n"
#define AT_CIPMODE "AT+CIPMODE=1\r\n" // 使用透传
#define AT_CIPSEND "AT+CIPSEND=0,19\r\n"
#define AT_CIPSERVER "AT+CIPSERVER=1,9090\r\n"
#define AT_CIFSR "AT+CIFSR\r\n" // AT+CIFSR 获取本地 IP
#define AT_CIPAP "AT+CIPAP?\r\n"
#define AT_CWSAP "AT+CWSAP=\"YYY\",\"1234567890\",6,3\r\n"
#define AT_RESTORE "AT+RESTORE\r\n"
#define RECV_LEN 100
//判断Wi-Fi发送过来的数据来解析出控制命令
#define IDENTIFIER "+IPD"
//Wi-Fi返回的数据
#define WIFI_NOT_LINK "link is not valid"
#define WIFI_CONNECT "CONNECT"
#define WIFI_GET_DATA "GETDATA"
#define WIFI_CON_FAIL "CONNECT FAIL"
#define WIFI_FAIL "FAIL"
#define SUCCESS 0
#define FAILED 1
uint8 checkEsp8266(void);
void resetEsp8266(void);
void connectOnenet(void);
void esp8266_AP(void);
uint8 esp8266_JRTC(void);
uint8 esp8266_TCTC(void);
uchar sendAtCmd(char *cmdStr);
4. uart.c(AP)
//串口配置函数
#include <ioCC2530.h>
#include <string.h>
#include "esp8266.h"
uchar U0Len = 0;
uchar U1Len = 0;
char Rx0Buf[UART_MAX_SIZE], Rx1Buf[UART_MAX_SIZE];
char *p;
char ii=0;
char ch[20];
int flag1=0;
int flag2=0;
/****************************************************************************
* 名 称: DelayMS()
* 功 能: 以毫秒为单位延时
* 入口参数: msec 延时参数,值越大,延时越久
* 出口参数: 无
****************************************************************************/
void delayMs(uint msec)
{
uint i,j;
for (i=0; i<msec; i++)
for (j=0; j<1070; j++);
}
/****************************************************************************
* 名 称: initUart0()
* 功 能: 串口初始化函数
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void initUart0(void)
{
PERCFG &= ~0x01; //指定USART0的IO口位置(候选位置1)
P0SEL |= 0x0c; //P0_2,P0_3置为外设模式
P2DIR &= ~0xc0; //P0优先作为UART0
U0CSR |= 0x80; //设置为UART方式
U0GCR |= 11;
U0BAUD |= 216; //波特率设为115200
//UTX0IF = 0; //UART0 TX中断标志初始置位0
U0CSR |= 0x40; //允许UART0接收
IEN0 |= 0x84; //开总中断允许接收中断
}
/****************************************************************************
* 名 称: InitUart1()
* 功 能: 串口初始化函数
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void initUart1(void)
{
PERCFG &= ~0x02; //指定USART1的IO口位置(候选位置1)
P0SEL |= 0x30; //P0_4,P0_5置为外设模式(手册P74)
U1CSR |= 0x80; //设置为UART方式
U1GCR |= 11;
U1BAUD |= 216; //波特率设为115200
//UTX1IF = 0; //UART1 TX中断标志初始置位0
U1CSR |= 0x40; //允许接收
IEN0 |= 0x88; //开总中断允许接收中断
}
/****************************************************************************
* 名 称: Uart0SendStr()
* 功 能: 串口发送函数
* 入口参数: Data-发送缓冲区
* 出口参数: 无
****************************************************************************/
void uart0SendStr(char *Data)
{
while(*Data != '\0')
{
U0DBUF = *Data++;
while(UTX0IF == 0);
UTX0IF = 0;
}
}
void uart1SendStr(char *Data)
{
while(*Data != '\0')
{
U1DBUF = *Data++;
while(UTX1IF == 0);
UTX1IF = 0;
}
}
/****************************************************************************
* 名 称: UART0_ISR(void) 串口中断处理函数
* 描 述: 当串口0产生接收中断,将收到的数据保存在Rx0Buf中
****************************************************************************/
//数据接收中断服务函数
#pragma vector = URX0_VECTOR
__interrupt void UART0_ISR(void)
{
if (U0Len < UART_MAX_SIZE)
{
Rx0Buf[U0Len++] = U0DBUF;
if(flag2 == 1)
{
U1DBUF = U0DBUF;
}
//URX0IF = 0; // 在ISR中硬件会自动清除该中断标志
}
}
/****************************************************************************
* 名 称: UART1_ISR(void) 串口中断处理函数
* 描 述: 当串口1产生接收中断,将收到的数据保存在Rx1Buf中
****************************************************************************/
//数据接收中断服务函数
#pragma vector = URX1_VECTOR
__interrupt void UART1_ISR(void)
{
if (U1Len < UART_MAX_SIZE)
{
Rx1Buf[U1Len++] = U1DBUF;
if(flag1 == 1)
{
U0DBUF = U1DBUF;
}
}
}
/****************************************************************************
* 名 称: clearRx0Buf()
* 功 能: 清空串口1接收缓冲区的数据
****************************************************************************/
void clearRx0Buf(void)
{
//发生异常时可以打开此注释来观察通讯情况
//Uart0SendString((char*)Uart1RxBuf); //通过串口0输出wifi返回的数据
memset(Rx0Buf, 0, UART_MAX_SIZE);
U0Len=0;
}
/****************************************************************************
* 名 称: clearRx1Buf()
* 功 能: 清空串口1接收缓冲区的数据
****************************************************************************/
void clearRx1Buf(void)
{
memset(Rx1Buf, 0, UART_MAX_SIZE);
U1Len=0;
}
5. uart.h(AP)
3. 作为STA模式的esp8266代码
1.主函数(STA)
2.ESP8266.c(STA)
//esp8266代码
#include <string.h>
#include "esp8266.h"
//#include "types.h"
/**************************************************************************
/ 功能:向ESP8266模块发测试指令"AT"(4次),检测其工作状态是否正常;
/
/ 返回值:如果收到"OK"则返回SUCCESS;如果未收到"OK"则返回FAILED。
**************************************************************************/
uint8 checkEsp8266(void)
{
extern char Rx1Buf[UART_MAX_SIZE]; // 关键字extern的作用:表明后面的变量是在别的.c模块中声明的全局变量
uint8 checkTimes = 4;
uart1SendStr(AT_AT);
while (checkTimes--)
{
delayMs(300);
uart0SendStr(Rx1Buf); // PC串口端打印AT指令的返回值
if(strstr((char const *)Rx1Buf,"OK")!=NULL) //Wi-Fi正常返回
{
clearRx1Buf();
return SUCCESS;
}
else //Wi-Fi模块没有返回"OK",异常
{
delayMs(300);
clearRx1Buf();
}
}
return FAILED; // 连续4条测试指令都没有回应。
}
/**************************************************************************
/ 功能:尝试结束ESP8266模块的透传模式并重启模块;
/
/ 返回值:无。
**************************************************************************/
void resetEsp8266(void)
{
uart1SendStr("+++");
delayMs(1500);
uart1SendStr(AT_RST);
delayMs(3000);
}
/****************************************************************************
* 功 能: 向Wi-Fi模块发AT指令来控制模块
* 参数说明:string为要发出的AT指令
* 检测Wi-Fi模块返回的数据中有没有OK 如果没有D1灯闪,提示用户检查硬件连接
****************************************************************************/
uchar sendAtCmd(char *cmdStr)
{
extern char Rx1Buf[UART_MAX_SIZE];
uchar time_out = 4;
char *pAddr;
char esp8266IpAddr[20];
char i=0;
clearRx1Buf();
uart1SendStr(cmdStr);
while(time_out--) //重复检测4次
{
delayMs(2000);
uart0SendStr(Rx1Buf); // PC串口打印AT指令的返回值
//CIFSR指令:查询并记录ESP8266的IP地址
if(strstr((char const *)Rx1Buf,"CIFSR") != NULL)
{
pAddr = strstr((char const *)Rx1Buf, "STAIP,\"") + 7;
while(*pAddr != '"')
{
esp8266IpAddr[i++] = *pAddr++;
}
uart0SendStr(esp8266IpAddr);
return SUCCESS;
}
// 其它AT指令
else if(strstr((char const *)Rx1Buf,"OK") == NULL)
{
//Wi-Fi模块没有返回"OK",异常
delayMs(300);
clearRx1Buf();
}
else
{
//Wi-Fi模块状态正常
delayMs(500);
clearRx1Buf();
return SUCCESS;
}
}
return FAILED;
}
/**************************************************************************
/
/ 功能:ESP8266模块通过AT指令连接OneNET服务器,并开启透传。
/
/ 返回值:无
**************************************************************************/
void connectOnenet(void)
{
sendAtCmd(AT_CWMODE); // 设置为AP/Station模式
delayMs(300);
//sendAtCmd(AT_CWLAP);
//delayMs(1000);
sendAtCmd(AT_CWJAP);
delayMs(1000);
//sendAtCmd(AT_CIFSR);
//delayMs(300);
sendAtCmd(AT_CIPSTART); // 连接OneNET服务器
delayMs(3000);
//sendAtCmd(AT_CIPMODE); // 透传模式
//delayMs(300);
sendAtCmd(AT_CIPSEND);
delayMs(500);
clearRx1Buf();
}
/**************************************************************************
/
/ 功能:ESP8266模块通过AT指令来实现两模块的通信
/
/
/ 返回值:无
**************************************************************************/
void WIFICONNECT()
{
extern char Rx1Buf[UART_MAX_SIZE];
sendAtCmd(AT_CWMODE); //设置STA模式
delayMs(300);
sendAtCmd(AT_CWJAP);//连接AP热点
delayMs(300);
if(strstr((char const *)Rx1Buf,"OK") == NULL)
{
uart0SendStr("WiFi热点连接成功!!\r\n");
clearRx1Buf();
delayMs(500);
sendAtCmd(AT_CONNECTWIFI);//连接AP创建的服务端
delayMs(300);
if(strstr((char const *)Rx1Buf,"OK") == NULL||strstr((char const *)Rx1Buf,"ERROR") != NULL)
{
uart0SendStr("服务器连接成功!!\r\n");
clearRx1Buf();
sendAtCmd(AT_CIPMODE); //设置为透传模式
delayMs(500);
if(strstr((char const *)Rx1Buf,"OK") == NULL)
{
uart0SendStr("进入透传模式成功!!\r\n");
sendAtCmd(AT_CIPSEND);
delayMs(300);
uart1SendStr("xxx");
}
else uart0SendStr("进入透传模式失败!!\r\n");
clearRx1Buf();
}
else uart0SendStr("服务器连接失败!!\r\n");
}
else
{
uart0SendStr("WiFi热点连接失败!!\r\n");
clearRx1Buf();
delayMs(500);
}
}
// 丁: 函数注释 SXTX是什么含义? 这个函数做什么事?
uint esp8266_SXTX(void)
{
extern char Rx0Buf[UART_MAX_SIZE];
extern uchar flag;
if(strstr((char const *)Rx0Buf,"*"))
{
clearRx0Buf();
delayMs(300);
flag=1;
//clearRx0Buf();
return 1;
}
else return 0;
}
3.ESP8266.h(STA)
//esp8266.h
#include "uart.h"
//ESP8266的AT命令
#define AT_AT "AT\r\n"
#define AT_RST "AT+RST\r\n"
#define AT_CWMODE "AT+CWMODE=1\r\n" // AP+STA
#define AT_CWLAP "AT+CWLAP\r\n"
#define AT_CWJAP "AT+CWJAP=\"YYY\",\"1234567890\"\r\n" // 注意字符串中带""号,需要转义符
#define AT_CIPMUX "AT+CIPMUX=1r\n"
#define AT_CIPSTART "AT+CIPSTART=\"TCP\",\"183.230.40.34\",80\r\n"
#define AT_CIPMODE "AT+CIPMODE=1\r\n" // 使用透传
#define AT_CIPSEND "AT+CIPSEND\r\n"
#define AT_CIPSERVER "AT+CIPSERVER=1,6666\r\n"
#define AT_CIFSR "AT+CIFSR\r\n" // AT+CIFSR 获取本地 IP
#define AT_CIPAP "AT+CIPAP?\r\n"
#define AT_CWSAP "AT+CWSAP=\"ALD16888\",\"12345678\",11,0\r\n"
#define AT_RESTORE "AT+RESTORE\r\n"
#define AT_CONNECTWIFI "AT+CIPSTART=\"TCP\",\"192.168.4.1\",9090\r\n"
#define RECV_LEN 100
//判断Wi-Fi发送过来的数据来解析出控制命令
#define IDENTIFIER "+IPD"
//Wi-Fi返回的数据
#define WIFI_NOT_LINK "link is not valid"
#define WIFI_CONNECT "CONNECT"
#define WIFI_GET_DATA "GETDATA"
#define WIFI_CON_FAIL "CONNECT FAIL"
#define WIFI_FAIL "FAIL"
#define SUCCESS 0
#define FAILED 1
extern uint8 SS;
uint8 checkEsp8266(void);
void resetEsp8266(void);
void connectOnenet(void);
uint esp8266_SXTX(void);
uchar sendAtCmd(char *cmdStr);
void WIFICONNECT();
4. uart.c(STA)
//uart.c
#include <ioCC2530.h>
#include <string.h>
#include "esp8266.h"
uchar U0Len = 0;
uchar U1Len = 0;
char Rx0Buf[UART_MAX_SIZE], Rx1Buf[UART_MAX_SIZE],DataBuf[UART_MAX_SIZE];
uchar flag=0;
/****************************************************************************
* 名 称: DelayMS()
* 功 能: 以毫秒为单位延时
* 入口参数: msec 延时参数,值越大,延时越久
* 出口参数: 无
****************************************************************************/
void delayMs(uint msec)
{
uint i,j;
for (i=0; i<msec; i++)
for (j=0; j<1070; j++);
}
/****************************************************************************
* 名 称: initUart0()
* 功 能: 串口初始化函数
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void initUart0(void)
{
PERCFG &= ~0x01; //指定USART0的IO口位置(候选位置1)
P0SEL |= 0x0c; //P0_2,P0_3置为外设模式
P2DIR &= ~0xc0; //P0优先作为UART0
U0CSR |= 0x80; //设置为UART方式
U0GCR |= 11;
U0BAUD |= 216; //波特率设为115200
//UTX0IF = 0; //UART0 TX中断标志初始置位0
U0CSR |= 0x40; //允许UART0接收
IEN0 |= 0x84; //开总中断允许接收中断
}
/****************************************************************************
* 名 称: InitUart1()
* 功 能: 串口初始化函数
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void initUart1(void)
{
PERCFG &= ~0x02; //指定USART1的IO口位置(候选位置1)
P0SEL |= 0x30; //P0_4,P0_5置为外设模式(手册P74)
U1CSR |= 0x80; //设置为UART方式
U1GCR |= 11;
U1BAUD |= 216; //波特率设为115200
//UTX1IF = 0; //UART1 TX中断标志初始置位0
U1CSR |= 0x40; //允许接收
IEN0 |= 0x88; //开总中断允许接收中断
}
/****************************************************************************
* 名 称: Uart0SendStr()
* 功 能: 串口发送函数
* 入口参数: Data-发送缓冲区
* 出口参数: 无
****************************************************************************/
void uart0SendStr(char *Data)
{
while(*Data != '\0')
{
U0DBUF = *Data++;
while(UTX0IF == 0);
UTX0IF = 0;
}
}
void uart1SendStr(char *Data)
{
while(*Data != '\0')
{
U1DBUF = *Data++;
while(UTX1IF == 0);
UTX1IF = 0;
}
}
/****************************************************************************
* 名 称: UART0_ISR(void) 串口中断处理函数
* 描 述: 当串口0产生接收中断,将收到的数据保存在Rx0Buf中
****************************************************************************/
//数据接收中断服务函数
#pragma vector = URX0_VECTOR
__interrupt void UART0_ISR(void)
{
if (U0Len < UART_MAX_SIZE)
{
Rx0Buf[U0Len++] = U0DBUF;
U1DBUF =U0DBUF;
//URX0IF = 0; // 在ISR中硬件会自动清除该中断标志
}
}
/****************************************************************************
* 名 称: UART1_ISR(void) 串口中断处理函数
* 描 述: 当串口1产生接收中断,将收到的数据保存在Rx1Buf中
****************************************************************************/
//数据接收中断服务函数
#pragma vector = URX1_VECTOR
__interrupt void UART1_ISR(void)
{
if (U1Len < UART_MAX_SIZE)
{
Rx1Buf[U1Len++] = U1DBUF;
if(flag == 1)
{
U0DBUF=U1DBUF;
}
//URX1IF = 0;
}
}
/****************************************************************************
* 名 称: clearRx0Buf()
* 功 能: 清空串口1接收缓冲区的数据
****************************************************************************/
void clearRx0Buf(void)
{
//发生异常时可以打开此注释来观察通讯情况
//Uart0SendString((char*)Uart1RxBuf); //通过串口0输出wifi返回的数据
memset(Rx0Buf, 0, UART_MAX_SIZE);
U0Len=0;
}
/****************************************************************************
* 名 称: clearRx1Buf()
* 功 能: 清空串口1接收缓冲区的数据
****************************************************************************/
void clearRx1Buf(void)
{
memset(Rx1Buf, 0, UART_MAX_SIZE);
U1Len=0;
}
3.uart.c(STA)
//uart.c
typedef unsigned int uint;
typedef unsigned char uint8;
typedef unsigned char uchar;
#define UART_MAX_SIZE 200
void delayMs(uint msec);
void initUart0(void);
void initUart1(void);
void uart0SendStr(char *Data);
void uart1SendStr(char *Data);
void clearRx1Buf(void);
void clearRx0Buf(void);
2. 复习了关于python的语法和基本操作