title: STM32外設驅動總結(公司項目需要)
tags: STM32
date: 2019-5-15 22:53:00
今天已經是2019年的5月中旬了,馬上要畢業論文檢查了,但是我一個字還沒有寫。本來計劃今天寫的,無奈無從下手呀,突然想到今天的工作記錄還沒有寫,果斷放棄了畢業論文,寫論文是不可能寫的,,,,(0*0)
今天來總結下我一天內完成的工作成果。
- STM32-SPI 外置內存的調試(W25Q128)參考的正點原子例程
- STM32-I2C 外置內存的調試(AT24C128)
- STM32關鍵參數的超級串口終端(可以進行關鍵參數的快速配置)-阿正原創
W25Q128遇到的問題:無法讀取FlashID
首先,剛開始調試SPI的時候就遇到了致命的問題,我調試了接近一晚上,但是連Flash的ID都讀不出來,一度讓我很煩躁,一行代碼一行代碼的調試,也沒有發現異常,畢竟Flash的ID讀取也就是幾個函數而已,底層的SPI其實是不需要配置的,爲了解決這個問題,我嘗試了很多辦法,代碼幾乎肯定是沒問題的,我把W25Q128換成了W25Q16,依舊無法讀取出來ID,此時我又把主機上的Flash換到了一塊能正常運行的F4單片機上,此時是可以讀出ID的,所以排除了硬件問題,但是代碼是否有問題依舊無法確認,一直到下午,把辦公室的老大哥,發現了原理圖上面的引腳MOSI與MISO的引腳畫反了!!!最終我把引腳飛線交叉以後,問題解決了,哎呀,下午的時候和我的恩同事一起去吃了土豆粉。
STM32-I2C 外置內存的調試(AT24C128)
調試代碼總是不順利的,這款IC也出現了問題,初始化無法校驗成功,後來發現是我的紅底昂一有問題,再加上論壇生的一些資料,幫助我解決了問題,成功實現flash讀寫。
STM32超級串口的設計
首先我手頭的主板爲STM32F103R8t6
三個串口已經全部使用了,
串口1用來做調試
串口2用來與NB模組通訊
串口3用來與485設備通訊
最後我次用了串口1作爲超級串口終端。
超級串口的用途:
- 批量配置設備主要參數,例如:NB模組IP地址、MQTT服務器域名、設備ID、問詢設備狀態等。
- 通過串口助手快速批量設置設備
- 通過PC端軟件快速便捷設置(QT上位機開發)
超級串口的實現方法:
- 串口中斷的使用,包括接收中斷與空閒中斷(用來接收長幀數據)
- 自定義字符處理函數(參考網上教程)
- 原創類似AT指令的串口配置命令:
指令配置表:
指令 | 功能 |
---|---|
CITC+IP[192.168.1.120] | 更改服務器IP地址 |
CITC+PORT[1883] | 更改服務器端口號 |
CITC+ID[TEST_NB] | 更改設備ID |
CITC+USER[admin] | 更改MQTT用戶名 |
CITC+PASSWORD[public] | 更改MQTT密碼 |
CITC+TOPIC[/device/NB/102365] | 更改發佈消息Topic |
地址對應表:
地址 | 功能 | 長度 |
---|---|---|
0-50 | 存儲開機打印信息與程序版本號等 | 50 |
50-70 | IP地址 | 20 |
70-80 | PORT端口 | 10 |
80-100 | ID設備ID | 20 |
100-120 | USER用戶名 | 20 |
120-140 | PASSWORD密碼 | 20 |
150-200 | TOPIC消息主題 | 50 |
代碼簡單記錄:
截取字符函數:
/***********************************************************
函數名稱:Find_string(char *pcBuf,char*left,char*right, char *pcRes)
函數功能:尋找特定字符串
入口參數:
char *pcBuf 爲傳入的字符串
char*left 爲搜索字符的左邊標識符 例如:"["
char*right 爲搜索字符的右邊標識符 例如:"]"
char *pcRes 爲輸出轉存的字符串數組
返回值:用來校驗是否成功,無所謂的。
備註:
服務器下發命令舉例:+MQTTPUBLISH: 0,0,0,0,/device/NB/zx99999999999999_back,6,[reastrobot]
***********************************************************/
int Find_string(char *pcBuf,char*left,char*right, char *pcRes)
{
char *pcBegin = NULL;
char *pcEnd = NULL;
pcBegin = strstr(pcBuf, left);
pcEnd = strstr(pcBuf, right);
if(pcBegin == NULL || pcEnd == NULL || pcBegin > pcEnd)
{
printf("Mail name not found!\n");
}
else
{
pcBegin += strlen(left);
memcpy(pcRes, pcBegin, pcEnd-pcBegin);
}
return 0;
}
超級串口終端代碼:
串口中斷部分:
/***********************************************************
函數名稱:USART1_IRQHandler(void)
函數功能:串口2中斷服務程序
入口參數:無
返回值:無
備註:
實現了數據接收中斷緩存,以及空閒中斷處理,實現長字符數據的接收
同時檢測是否有下發命令的數據回傳。
***********************************************************/
void USART1_IRQHandler(void) //串口2中斷服務程序
{
uint8_t ch;
uint8_t Clear = Clear;
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit(USART1, USART_IT_RXNE); //接收中斷
ch = USART_ReceiveData(USART1);
struct_usart.USART1_BUFF[struct_usart.USART1_Length++] = ch;
}
if ( USART_GetITStatus( USART1, USART_IT_IDLE ) == SET ) //空閒總線中斷
{
USART_ClearITPendingBit(USART1, USART_IT_IDLE);
ch = USART_ReceiveData(USART1);
if (struct_usart.USART1_Length != 0) //返回值不爲空
{
printf("\r\nBACK_CITC\r\n{%s}\r\n",struct_usart.USART1_BUFF);
if (strstr((char*)struct_usart.USART1_BUFF, "CITC")) //是否包含回傳數據
{
printf("\r\nBACK_CITC_OK!\r\n[%s]\r\n",struct_usart.USART1_BUFF);
scan_CITC();
memset(&struct_usart.USART1_BUFF,0,sizeof(struct_usart.USART1_BUFF));//清空結構體數組(此處不能清空,因爲有可能數據正在處理的時候,服務器下發了數據)
struct_usart.USART1_Length = 0;
}
else {
printf("\r\nBACK_CITC_ERROR!\r\n");
memset(&struct_usart.USART1_BUFF,0,sizeof(struct_usart.USART1_BUFF));//清空結構體數組
struct_usart.USART1_Length = 0;
}
}
}
}
接收數據處理部分:
void scan_CITC(void){
memset(&CITC_MSG,0,sizeof(CITC_MSG));
memset(&CITC_msg,0,sizeof(CITC_msg));
if (strstr((char*)struct_usart.USART1_BUFF, "CITC+IP")) //是否包含回傳數據
{
Find_string((char*)struct_usart.USART1_BUFF,"[","]",CITC_msg);
sprintf(CITC_MSG,"%s%s%s","[",CITC_msg,"]"); //再次組裝數據便於不定長數據的截取
AT24CXX_Write(50,(u8*)CITC_MSG,strlen(CITC_MSG));
}else if(strstr((char*)struct_usart.USART1_BUFF, "CITC+PORT"))
{
Find_string((char*)struct_usart.USART1_BUFF,"[","]",CITC_msg);
sprintf(CITC_MSG,"%s%s%s","[",CITC_msg,"]"); //再次組裝數據便於不定長數據的截取
AT24CXX_Write(70,(u8*)CITC_MSG,strlen(CITC_MSG));
}else if(strstr((char*)struct_usart.USART1_BUFF, "CITC+ID"))
{
Find_string((char*)struct_usart.USART1_BUFF,"[","]",CITC_msg);
sprintf(CITC_MSG,"%s%s%s","[",CITC_msg,"]"); //再次組裝數據便於不定長數據的截取
AT24CXX_Write(80,(u8*)CITC_MSG,strlen(CITC_MSG));
}else if(strstr((char*)struct_usart.USART1_BUFF, "CITC+USER"))
{
Find_string((char*)struct_usart.USART1_BUFF,"[","]",CITC_msg);
sprintf(CITC_MSG,"%s%s%s","[",CITC_msg,"]"); //再次組裝數據便於不定長數據的截取
AT24CXX_Write(100,(u8*)CITC_MSG,strlen(CITC_MSG));
}else if(strstr((char*)struct_usart.USART1_BUFF, "CITC+PASSWORD"))
{
Find_string((char*)struct_usart.USART1_BUFF,"[","]",CITC_msg);
sprintf(CITC_MSG,"%s%s%s","[",CITC_msg,"]"); //再次組裝數據便於不定長數據的截取
AT24CXX_Write(120,(u8*)CITC_MSG,strlen(CITC_MSG));
}else if(strstr((char*)struct_usart.USART1_BUFF, "CITC+TOPIC"))
{
Find_string((char*)struct_usart.USART1_BUFF,"[","]",CITC_msg);
sprintf(CITC_MSG,"%s%s%s","[",CITC_msg,"]"); //再次組裝數據便於不定長數據的截取
AT24CXX_Write(150,(u8*)CITC_MSG,strlen(CITC_MSG));
}
}
主機開機初始化部分(從內存中讀取信息)
/***********************************************************
函數名稱:CITC_Init()
函數功能:內存初始化
入口參數:無
返回值:
***********************************************************/
void CITC_Init(void)
{
AT24CXX_Read(50,datatemp,20);
Find_string((char*)datatemp,"[","]",Find_msg);
sprintf(IP,"%s",Find_msg);
printf("IP: %s\r\n",Find_msg);
memset(&Find_msg,0,sizeof(Find_msg));
AT24CXX_Read(70,datatemp,10);
Find_string((char*)datatemp,"[","]",Find_msg);
sprintf(Port,"%s",Find_msg);
printf("PORT: %s\r\n",Find_msg);
memset(&Find_msg,0,sizeof(Find_msg));
AT24CXX_Read(80,datatemp,20);
Find_string((char*)datatemp,"[","]",Find_msg);
sprintf(ID,"%s",Find_msg);
printf("ID: %s\r\n",Find_msg);
memset(&Find_msg,0,sizeof(Find_msg));
AT24CXX_Read(100,datatemp,20);
Find_string((char*)datatemp,"[","]",Find_msg);
sprintf(User,"%s",Find_msg);
printf("USER: %s\r\n",Find_msg);
memset(&Find_msg,0,sizeof(Find_msg));
AT24CXX_Read(120,datatemp,20);
Find_string((char*)datatemp,"[","]",Find_msg);
sprintf(Pwd,"%s",Find_msg);
printf("PWD: %s\r\n",Find_msg);
memset(&Find_msg,0,sizeof(Find_msg));
AT24CXX_Read(150,datatemp,50);
Find_string((char*)datatemp,"[","]",Find_msg);
sprintf(TOPIC,"%s",Find_msg);
printf("TOPIC: %s\r\n",Find_msg);
memset(&Find_msg,0,sizeof(Find_msg));
}
晚安世界,希望以後自己更加努力,好好學習,努力工作。
學到更多的東西、學到更多的知識。