阅读完本文,要能回答以下问题:
1、阐述例程主函数代码结构?首先是单片机串口初始化,然后是其余用到的外设初始化,最后是WIFI模块初始化,之后就是测试WIFI模块收发数据。详细代码如下:
int main(void)
{
u8 key,fontok=0;
//基本的外设初始化
Stm32_Clock_Init(360,25,2,8); //设置时钟,180Mhz
HAL_Init(); //HAL库初始化
delay_init(180); //初始化延时函数
uart_init(115200); //初始化USART1
usart3_init(115200); //初始化USART3
//下面就是些其他外设的初始化配置了,以后再来学习。
usmart_dev.init(90); //³õʼ»¯usmart
LED_Init(); //³õʼ»¯LED
KEY_Init(); //³õʼ»¯°´¼ü
SDRAM_Init(); //SDRAM³õʼ»¯
LCD_Init(); //LCD³õʼ»¯
W25QXX_Init(); //³õʼ»¯W25Q256
tp_dev.init(); //³õʼ»¯´¥ÃþÆÁ
my_mem_init(SRAMIN); //³õʼ»¯ÄÚ²¿ÄÚ´æ³Ø
my_mem_init(SRAMEX); //³õʼ»¯ÍⲿSDRAMÄÚ´æ³Ø
my_mem_init(SRAMCCM); //³õʼ»¯ÄÚ²¿CCMÄÚ´æ³Ø
exfuns_init(); //ΪfatfsÏà¹Ø±äÁ¿ÉêÇëÄÚ´æ
f_mount(fs[0],"0:",1); //¹ÒÔØSD¿¨
f_mount(fs[1],"1:",1); //¹ÒÔØSPI FLASH.
key=KEY_Scan(0);
if((key==KEY0_PRES)&&(tp_dev.touchtype&0X80)==0) //Ç¿ÖÆУ׼£¬µç×èÆÁ²ÅÐèҪУ׼
{
LCD_Clear(WHITE); //ÇåÆÁ
TP_Adjust(); //ÆÁĻУ׼
TP_Save_Adjdata();
LCD_Clear(WHITE); //ÇåÆÁ
}
fontok=font_init(); //¼ì²é×Ö¿âÊÇ·ñOK
if(fontok||key==KEY1_PRES)//ÐèÒª¸üÐÂ×Ö¿â
{
LCD_Clear(WHITE); //ÇåÆÁ
POINT_COLOR=RED; //ÉèÖÃ×ÖÌåΪºìÉ«
LCD_ShowString(60,50,200,16,16,"ALIENTEK STM32");
while(SD_Init()) //¼ì²âSD¿¨
{
LCD_ShowString(60,70,200,16,16,"SD Card Failed!");
delay_ms(200);
LCD_Fill(60,70,200+60,70+16,WHITE);
delay_ms(200);
}
LCD_ShowString(60,70,200,16,16,"SD Card OK");
LCD_ShowString(60,90,200,16,16,"Font Updating...");
key=update_font(20,110,16,"0:");//´ÓSD¿¨¸üÐÂ
while(key)//¸üÐÂʧ°Ü
{
LCD_ShowString(60,110,200,16,16,"Font Update Failed!");
delay_ms(200);
LCD_Fill(20,110,200+20,110+16,WHITE);
delay_ms(200);
}
LCD_ShowString(60,110,200,16,16,"Font Update Success!");
delay_ms(1500);
LCD_Clear(WHITE);//ÇåÆÁ
}
//到这里都是其他外设的配置,先不研究
atk_8266_test(); //ATK_ESP8266的测试
}
串口通信的初始化配置已在前文介绍,其余用到的外设初始化本文暂时不涉及。下面重点关注WIFI测试函数void atk_8266_test(void),
2.atk_8266_test函数流程是什么样的?首先测试WIFI模块能否正常应答,当WIFI模块能够应答后,先关闭其事先设置好的透传模式(关于透传模式是什么,看这篇文章.),然后按键选择不同的透传模式。一共有三种模式可以选择:STA+AP、STA、AP。配置好模式后,测试WIFI模块收发数据。整个流程的具体代码如下所示:
void atk_8266_test(void)
{
// u16 rlen=0;
u8 key;
u8 timex;
POINT_COLOR=RED;
Show_Str_Mid(0,30,"ATK-ESP8266 WIFIÄ£¿é²âÊÔ",16,240);
while(atk_8266_send_cmd("AT","OK",20))//检查WIFI模块是否能够应答
{
atk_8266_quit_trans();//退出透传
atk_8266_send_cmd("AT+CIPMODE=0","OK",200); //关闭透传模式
Show_Str(40,55,200,16,"未检查到模块",16,0);
delay_ms(800);
LCD_Fill(40,55,200,55+16,WHITE);
Show_Str(40,55,200,16,"尝试连接模块...",16,0);
}
while(atk_8266_send_cmd("ATE0","OK",20));//关闭回显,以为会死循环,后来才发现有break语句跳出while循环。如果没有break就一直配置。
atk_8266_mtest_ui(32,30);
while(1)
{
delay_ms(10);
atk_8266_at_response(1);//¼ì²éATK-ESP8266Ä£¿é·¢Ë͹ýÀ´µÄÊý¾Ý,¼°Ê±ÉÏ´«¸øµçÄÔ
key=KEY_Scan(0);
if(key)
{
LCD_Clear(WHITE);
POINT_COLOR=RED;
switch(key)
{
case 1://KEY0
Show_Str_Mid(0,30,"ATK-ESP WIFI-AP+STA ²âÊÔ",16,240);
Show_Str_Mid(0,50,"ÕýÔÚÅäÖÃATK-ESP8266Ä£¿é£¬ÇëÉÔµÈ...",12,240);
atk_8266_apsta_test(); //STA+AP
break;
case 2://KEY1
Show_Str_Mid(0,30,"ATK-ESP WIFI-STA ²âÊÔ",16,240);
Show_Str_Mid(0,50,"ÕýÔÚÅäÖÃATK-ESP8266Ä£¿é£¬ÇëÉÔµÈ...",12,240);
atk_8266_wifista_test();//WIFI STA模式
break;
case 4://WK_UP
atk_8266_wifiap_test(); //WIFI AP模式
break;
}
atk_8266_mtest_ui(32,30);
timex=0;
}
if((timex%20)==0)LED0=!LED0;//200msÉÁ˸
timex++;
}
}
3、STA+AP、STA、AP三种模式是什么意思?
通过上一节我们知道了,在WIFI测试函数里面,单片机与wifi模块的通讯,是通过发送AT指令并等待应答实现的。发送AT指令对应的函数是atk_8266_send_cmd()函数,代码如下:
u8 atk_8266_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
u8 res=0;
USART3_RX_STA=0;
u3_printf("%s\r\n",cmd); //串口3发送数据
if(ack&&waittime) //如果需要等待应答
{
while(--waittime) //等待时间开始倒计时
{
delay_ms(10);
if(USART3_RX_STA&0X8000)//接收到读操作的标记位
{
if(atk_8266_check_cmd(ack))
{
printf("ack:%s\r\n",(u8*)ack);
break;//做出应答回复,结束程序
}
USART3_RX_STA=0;
}
}
if(waittime==0)res=1;
}
return res;
}
简单分析一轮atk_8266_send_cmd()函数:
void u3_printf(char* fmt,...)
{
u16 i,j;
va_list ap;
va_start(ap,fmt);
vsprintf((char*)USART3_TX_BUF,fmt,ap);
va_end(ap);
i=strlen((const char*)USART3_TX_BUF); //此次发送数据的长度
for(j=0;j<i;j++) //循环发送数据
{
while((USART3->SR&0X40)==0); //不断将要发送的数据写入UART3的数据寄存器中
USART3->DR=USART3_TX_BUF[j];
}
}
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}
u8* atk_8266_check_cmd(u8 *str)
{
char *strx=0;
if(USART3_RX_STA&0X8000) //½ÓÊÕµ½Ò»´ÎÊý¾ÝÁË
{
USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//Ìí¼Ó½áÊø·û
strx=strstr((const char*)USART3_RX_BUF,(const char*)str);
}
return (u8*)strx;
}
WIFI模块有三种模式可以选择:STA+AP、STA、AP。本文只剖析sta模式(ap模式后续再说)的测试代码,对应于函数atk_8266_wifista_test()
1、简述配置STA模式的代码架构?代码流程如下:
u8 atk_8266_wifista_test(void)
{
//......
//设置为STA模式
atk_8266_send_cmd("AT+CWMODE=1","OK",50); //设置为STA模式
//......
//配置无线参数,连接目标路由器
sprintf((char*)p,"AT+CWJAP=\"%s\",\"%s\"",wifista_ssid,wifista_password);
while(atk_8266_send_cmd(p,"WIFI GOT IP",300));
//......
//配置网络模式
netpro|=atk_8266_netpro_sel(50,30,(u8*)ATK_ESP8266_CWMODE_TBL[0]);
if(netpro&0X02) //UDP
{
}
else//TCP
{
if(netpro&0X01)//TCP Client
{}
else//TCP Server
{}
}
while(1)
{
key=KEY_Scan(0);
if(key==WKUP_PRES)//WK_UP 退出测试
{
}
else if(key==KEY0_PRES)//KEY0 发送数据
{
if((netpro==3)||(netpro==2)) //UDP
{}
else if((netpro==1)) //TCP Client
{}
else //TCP Server
}
else;
//......
if(USART3_RX_STA&0X8000) //如果接收到数据
{
//将接收到的数据打印到串口
}
t++;
if(t==1000)
{
//检查wifi模块连接状态
}
if((t%20)==0)LED0=!LED0;//程序正常运行的指示灯
}
myfree(SRAMIN,p); //释放内存
return res;
}
2、STA模式下有三种子模式(TCP服务器、TCP客户端和UDP)是什么意思?
在选择TCP进行通信的时候,通信的双方,必须一方为TCP客户端(TCP Client),一方为TCP服务器(TCP Server)。以打电话来类比,打电话的人是TCP客户端,接电话的一方为TCP服务器。TCP/IP协议中的IP地址类似电话号码,而TCP/IP中的端口号类似电话分机号。客户端(拨电话者),首先需要知道对方的IP地址和端口(电话号码和分机号),先连接上TCP服务器端(接听者的电话摘机),才能进行数据传输(通话)。和一般电话不同,在这里TCP服务器可以同时接入多个TCP客户端,就如有多路线路的电话,不会因为一路电话在接通中而不能接入其它电话。
1、如何将wifi模块配置成TCP客户端?此时WIFI模块作为打电话的一方,最重要的步骤就是输入对方的电话号码,对应函数atk_8266_ip_set(),该函数通过显示屏按键输入远端IP地址。
if(netpro&0X01) //TCP Client ͸´«Ä£Ê½²âÊÔ
{
LCD_Clear(WHITE);
POINT_COLOR=RED;
Show_Str_Mid(0,30,"ATK-ESP WIFI-STA ²âÊÔ",16,240);
Show_Str(30,50,200,16,"ÕýÔÚÅäÖÃATK-ESPÄ£¿é,ÇëÉÔµÈ...",12,0);
if(atk_8266_ip_set("WIFI-STA Ô¶¶ËIPÉèÖÃ",(u8*)ATK_ESP8266_WORKMODE_TBL[netpro],(u8*)portnum,ipbuf))goto PRESTA; //IPÊäÈë
atk_8266_send_cmd("AT+CIPMUX=0","OK",20); //0£ºµ¥Á¬½Ó£¬1£º¶àÁ¬½Ó
sprintf((char*)p,"AT+CIPSTART=\"TCP\",\"%s\",%s",ipbuf,(u8*)portnum); //ÅäÖÃÄ¿±êTCP·þÎñÆ÷
while(atk_8266_send_cmd(p,"OK",200))
{
LCD_Clear(WHITE);
POINT_COLOR=RED;
Show_Str_Mid(0,40,"WK_UP:·µ»ØÖØÑ¡",16,240);
Show_Str(30,80,200,12,"ATK-ESP Á¬½ÓTCPʧ°Ü",12,0); //Á¬½Óʧ°Ü
key=KEY_Scan(0);
if(key==WKUP_PRES)goto PRESTA;
}
atk_8266_send_cmd("AT+CIPMODE=1","OK",200); //´«ÊäģʽΪ£ºÍ¸´«
}
1、如何发送数据?当WIFI模块已经和远端IP建立好连接后,只要单片机开启透传模式,然后向串口3(连接WIFI模块的串口)写数据就可以发送数据了。
else if((netpro==1)) //TCP Client
{
atk_8266_quit_trans();
atk_8266_send_cmd("AT+CIPSEND","OK",20); //¿ªÊ¼Í¸´«
sprintf((char*)p,"ATK-8266%s测试%d\r\n",ATK_ESP8266_WORKMODE_TBL[netpro],t/10);//待发送的数据
Show_Str(30+54,100,200,12,p,12,0);
u3_printf("%s",p);
timex=100;
}