搜索

[活动专区] 【赛元95F】基于SC95F8617开发记录

[复制链接]
1629|2
 楼主 | 2020-4-6 17:35 | 显示全部楼层 |阅读模式
【赛元95F】基于SC95F8617开发记录(二)

    由于之前发过一篇帖子,这里就不再赘述之前的事情了。

    那本次的开发呢是基于SC95F8617的远程温度监测,可添加湿度,光照等模块,一般适用于工厂、花圃等场景,基本可以做到“管理不出门,便知工作事”。

    本次使用的器件主要有:SC95F8617开发核心板,烧录工具,CP2102-USB转串口工具,数字温度传感器DS18B20,基于ESP8266的NodeMCU,TFT 1.8寸液晶显示屏一块,杜邦线若干,面包板一块,电阻电容若干,LED指示灯若干以及其他一些选择性配件。

    本次开发的目的就是远端可以一直采集数据(温湿度等),通过TFT彩屏显示,近端呢可以通过APP与WIFI模块通信实时查看远端情况,实现结果如下图。

866665e8aec827e418.png

    关于本次电路供电之前规划的是选用9V-DC电源输入,然后9V通过器件输出5V,5V再通过器件转为3.3V,为了方便一点,本次采用烧录工具里的3.3V输出供电。

    开发板SC95F8617选择32M的时钟,UART波特率选择115200bps。

    接下来,我会分模块讲述我的实现方法。

(一)DS18B20数字温度传感器

    由于生活在南方,暂时没考虑过温度为负的情况,所以程序上也没有增加这个处理,后期会补充。

    DS18B20基本上大家用的也比较多,这里不再过多赘述。值得注意的是该传感器是12位精度的,采样出来的值需要乘以0.0625才是我们需要的温度数值。接线呢也是十分简单,一般会在DQ总线上增加一个4.7K的上拉电阻,不过对工作时序的要求会高一点,即需要延时函数恰当合理。模块接线图如下:

299345e8ae5c0f0596.png

由于DQ引脚既作为输入也作为输出,所以在程序处理的时候需要切换。我的处理如下:

  1. #define        BS(SFR,NUM)                (SFR|= NUM)            //BIT位置1
  2. #define        BC(SFR,NUM)                (SFR&=~(NUM))        //BIT位清0
  3. #define DS18B20_DQ              P00
  4. #define DS18B20_DQ_OUTPUT()     {BS(P0CON,BIT0);}
  5. #define DS18B20_DQ_INPUT()      {BC(P0CON,BIT0);}
复制代码
这样的话该模块基本不用初始化了;由于初期写的程序,没有采用等待超时的方法。完整的模块代码如下:

  1. u16 DS18B20_GetTemp(void)
  2. {
  3.         u8 TPH,TPL;                     //存放温度值的高字节和低字节
  4.         u16 Temp;                       //存放临时转换数据
  5.     DS18B20_Reset();                //设备复位
  6.     DS18B20_WriteByte(SkipROM);     //跳过ROM命令
  7.     DS18B20_WriteByte(TemperatureConversion);        //开始转换命令
  8.     while (!DS18B20_DQ);            //等待转换完成
  9.     DS18B20_Reset();                //设备复位
  10.     DS18B20_WriteByte(SkipROM);     //跳过ROM命令
  11.     DS18B20_WriteByte(ReadData);    //读暂存存储器命令
  12.     TPL = DS18B20_ReadByte();       //读温度低字节
  13.     TPH = DS18B20_ReadByte();       //读温度高字节
  14.           
  15.         Temp=(TPH<<8)+TPL;
  16.         return Temp;
  17. }

  18. void DS18B20_Reset(void)
  19. {
  20.     CY = 1;
  21.     while (CY)
  22.     {
  23.         DS18B20_DQ_OUTPUT();
  24.         DS18B20_DQ = 0;                    
  25.         DelayXus(240);              
  26.         DelayXus(240);
  27.         DS18B20_DQ = 1;                     
  28.         DelayXus(60);
  29.         DS18B20_DQ_INPUT();        
  30.         CY = DS18B20_DQ;                  
  31.         DelayXus(240);              
  32.         DelayXus(180);
  33.     }
  34. }

  35. void DS18B20_WriteByte(u8 dat)
  36. {
  37.         unsigned char i;
  38.         for(i=0;i<8;i++)
  39.         {
  40.         DS18B20_DQ_OUTPUT();
  41.                 DS18B20_DQ = 0;
  42.                 DelayXus(1);
  43.                 dat >>=1;
  44.                 DS18B20_DQ = CY;
  45.                 DelayXus(60);
  46.                 DS18B20_DQ = 1;
  47.                 DelayXus(1);       
  48.         }
  49. }

  50. u8 DS18B20_ReadByte(void)
  51. {
  52.         u8 i;
  53.         u8 dat = 0;
  54.         for (i=0; i<8; i++)            
  55.     {
  56.         DS18B20_DQ_OUTPUT();
  57.         dat >>= 1;
  58.         DS18B20_DQ = 0;                     
  59.         DelayXus(1);               
  60.         DS18B20_DQ = 1;                     
  61.         DelayXus(1);
  62.         DS18B20_DQ_INPUT();        
  63.         if (DS18B20_DQ)
  64.         {
  65.            dat |= 0x80;  
  66.         }      
  67.         DelayXus(60);               
  68.     }
  69.         return dat;
  70. }

  71. void DelayXus(u16 n)
  72. {
  73.         while(n--)
  74.         {
  75.                 _nop_();
  76.                 _nop_();
  77.         _nop_();
  78.                 _nop_();
  79.         }
  80. }
复制代码
值得注意的是,该模块使用的延时函数暂只能适用于时钟速率为32MHz的情况下。用于宏定义的一些处理命令如下:

  1. //DQ端需加一个4.7K上拉电阻
  2. //=============================================================
  3. #define TemperatureConversion          0x44    //开始转换命令
  4. #define ReadROM                 0x33    //读ROM
  5. #define MatchROM                0x55    //匹配ROM
  6. #define SearchROM               0xF0    //搜索ROM
  7. #define AlarmSearch             0xEC    //告警搜索
  8. #define SkipROM                                        0xCC    //跳过ROM地址
  9. #define ReadData                                0xBE        //读暂存存储器命令
  10. #define        ClearStorage            0x4E           //写暂存存储器置零
  11. #define ReadPowerMode                        0xB4    //读电源供电方式
  12. //=============================================================
复制代码
调用DS18B20_GetTemp()方法就能获得一次温度采样原始数值;

(二)驱动TFT 1.8寸(ST7735S)彩色液晶显示屏

    本次使用的液晶显示屏自带了可插入SD卡用于存放字库的模块,由于我这边没有买SD卡,所以暂时未能使用。该模块使用的是SPI驱动方式,刚好SC95F8617上有很多SPI接口。我的外部接线图如下,TFT_SCK接P0.4,TFT_SDA接P0.5,其他的自行选择;

661855e8aedfc3a5b9.png

    所以本次使用的是硬件SPI作为主机驱动,SPI速率2MHz,模式0,这样就能提高效率。SPI初始化的过程可参考赛元提供的Demo程序,以下是我的字节数据传送和接收的函数,仅供参考。

  1. /********************************************
  2. * 函数名        :u8 USCI0_SPI_SendReadByte(u8 wdat)
  3. * 功能                :SPI读写一个字节
  4. ********************************************/
  5. u8 USCI0_SPI_SendReadByte(u8 wdat)
  6. {
  7.    US0CON2 = wdat;
  8.    while(!USCI0_SPI_SendFlag);
  9.    USCI0_SPI_SendFlag = 0;
  10.    return US0CON2;
  11. }
复制代码
关于这块LCD屏的规格等参考资料等可以通过附件查看。由于此次还使用了点阵汉字的显示,所以还需要使用字模提取软件提取点阵字符。这块LCD屏的点阵字符提取方式可能和其他不太一样,我的这块方式如下:

558975e8af07a188e5.png


在字模提取软件确认参数之后,输入想要提取的字符就能输出字模表,当然也是可以自定义字符的,我的温度单位(摄氏度)就是自定义的字符,字模提取软件见附件。

还有一个很重要的就是,LCD屏显示汉字需要根据你所使用的字符点阵的大小设置显示坐标,这个很关键,不然会乱码的。如果遇到只能显示汉字的一半,多半是显示的方法不对,附上我的16*16点阵显示代码吧!

  1. /********************************************
  2. * 函数名        :void LCD_Show_Character(u16 x,u16 y,u8 index,u8 *character)
  3. * 功能                :在指定位置显示一个汉字(16*16大小)
  4. ********************************************/
  5. void LCD_Show_Character(u16 x,u16 y,u8 index,u8 *word)       
  6. {  
  7.         u8 i,j;
  8.         u8 *temp=word;   
  9.     Address_set(x,y,x+16-1,y+16-1); //设置区域      
  10.         temp+=index*32;            //32是一个汉字占的字节数
  11.         for(j=0;j<32;j++)   //显示一个汉字
  12.         {
  13.                 for(i=0;i<8;i++)
  14.                 {                      
  15.                          if((*temp&(1<<i))!=0)
  16.                         {
  17.                                 LCD_WR_DATA(POINT_COLOR);
  18.                         }
  19.                         else
  20.                         {
  21.                                 LCD_WR_DATA(BACK_COLOR);
  22.                         }   
  23.                 }
  24.                 temp++;
  25.          }   
  26. }
复制代码
今天就到这里了,经过这一轮的努力,收获还是不小呢。加油!冲啊……

万水千山总是情,不试怎知行不行!附上我的一些参考资料吧!

如上述描述操作有误,希望大家不吝赐教。


下一站,WIFI模块!







19595e8aef62eb58f.png

LcmZimoLCD字模提取工具软件.zip

3.07 MB, 阅读权限: 10, 下载次数: 6

ST7735S_V1.1_20111121.pdf

2.49 MB, 阅读权限: 10, 下载次数: 11

使用特权

评论回复
 楼主 | 2020-4-6 23:32 | 显示全部楼层
【赛元95F】基于SC95F8617开发记录(三)

      轻轻的我又来了,带来的是故事和酒。

      来,咱们干完这杯接着说。上一节讲完了如何驱动LCD屏,现在咱们来探索一下如何驱动WIFI模块与之(MCU)通信。

      直接开门见山吧,本次使用的WIFI模块是基于ESP8266的NodeMCU,引脚图对应参考如下:
       526005e8b2c2cbbe00.png

      拿到NodeMCU,首先需要的是刷固件,由于我这块WIFI模组上的USB转串口不能使用,所以需要单独使用CP2102连线ESP8266的GPIO0等引脚,其中GPIO0为默认高电平代表从FLASH启动,GPIO0为低电平代表进入系统升级状态进而可以经过串口升级内部固件。我这边刷的是安信可公司提供的一个集成AT指令的固件,当然也可以根据需要去刷相应的固件。烧写界面图及相应设置如下:


400785e8b2ef3e0421.png


      如果遇到升级固件失败,可以试着把波特率调低一点,不过等待的时间就需要更长啦。
      成功升级固件之后呢,可以通过ESPlorer(需要安装JDK环境)编辑基于lua的脚本语言代码上传到NodeMCU,我这边建议在写代码前可以看看网上一些大神的资料,附上链接吧:https://www.jianshu.com/p/ecc6a8ec024d,里面清楚的讲述了从环境的配置到Lua语言的基础再到各个功能模块的使用,真的非常详细。以下呢,是一段init.lua设置ESP8266工作在STA模式的代码示例:
  1. -- init.lua
  2. print('Setting up WIFI...')
  3. wifi.setmode(wifi.STATION)
  4. wifi.sta.config('A+B', '123456')
  5. wifi.sta.connect()

  6. tmr.alarm(1, 1000, tmr.ALARM_AUTO, function()
  7.     if wifi.sta.getip() == nil then
  8.         print('Waiting for IP ...')
  9.     else
  10.         print('IP is ' .. wifi.sta.getip())
  11.     tmr.stop(1)
  12.     end
  13. end)
复制代码
     由于一些原因,咱们这次使用AT指令的方式去操作ESP8266。(需先刷写带AT指令的固件)
      AT指令呢,其实就是终端设备与PC应用之间的连接与通信的指令,英文全称“Attention”。每条AT命令行中只能包含一条AT指令,对于发送而言,除了AT两个字符外,最多可以接收1056个字符的长度(包括了空字符)。AT指令示例:
       549125e8b32b52917a.png
      其他更多AT指令可参考AT指令使用说明文档。
      本次使用的是SC95F8617的UART与ESP8266通信(MCU的TX接8266的RX,MCU的RX接8266的TX)完成AT指令的收发,通信的波特率是115200bps。调试工具可以选择任何一个串口助手收发AT指令,我推荐选用安信可串口调试助手,因为上面包含了经常使用的AT指令,使用起来快捷方便。其实ESPlorer里面也可以调试呢。我这边为了调试方便,引了一根线从MCU的RX接入CP2102的RXD,然后使用仿真的方式调试。
      先说一下模块的工作模式AP  Station  AP+Station
68125e8b3dda3fe5a.png
537185e8b3dfe51d68.png
      下面讲一下在不同模式下使用不同协议的常用AT指令配置:
(1) AP 模式下作为 TCP server
AT+CWMODE=2               // 开启 AP 模式
AT+CWSAP="ESP8266","0123456789",11,0            //设置模块的 wifi 和密码
AT+CIPSERVER=1,8080        //设置模块服务器端口,即建立了WIFI热点,默认的 ip 为 192.168.4.1,端口为自己设定的 8080(默认为 333)
AT+CIPSEND=0,X           //进入数据发送模式为X个字节,X值自己设定
>                           //进入发送模式

(2)STA 模式下作为 TCP server(本次我使用的模式
AT+CWMODE=1              //设置模组为STA模式。
AT+CWLAP             //查询附近 WIFI
AT+CWJAP="SSID","Password"   //连接 WIFI,SSID和Password需替换
AT+CIFSR                //查看路由器分配给模组的IP地址,例如 192.168.1.101
AT+CIPMUX=1                     //打开多连接
AT+CIPSERVER=1,8080       //设置模块服务器端口
AT+CIPSEND=0,16          //进入数据发送模式为16个字节

(3)STA模式下 TCP  Client 透传模式
AT+CWMODE=1                //设置模组为STA模式
AT+CWLAP                  //查询附近 WIFI
AT+CWJAP="SSID","Password"    //连接路由器的 WIFI
AT+CIFSR                  //查看路由器分配给模组的IP地址,例如 192.168.1.101
AT+CIPMUX=0                //设置单连接
AT+CIPMODE=1               //设置透传模式
AT+CIPSTART="TCP","192.168.1.108",8080     //连接手机端建立的TCP服务器
AT+CIPSEND                        //开始发送数据
>                             // 进入发送模式
Hello                 // 发送数据
+++                       // 注意退出透传,直接发送。取消发送新行
值得注意的是:透传只能在单连接模式下进行,所以在建立连接之前一定要用(AT+CIPMUX=0设置单连接),但是模块处于服务器模式下时,必须要多链接,由于冲突,所以模块开启服务器模式不能做 TCP透传。

(4)UDP 多连接模式
AT+CWMODE= 1                         //设置 STA模式
AT+CWLAP                                  // 查询附近 WIFI
AT+CWJAP="SSID","Password"      //  连接 WIFI
AT+CIFSR                                  // 查看模块当前的 IP
AT+CIPMUX=1                                // 打开模块多连接
AT+CIPSTART=0,"UDP","255.255.255.255",50000,1000, 0       //是建立 UDP 连接,其中手机 UDP server 设置 50000,UDP client 设置的端口 1000 AT+CIPSEND=0,11                             // 模块发送数据模式为 9 个字节


(5) 模块通过数据外网透传
AT+CWMODE=3      //设置 AP 和 STA 共存模式
AT+CWLAP            //查询附近 WIFI
AT+CWJAP="CMCC","12345678"           //连接 wifi
AT+CIPMUX=0                         // 设置单连接
AT+CIPMODE=1                        //设置透传模式
AT+CIPSTART="TCP","115.29.109.104",6602    //连接外网服务器
AT+CIPSEND         //发送数据
>
(6)当然了也可以使用智能配网,通过以下两种方式进行配网:乐鑫ESP-Touch APP和微信Airkiss。更多AT指令可以通过附件查看哦。
//******************这是一条分界线************************//     
接下来该讲一下我的实现方法啦:1、UART的配置我是参考了Demo程序,波特率设为115200bps,记得TXD和RXD要设置成输入带上拉模式,这个我入坑了,后面才发现的。
UART的发送不使能中断,在中断里接收AT指令的返回结果,由于MCU-UART接收的数据长度不固定,所以我这边设置了最长接收100个字节的Buffer,超过了就不存入,还有,由于很多返回结果只有OK或其他指令,我这边也设置了假设接收到了“OK”字符就标记为接收完成。整个的一个UART中断服务函数和字节发送、字符串发送函数如下:
  1. bit comm_flag1=0,comm_flag2=0;
  2. u8 first_flag=1;
  3. void UART_Interrupt(void) interrupt 4  using 1
  4. {
  5.     u8 res=0;
  6.         if(RI)  
  7.         {
  8.         RI=0;
  9.                 res = SBUF;
  10.         if((UART_RX_STATUS&(1<<15))==0)//接收完的一批数据,还没有被处理,则不再接收其他数据
  11.         {
  12.             if(UART_RX_STATUS < 100)//还可以接收数据
  13.             {  
  14.                 if((con_state==1))
  15.                 {   if(res == ':') first_flag=0;
  16.                     if(first_flag==0)
  17.                     {
  18.                        if(res == 'T')
  19.                        {
  20.                             u16 Get_Current_Temp=0;
  21.                             Get_Current_Temp=DS18B20_GetTemp();
  22.                             Get_Current_Temp=Get_Current_Temp*0.0625;
  23.                             con_state=0;
  24.                             ESP8266_SendCmd("AT+CIPSEND=0,16","OK",20);
  25.                             {
  26.                                 //u8 *p;
  27.                                 u16 Get_Current_Temp=0;
  28.                                 //p=malloc(18);
  29.                                 Get_Current_Temp=DS18B20_GetTemp();
  30.                                 Get_Current_Temp=Get_Current_Temp*0.0625;
  31.                                 //sprintf((char*)p,"Current_Temp:%2d C\r\n",Get_Current_Temp);
  32.                                 ESP8266_SendCmd("Today is Moday\r\n","OK",20);
  33.                                 //free(p);
  34.                             }
  35.                        }                           
  36.                     }                        
  37.                 }
  38.                 else
  39.                 {
  40.                     UART_RX_BUFFER[UART_RX_STATUS++]=res;//记录接收到的值
  41.                     if(res == 'O')   //判断是否回传"OK"
  42.                     {
  43.                         comm_flag1=1;
  44.                     }
  45.                     if(res == 'K')   //判断是否回传"OK"
  46.                     {
  47.                         comm_flag2=1;
  48.                     }
  49.                     if(comm_flag1&comm_flag2)
  50.                     {
  51.                         comm_flag1=comm_flag2=0;
  52.                         UART_RX_STATUS |= 1<<15;        //强制标记接收完成  
  53.                     }
  54.                 }                        
  55.             }
  56.             else
  57.             {
  58.                 UART_RX_STATUS |= 1<<15;        //强制标记接收完成
  59.             }
  60.         }
  61.     }
  62.     if(TI)
  63.     {
  64.         TI=0;
  65.     }
  66.    
  67. }
  68. //********************************************
  69. // 函数名        :void SendData(u8 DATA)
  70. // 功能                :Uart发送一个Byte
  71. //********************************************
  72. void UART0_SendByte(u8 dat)
  73. {
  74.     EUART = 0;
  75.         TI = 0;
  76.         SBUF = dat;
  77.         while(!TI);
  78.     TI = 0;
  79.     EUART = 1;
  80. }
  81. void UART_SendString(u8* buf)
  82. {
  83.     while(*buf!='\0')                      
  84.         {   
  85.                 UART0_SendByte(*buf);      
  86.                 buf++;   
  87.         }
  88. }
复制代码
申明:由于C51编译器里面不知道是不是不能通过sprintf来将数字转化为字符,所以远程接收温度值暂时有问题,不过接收字符串等文本形式还是可以的。后期呢,我会想下解决的方法,其实我最喜欢用sprintf了,嘿嘿!
2、接下来就是进入对ESP8266的一些操作啦,我这边先是使用while等待通过AT指令对其复位和关闭回显操作,关于回显是啥咱们下期讲,复位之后需延时几秒。代码如下
533575e8b41b57a0d5.png
其中呢,这个ESP8266_SendCmd既可以发送Cmd也可以发送dat用,里面的UART_RX_STATUS(u16)用来作为接收的判断,最高位用来作为接收数据的标记(1:有数据,0:无有效数据),其他位作为接收数据的长度,函数方法如下:
  1. //ESP8266发送命令后,检测接收到的应答
  2. //str:期待的应答结果
  3. //返回值:0,没有得到期待的应答结果
  4. //       其他,期待应答结果的位置(str的位置)
  5. u8* ESP8266_CheckCmd(u8 *str)
  6. {       
  7.         char *strx=0;
  8.         if(UART_RX_STATUS&0X8000)                //接收到一次数据了
  9.         {
  10.                 UART_RX_BUFFER[UART_RX_STATUS&0X7FFF]=0;//添加结束符
  11.                 strx=strstr((const char*)UART_RX_BUFFER,(const char*)str);
  12.         }
  13.         return (u8*)strx;
  14. }
  15. //向ESP8266发送命令
  16. //cmd:发送的命令字符串
  17. //ack:期待的应答结果,如果为空,则表示不需要等待应答
  18. //waittime:等待时间(单位:10ms)
  19. //返回值:0,发送成功(得到了期待的应答结果)
  20. //       1,发送失败
  21. u8 ESP8266_SendCmd(u8 *cmd,u8 *ack,u16 wait_time)                         
  22. {  
  23.     u8 res = 0;
  24.         UART_RX_STATUS = 0;     
  25.     UART_SendString(cmd); //向WIFI模块发送控制指令   
  26.         Delay_us(5);  
  27.         UART0_SendByte('\r');                         //回车  
  28.         Delay_us(5);  
  29.         UART0_SendByte('\n');                   //换行
  30. /////////////////////////////////////////
  31.     if(ack&&wait_time)                //需要等待应答
  32.         {
  33.                 while(--wait_time)        //等待倒计时
  34.                 {
  35.                         Delay_ms(10);
  36.                         if(UART_RX_STATUS&0X8000)//接收到期待的应答结果
  37.                         {
  38.                                 if(ESP8266_CheckCmd(ack))
  39.                                 {
  40. //                                        printf("ack:%s\r\n",(u8*)ack);
  41.                                         break;//得到有效数据
  42.                                 }
  43.                 UART_RX_STATUS=0;
  44.                         }
  45.                 }
  46.                 if(wait_time==0) res=1;
  47.         }
  48.         return res;
  49. }
  50. //ESP8266退出透传模式
  51. //返回值:0,退出成功;
  52. //       1,退出失败
  53. u8 ESP8266_QuitTrans(void)
  54. {
  55.     UART_SendString('+');     
  56.         Delay_ms(15);                                        //大于串口组帧时间(10ms)
  57.         UART_SendString('+');      
  58.         Delay_ms(15);                                        //大于串口组帧时间(10ms)
  59.         UART_SendString('+');      
  60.         Delay_ms(500);                                        //等待500ms
  61.         return ESP8266_SendCmd("AT","OK",20);//退出透传判断.
  62. }
复制代码
接下来呢,就是配置网络等的操作啦,不多说先上程序吧:
  1. //ESP8266模块 STA 模式下作 TCP server 配置
  2. void ESP8266_STA_TCP_Server_Config(u16 x,u16 y,u8 wanip)
  3. {
  4.         u8 *p1,*p2;
  5.     u8 res=0;
  6.     u8 ipbuf[16];
  7.     p1=malloc(32);        //申请32字节内存
  8.     p2=malloc(8);
  9.         POINT_COLOR=BLUE;
  10.     con_state = 0;
  11.         res|=ESP8266_SendCmd("AT+CWMODE_DEF=1","OK",20);
  12.         res|=ESP8266_SendCmd("AT+RST","OK",20);
  13.         Delay_ms(1000);//延时2s等待模块重启
  14.         Delay_ms(1000);//
  15.         Delay_ms(1000);
  16.         Delay_ms(1000);
  17.         res|=ESP8266_SendCmd("AT+CWJAP=\"A+B\",\"12345678\"","WIFI GOT IP",1000);
  18.     res|=ESP8266_SendCmd("AT+CIPMUX=1","OK",20);   //0:单连接,1:多连接
  19.         //sprintf((char*)p,"AT+CIPSERVER=1,%s",(u8*)portnum);   
  20.         res|=ESP8266_SendCmd("AT+CIPSERVER=1,8080","OK",20); //开启Server模式,端口号为8080
  21.     //res|=ESP8266_SendCmd("AT","OK",20);
  22.     //ESP8266_SendCmd("AT+CIPSTART=0,\"TCP\",\"192.168.1.101\",5000","OK",1000);
  23.     res|=ESP8266_SendCmd("AT+CIPSTO=0","OK",20);    //永远不超时
  24.     ESP8266_Get_WanIP(ipbuf);
  25.     //sprintf((char*)p,"IP地址:%s 端口:%s",ipbuf,(u8*)portnum);
  26.     //ESP8266_SendCmd("AT+CIPMODE=1","OK",200);      //传输模式为:透传
  27.     if(res==0)//Server开启
  28.         {
  29.         LCD_ShowString(0,35,"IP:");
  30.         sprintf((char*)p1,"%s",ipbuf);
  31.         LCD_ShowString(0,50,p1);
  32.         free(p1);
  33.                 sprintf((char*)p2,"Port:%s","8080");
  34.         LCD_ShowString(0,65,p2);
  35.         free(p2);
  36.         LCD_ShowString(x,y,"TCPServer OK");
  37.         }
  38.     else
  39.     {
  40.         LCD_ShowString(0,35,"NetWork_ERR");
  41.     }
  42.     UART_RX_STATUS=0;   
  43. }
复制代码
我选择的是STA模式下作为TCP Server,STA成功之后,然后ESP8266开启Server模式,端口号我这边固定设置为8080,设置完成之后,路由器会给ESP8266分配一个IP地址,然后通过查询ESP8266的本地连接可以获得STAIP地址和STAMAC,获得的IP和端口通过LCD屏显示,如开篇首图,查询IP的函数如下:
  1. //获取Client ip地址
  2. //ipbuf:ip地址输出缓存区
  3. void ESP8266_Get_WanIP(u8* ipbuf)
  4. {
  5.         u8 *p,*p1;
  6.     if(ESP8266_SendCmd("AT+CIFSR","OK",50))//获取WAN IP地址失败
  7.     {
  8.         ipbuf[0]=0;
  9.         return;
  10.     }               
  11.     p=ESP8266_CheckCmd("\"");
  12.     p1=(u8*)strstr((const char*)(p+1),"\"");
  13.     *p1=0;
  14.     sprintf((char*)ipbuf,"%s",p+1);       
  15. }
复制代码
成功获取IP之后呢,可以通过这个TCP Server的IP和Port进行与Client的连接了。
接下来呢,快到末尾了,就是while(1)函数,里面会不断采集温度数据(也可以加入其他采集数据)并通过LCD屏显示刷新。TCP的连接接收发送已经放在UART中断函数里了,我这边是客户端通过发送字符“T”就能获取到相应的数据。
程序的结束,只是调试的开始,由于不能使用sprintf,不得不放弃了很多;调试的路上一路披荆斩棘,翻阅了很多规格书资料。调试呢,我这边边仿真边通过串口助手查看ESP8266的回传指令,我的一个调试过程可参考如下:
947375e8b47499dbff.png
最后呢,成功的实现了可以通过手机发送命令去获取信息啦。使用的是网络调试助手,手机配置为TCP Client,IP为192.168.1.108,端口为8080,成功连接后就可以通信啦,通信截图如下;
205425e8b48b6c62ad.png 907085e8b48be312d9.png
啊哦,Monday这个单词好像拼错了!忘记改了。
本次开发呢,由于第一次使用WIFI模块,操作上也存在很多不足,不过后面我会慢慢改进的;
还有想问广大网友有没有C51里数字快速转字符串的方法(不使用sprintf),有的话帮忙告知一下。
最后感谢赛元提供的开发核心板,真的很不错呢,主要是Flash容量大,不用担心Code的大小问题,还有一个就是外设资源很丰富,开发上手快。
本次更新到此结束,期待我们下次再见!
还请各位大神不吝赐教,我将虚心向各位学习!

夜已深,附件后面再上传吧!
生活不止眼前的苟且,还有我的代码和单片机!加油!



913685e8b2eea0b779.png

使用特权

评论回复
| 2020-4-7 15:04 | 显示全部楼层
感谢分享,奖励您50家园币,家园币可以兑换礼品或抽奖,欢迎体验~

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表