日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STM32F4+Wi-Fi+EDP 向 OneNet 上传数据

發布時間:2023/12/18 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32F4+Wi-Fi+EDP 向 OneNet 上传数据 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

源地址:https://www.arduino.cn/thread-19000-1-1.html

? ? 利用STM32F4+WIFI+EDP向OneNet平臺上傳數據,雖然非常簡單,但是在個人調試過程中的仍有一些細節需要注意,下面將調試過程總結如下,希望能和大家一起交流,共同進步。 實驗過程主要分為以下四個步驟:

1.調試STM32F4的串口發送功能。
2.利用STM32F4串口向WIFI模塊發送平臺連接的TCP連接指令。
3.利用STM32F4串口向WIFI模塊發送EDP設備連接請求報文。
4.利用STM32F4串口向WIFI模塊發送EDP數據報文。
步驟1:串口發送功能的調試,STM32F4有一套編寫好的庫函數,我們只需要簡單調用其中的某些函數,即可以實現STM32F4的串口發送功能。 串口初始化函數代碼如下:

[C++] 純文本查看 復制代碼

?

代碼

001

002

003

004

005

006

007

008

009

010

011

012

013

014

015

016

017

018

019

020

021

022

023

024

025

026

027

028

029

030

031

032

033

034

035

036

037

void usart1_init(u32 bound)

{

????//GPIO端口初始化

????GPIO_InitTypeDef GPIO_InitStructure;

????USART_InitTypeDef USART_InitStructure;

????NVIC_InitTypeDef NVIC_InitStructure;

????RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA時鐘

????RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1時鐘

????//串口1對應引腳復用映射

????GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);

????GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);

????//USART1端口配置

????GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;

????GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

????GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;???

????GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

????GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

????GPIO_Init(GPIOA,&GPIO_InitStructure);

????//USART1串口初始化配置

????USART_InitStructure.USART_BaudRate = bound;

????USART_InitStructure.USART_WordLength = USART_WordLength_8b;

????USART_InitStructure.USART_StopBits = USART_StopBits_1;

????USART_InitStructure.USART_Parity = USART_Parity_No;

????USART_InitStructure.USART_HardwareFlowControl =???????????????????? USART_HardwareFlowControl_None;

????USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;???

????USART_Init(USART1, &USART_InitStructure);

?

????USART_Cmd(USART1, ENABLE); //使能串口1

????//開啟串口接收中斷

????USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

????//USART1 NVIC配置

????NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

????NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;

????NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;???

????NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;???

????NVIC_Init(&NVIC_InitStructure);???

}


串口發送函數代碼如下:
?

[C++] 純文本查看 復制代碼

?

代碼

001

002

003

004

005

006

007

008

009

010

011

void usart1_write(USART_TypeDef* USARTx, uint8_t *Data,uint8_t len)

{

????uint8_t? i;

????USART_ClearFlag(USART1,USART_FLAG_TC);

????//USART_GetFlagStatus(USART1, USART_FLAG_TC);

????for(i=0; i<len; i++)

????{????????????????????????????????????????

????????USART_SendData(USARTx, *Data++);

????????while( USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET );

????}

}


這里主要是注意USART_ClearFlag(USART1,USART_FLAG_TC);調試過程中發現發送功能函數發送的字符串缺少第一個字符,剛開始以為是串口波特率定義為115200過快,造成第一個字節沒法顯示,查看查閱stm32f10x參考手冊,找到問題原因: TC:發送完成 當包含有數據的一幀發送完成后,由硬件將該位置位。如果USART_CR1中的TCIE為1,則產生中斷。由軟件序列清除該位(先讀USART_SR,然后寫入USART_DR)。TC位也可以通過寫入0來清除,只有在多緩存通訊中才推薦這種清除程序。 0:發送還未完成;1:發送完成。而軟件清除該位(先讀USART_SR,然后寫入USART_DR)。也就是說,要先read USART_SR,然后write USART_DR,才能完成TC狀態位的清除。而在硬件復位后,串口發送的首個數據之前沒有read SR的操作,是直接write DR,也就是說,TC沒有被清除掉。那么在發送字符串之前加上一句清除發送位TC標記或者讀取USART_SR值的代碼都可以解決問題。
?

[C++] 純文本查看 復制代碼

?

代碼

001

002

USART_GetFlagStatus(USART1, USART_FLAG_TC); //得到串口狀態標記函數

USART_SR USART_ClearFlag(USART2,USART_FLAG_TC); //清除TC位



步驟2:通過串口指令配置WIFI模塊,和OneNet平臺建立TCP連接。參考WIFI模塊命令手冊,依次發送如下幾個命令到WIFI模塊:

AT
AT+CWMODE=3
AT+RST
AT+CIFSR
AT+CWJAP="your ssid","password"
AT+CIPSTART="TCP","183.230.40.33",80??//和服務器建立TCP連接
AT+CIPMODE=1? ? //進入透明傳輸模式
AT+CIPSEND??//開始傳輸
對應程序代碼如下:(對應的四個XXXX字符串換成你自己的設備ID,設備ID關聯的APIKEY以及你的WIFI網絡名和連接密碼)
?

[C++] 純文本查看 復制代碼

?

代碼

001

002

003

004

005

006

007

008

009

010

011

012

013

014

015

016

017

018

019

020

021

022

023

024

025

026

027

#define? CMD_AT????????? "AT\r\n"

#define? CMD_CWMODE??? "AT+CWMODE=3\r\n"

#define? CMD_RST???????? "AT+RST\r\n"

#define? CMD_CIFSR??????? "AT+CIFSR\r\n"

#define? CMD_CWJAP?????? "AT+CWJAP=\" XXXX \",\" XXXX \"\r\n"

#define? CMD_CIPSTART???? "AT+CIPSTART=\"TCP\",\"183.230.40.39\",876\r\n"

#define? CMD_CIPMODE???? "AT+CIPMODE=1\r\n"

#define? CMD_CIPSEND????? "AT+CIPSEND\r\n"

void create_tcp_link(void)

{

????usart1_write(USART1, CMD_AT,strlen(CMD_AT));

????delay();

????usart1_write(USART1, CMD_CWMODE,strlen(CMD_CWMODE));

????delay();

????usart1_write(USART1, CMD_RST,strlen(CMD_RST));

????delay();

????usart1_write(USART1, CMD_CIFSR,strlen(CMD_CIFSR));

????delay();

????usart1_write(USART1, CMD_CWJAP,strlen(CMD_CWJAP));

????delay();

????usart1_write(USART1, CMD_CIPSTART,strlen(CMD_CIPSTART));

????delay();

????usart1_write(USART1, CMD_CIPMODE,strlen(CMD_CIPMODE));

????delay();

????usart1_write(USART1, CMD_CIPSEND,strlen(CMD_CIPSEND));

????delay();

}


這里有兩個問題,指令發送出去之后WIFI模塊是否得到正確的響應我們并不知道,另外發送指令后的delay函數,到底延時多久,如果延時太短,指令發送太快,WIFI模塊可能無法接收到我們發送的指令,我們需要對代碼進一步優化.
?

[C++] 純文本查看 復制代碼

?

代碼

001

002

003

004

005

006

007

008

009

010

011

012

013

014

015

016

017

018

019

020

021

022

023

024

025

026

027

028

029

030

031

032

033

034

035

036

037

038

039

void? wait_cmd_echo(char * cmd_buf)

{

????usart1_write(USART1,cmd_buf,strlen(cmd_buf)); //發送WIFI指令

????while(1)

????{

????????if(usart1_rcv_flag==1) //接收WIFI模塊回復信息完成

????????{

????????????if(strstr(usart1_rcv_buf,"OK")!=NULL) //如果WIFI模塊回復成功信息

????????????{

????????????????memset(usart1_rcv_buf,0,usart1_rcv_len);

????????????????usart1_rcv_len=0;

????????????????usart1_rcv_flag=0;

????????????????break; //跳出循環進行下一條指令發送

????????????}

????????????else if(strstr(usart1_rcv_buf,"ERROR")!=NULL) //如果WIFI模塊回復失敗信息

????????????{

????????????????memset(usart1_rcv_buf,0,usart1_rcv_len);

????????????????usart1_rcv_len=0;

????????????????usart1_rcv_flag=0;

????????????????usart1_write(USART1,cmd_buf,strlen(cmd_buf)); //重發指令

????????????}

????????}

????????If(wait_cmd_timeout==1)//等待WIFI模塊回復超時

????????{

????????????usart1_write(USART1,cmd_buf,strlen(cmd_buf)); //重發指令

????????}

????}

}

void create_tcp_link(void)

{

wait_cmd_echo(CMD_AT);

wait_cmd_echo(CMD_CWMODE);

wait_cmd_echo(CMD_RST);

wait_cmd_echo(CMD_CIFSR);

wait_cmd_echo(CMD_CWJAP);

wait_cmd_echo(CMD_CIPSTART);

wait_cmd_echo(CMD_CIPMODE);

usart1_write(USART1, CMD_CIPSEND,strlen(CMD_CIPSEND));

}


步驟3:通過串口向WIFI模塊發送設備連接請求報文,這里我們利用平臺提供的SDK。
?

[C++] 純文本查看 復制代碼

?

代碼

001

002

003

004

005

006

#define? DEVICEID "634631"

#define? APIKEY?? "BlkPaCqLFHrGVfFRacsXVEwVv80="

EdpPacket* send_pkg;

send_pkg = PacketConnect1(DEVICEID, APIKEY);? //設備連接請求包生成函數

usart1_write(USART1,send_pkg->_data,send_pkg->_write_pos); //發送設備連接請求報文???

DeleteBuffer(&send_pkg);//釋放內存


一定要記得DeleteBuffer(&send_pkg);不然程序運行一段時間后,可能由于內存耗盡而崩潰。

步驟4:通過串口向WIFI模塊發送設備連接請求報文
?

[C++] 純文本查看 復制代碼

?

代碼

001

002

003

004

005

006

007

008

009

010

011

012

013

char text[25] = {0};

char send_buf[512];

//生成數據報文的JSON格式

strcat(send_buf, "{\"datastreams\": [{");

strcat(send_buf, "\"id\": \"systime\",");

strcat(send_buf, "\"datapoints\": [");

strcat(send_buf, "{");

sprintf(text,"\"value\":\"%d\"",40);

strcat(send_buf, text);

strcat(send_buf, "}]}]}");???

send_pkg = PacketSaveJson(DEVICEID, send_buf); //生成EDP數據報文

usart1_write(USART1,send_pkg->_data,send_pkg->_write_pos); //發送EDP數據報文???????

DeleteBuffer(&send_pkg); //釋放內存


同樣,要注意DeleteBuffer(&send_pkg);釋放內存。

?

總結

以上是生活随笔為你收集整理的STM32F4+Wi-Fi+EDP 向 OneNet 上传数据的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。