本文描述通过RA2E1的UART接口连接WIFI模块(RTL8710)通过AT指令获取网络天气信息
一、接线图
使用的WIFI模块为RTL8710,烧录原厂AT固件
RA2E1使用UART2连接RTL8710,波特率38400。
使用UART1连接PC,波特率115200,用作调试打印和结果输出
主要AT指令:
1、 ATSR :模块重启
2、 ATSE=1 :开启回显
3、 ATPW=1: station模式
4、 ATPN=ssid,password,,: 连接到AP
5、 ATPK=1 :设置自动接收
6、 ATPC=0,v1.yiketianqi.com,80: 与网站建立TCP连接
7、**ATPT=128,1:GET /api?unescape=1&version=v61&appid=84681915&appsecret=Vs4dufMa HTTP/1.1\r\nHost: gfeljm.tianqiapi.com:80\r\n\r\n**
向天气API网站发送调用API的url请求,以获取天气信息
二、FSP配置
UART1:
UART2:
三、程序
1、uart2回调函数
void user_uart2_callback (uart_callback_args_t * p_args)
{
switch (p_args->event)
{
case UART_EVENT_RX_CHAR:
{
if(Uart2_Num>=3000) Uart2_Num=0;
At_Rx_Buff[Uart2_Num++] = ( char ) p_args->data;
break;
}
case UART_EVENT_RX_COMPLETE:
{
uart2_receive_complete_flag=true;
break;
}
case UART_EVENT_TX_COMPLETE:
{
uart2_send_complete_flag = true;
break;
}
default:
break;
}
}
2、发送AT指令函数
void RTL8710_AT_Send(char *cmd )
{
R_SCI_UART_Write(&g_uart2_ctrl, (uint8_t *)cmd, strlen(cmd));
uart2_receive_complete_flag = false;
}
3、设置WIFI模块为station模式:
void RTL8710_STA ( uint8_t timeout )
{
uint8_t i;
RTL8710_AT_Send ( "ATPW=1\r\n" );
for(i = 0; i <= timeout; i++)
{
if (strstr( At_Rx_Buff , "OK\r\n" ))
{
RTL8710_DEBUG_MSG("\r\nset RTL8710 STA \r\n");
Clear_Buff();
break;
}
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
}
}
4、加入AP函数
void RTL8710_STA_JoinAP( char * id , char * password , uint8_t timeout )
{
char JoinAP_AT[256];
uint8_t i,j;
sprintf( JoinAP_AT , "ATPN=\"%s\",%s,,\r\n" , id , password);
RTL8710_AT_Send( JoinAP_AT );
for(i = 0; i <= timeout; i++)
{
if ( strstr( At_Rx_Buff , "OK\r\n" ) )
{
RTL8710_DEBUG_MSG("\r\nWifi connected\r\n");
Clear_Buff();
break;
}
if ( strstr( At_Rx_Buff , "ERROR\r\n" ) )
{
RTL8710_DEBUG_MSG("\r\nERROR\r\n");
for(j=0;j<10;j++) RTL8710_ERROR_Alarm();
}
if ( i == timeout )
{
RTL8710_DEBUG_MSG("\r\nRTL8710_STA_JoinAP timeout\r\n");
for(j=0;j<10;j++) RTL8710_ERROR_Alarm();
}
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
}
}
5、连接到远端网络
void RTL8710_STA_Connect(char mode,char *addr,char *port,uint8_t timeout)
{
char JoinAP_AT[256];
uint8_t i,j;
sprintf( JoinAP_AT , "ATPC=%d,%s,%s\r\n",mode,addr,port);
RTL8710_AT_Send( JoinAP_AT );
for(i = 0; i <= timeout; i++)
{
if ( strstr( At_Rx_Buff , "con_id" ) )
{
con_id=getNumber(At_Rx_Buff,"con_id=");
RTL8710_DEBUG_MSG("\r\nWifi con_id:%d\r\n",con_id);
Clear_Buff();
break;
}
else if ( strstr( At_Rx_Buff , "ERROR\r\n" ) )
{
RTL8710_DEBUG_MSG("\r\nRTL8710_STA_Connect ERROR,ERROR INRO %s\r\n",At_Rx_Buff);
for(j=0;j<10;j++) RTL8710_ERROR_Alarm();
}
if ( i == timeout )
{
RTL8710_DEBUG_MSG("\r\nRTL8710_STA_Connect timeout\r\n");
for(j=0;j<10;j++) RTL8710_ERROR_Alarm();
}
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
}
}
6、向远端发送数据
void RTL8710_STA_SendData(char *Data,uint8_t timeout)
{
char JoinAP_AT[256];
uint8_t i,j;
sprintf( JoinAP_AT , "ATPT=%d,%d:%s\r\n",strlen(Data),con_id,Data);
RTL8710_AT_Send( JoinAP_AT );
for(i = 0; i <= timeout; i++)
{
if(uart2_receive_complete_flag)
{
uart2_receive_complete_flag=false;
RTL8710_DEBUG_MSG(At_Rx_Buff);
Clear_Buff();
}
if ( strstr( At_Rx_Buff ,"ERROR:7" ) )
{
strcpy(weather_buff,At_Rx_Buff);
Clear_Buff();
break;
}
if ( i == timeout )
{
RTL8710_DEBUG_MSG("\r\nRTL8710_STA_SendData TIMEOUT\r\n");
for(j=0;j<10;j++) RTL8710_ERROR_Alarm();
}
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
}
}
7、设置或取消自动接收数据
void RTL8710_STA_ATPK(int enable,uint8_t timeout)
{
char JoinAP_AT[256];
uint8_t i;
sprintf( JoinAP_AT , "ATPK=%d\r\n",enable);
RTL8710_AT_Send( JoinAP_AT );
for(i = 0; i <= timeout; i++)
{
if ( strstr( At_Rx_Buff , "OK\r\n" ) )
{
RTL8710_DEBUG_MSG("\r\nATPK success\r\n");
Clear_Buff();
break;
}
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
}
}
8、断开连接
void RTL8710_STA_DisConnect(int id,uint8_t timeout)
{
char JoinAP_AT[256];
uint8_t i;
sprintf( JoinAP_AT , "ATPD=%d\r\n",id);
RTL8710_AT_Send( JoinAP_AT );
for(i = 0; i <= timeout; i++)
{
if ( strstr( At_Rx_Buff , "OK\r\n" ) )
{
RTL8710_DEBUG_MSG("\r\n disconnected success!\r\n");
Clear_Buff();
break;
}
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
}
}
9、调用前面的函数,获取网络天气数据
void RTL8710_STA_Test(void)
{
char buff[20];
char Data[]="GET /api?unescape=1&version=v61&appid=84681915&appsecret=Vs4dufMa HTTP/1.1\r\nHost: gfeljm.tianqiapi.com:80\r\nConnection: close\r\n\r\n";
RTL8710_STA(2);
RTL8710_STA_JoinAP( ID , PASSWORD , 5 );
RTL8710_STA_Connect(0, SeverIP , SeverPort , 5 );
RTL8710_STA_ATPK(1,5);
RTL8710_STA_SendData(Data,10);
getjson(weather_buff);
RTL8710_STA_DisConnect(con_id,5);
extract_item_from_json(weather_json,"\"cityEn\":\"",buff);
printf("CITY:[%s]\r\n",buff);
extract_item_from_json(weather_json,"\"tem\":\"",buff);
printf("tem:[%s]\r\n",buff);
extract_item_from_json(weather_json,"\"date\":\"",buff);
printf("date:[%s]\r\n",buff);
}
10、从网站返回的信息中提取除json数据段
void getjson(char *Data)
{
char *start,*end;
size_t length;
start=strstr(Data,"{");
end=strstr(start,"\n");
length=end-start-1;
strncpy(weather_json,start,length);
start=end;
end=strstr(start,"[ATPR] OK,");
start=end;
end=strstr(start,":");
start=end+1;
end=strstr(start,"\n");
length=end-start-1;
strncpy(weather_json+strlen(weather_json),start,length);
weather_json[strlen(weather_json)] = '\0';
}
11、从json中解析出城市、温度、时间
本来想用cjson来解析的,但是一直没有成功,就自己解析了。
void extract_item_from_json(const char *json_str,char *itemname,char *target)
{
char *start = strstr(json_str, itemname);
char *end;
size_t len=20;
char item[20];
if (start != NULL) {
start += strlen(itemname);
end = strchr(start, '"');
if (end != NULL) {
len = end - start;
strncpy(item, start, len);
item[len] = '\0';
printf("Item: %s\n", item);
strncpy(target, item, len);
target[len] = '\0';
}
} else {
printf("Item[%s] not found in the JSON string.\n",itemname);
}
}
四、串口输出