STM32外設驅動總結(公司項目需要)


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作爲超級串口終端。

超級串口的用途:

  1. 批量配置設備主要參數,例如:NB模組IP地址、MQTT服務器域名、設備ID、問詢設備狀態等。
  2. 通過串口助手快速批量設置設備
  3. 通過PC端軟件快速便捷設置(QT上位機開發)

超級串口的實現方法:

  1. 串口中斷的使用,包括接收中斷與空閒中斷(用來接收長幀數據)
  2. 自定義字符處理函數(參考網上教程)
  3. 原創類似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));
	
}

晚安世界,希望以後自己更加努力,好好學習,努力工作。
學到更多的東西、學到更多的知識。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章