STM32的串口接收機制
??與阻塞式發送函數HAL_UART_Transmit配套,有個阻塞式的接收函數,HAL_UART_Receive,但此函數不常用,串口接收通常使用中斷函數HAL_UART_Receive_IT。HAL庫的串口中斷比較復雜,主要流程如下:
??USART1_IRQHandler:由硬件調用,不是HAL庫函數,寄存器編程或固件庫編程也需要調用此函數;
??HAL_UART_IRQHandler:通過中斷類型(發送中斷還是接收中斷)來判斷調用哪個函數;
??UART_Receive_IT:此函數可以指定,每收到若干個數據,調用一次回調函數;這是因為,每收到一個字節,都會把此函數的接收計數器-1,如果接收計數器為零,調用串口接收回調函數HAL_UART_RxCpltCallback(實際上HAL庫一共提供了5個回調函數,只有這個函數在接收完成時調用)。
??HAL_UART_RxCpltCallback:弱函數,用戶可以在此函數中編寫業務邏輯。清除中斷標記,是中斷處理函數一定要做的事情,但是對于用戶函數,把這個操作給隱藏了
使能串口接收中斷
??由于串口不方便傳參數,所以我通常會定義一些用于串口通信的全局變量。也可以模仿庫函數,把這些變量打包成一個結構體。
//UART.c
unsigned char UART1_Rx_Buf[MAX_REC_LENGTH] = {0}; //USART1存儲接收數據
unsigned char UART1_Rx_flg = 0; //USART1接收完成標志
unsigned int UART1_Rx_cnt = 0; //USART1接受數據計數器
unsigned char UART1_temp[REC_LENGTH] = {0}; //USART1接收數據緩存
??由于這些變量也要在main.c文件中使用,跨文件使用,可以在頭文件中做外部聲明:
#ifndef __UART_H
#define __UART_H
#ifdef __cplusplus
extern "C" {
#endif
#define REC_LENGTH 1
#define MAX_REC_LENGTH 1024
extern unsigned char UART1_Rx_Buf[MAX_REC_LENGTH];
extern unsigned char UART1_Rx_flg ;
extern unsigned int UART1_Rx_cnt ;
extern unsigned char UART1_temp[REC_LENGTH];
#ifdef __cplusplus
}
#endif
#endif
??要使用中斷來接收串口數據,則必須開啟中斷。并且,每次處理完串口接收中斷以后,會自動關閉中斷,如果想循環接收數據,則必須在處理完中斷以后,再次開啟中斷。
??我們希望完成初始化以后就開始接收串口數據,所以要修改串口初始化函數。
//main.c
static void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 2 */
HAL_UART_Receive_IT(&huart1,(uint8_t *)UART1_temp,REC_LENGTH);
/* USER CODE END USART1_Init 2 */
}
串口接收中斷函數處理
??程序的邏輯:
??如果接收到了指定數量的串口數據(在本例中,指定的數量是1字節),則會執行回調函數HAL_UART_RxCpltCallback。此函數是個弱函數,用戶可以根據業務邏輯來“重載”。我們要在此函數中,把串口收到的數據打包,并判斷結束符判斷數據結束。我們規定,只發送ASCII碼,并以0x0a作為結束符。
//UART.c
/**
* @brief 串口中斷回調函數
* @param 調用回調函數的串口
* @note 串口每次收到數據以后都會關閉中斷,如需重復使用,必須再次開啟
* @retval None
*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance==USART1)
{
UART1_Rx_Buf[UART1_Rx_cnt] = UART1_temp[0];
UART1_Rx_cnt++;
if(0x0a == UART1_temp[0])
{
UART1_Rx_flg = 1;
}
HAL_UART_Receive_IT(&huart1,(uint8_t *)UART1_temp,REC_LENGTH);
}
}
??主函數中,實現“串口應聲蟲”的功能,收到什么就發送什么。如果串口數據接收完成,則發送出去然后把數組,計數器,標志都恢復初始狀態。
//main() while(1)
if(UART1_Rx_flg)
{
HAL_UART_Transmit(&huart1,UART1_Rx_Buf,UART1_Rx_cnt,0x10); //發送接收到的數據
for(int i = 0;i UART1_Rx_cnt = 0; UART1_Rx_flg = 0; } ??現象:向串口發送ASCII碼,單片機收到什么數據,就返回什么數據。注意,發送給串口的數據結尾要有回車鍵。 數據階段的方法與ASCII碼 ??一組數據怎么判斷是否結束? ??2種方法: ??1特定時間,特定的時間內沒有收到新的數據,認為這一組數據就結束了。這種方法在定時器的章節來實現。 ??2特定字符,通信雙方約定,用特定的字符作為結束,比如把0xff作為結束符。收到0xff就把數據截斷。就像我們演講,最后說一句謝謝大家,下邊的人就知道了你講完了,該鼓掌了。謝謝就是結束符。 ??但是這種做法有一個弊端,就是正常通信的數據不允許在使用0xff。 ??對于ASCII碼,正常情況下是不會發送0x0d與0x0a(回車與換行)的,所以可以用作結束符。 ??ASCII(American Standard Code for Information Interchange,美國信息交換標準代碼)是基于拉丁字母的一套電腦編碼系統,主要用于顯示現代英語和其他西歐語言。它是現今最通用的系統,并等同于國際標準ISO/IEC 646。 ??ASCII碼主要用于英文字符的顯示,不包含中文。標準ASCII碼只有7位(最高位是校驗位),所以只能顯示2^7=128個字符,其中0-31還是不能顯示的字符,例如回車,作用是控制字符或通信字符。 ??假如,發送的數據是0x31,它可能代表著十六進制的數字0x31,也可能表示十進制的數字49(十六進制與十進制雖然看上去不一樣,但表示的數是同樣的大小),還可能表示ASCII碼,字符’1’。這三者,在傳輸線上使用示波器來觀察,波形是一模一樣的,接收方把它理解為0x31還是理解為字符,要看通信雙方的約定。
上一篇:HAL庫教程7:STM32的時鐘系統
下一篇:HAL庫教程5:串口數據發送
推薦閱讀
史海拾趣
為了進一步擴大業務范圍和提升技術實力,Keil公司決定與美國德克薩斯州理查森的Keil Software Inc進行聯合運營。這一舉措不僅使公司得以接觸更廣闊的市場,還促進了雙方在技術、產品和市場等方面的深度融合。聯合運營后,Keil公司的發展速度明顯加快,逐漸在嵌入式系統開發工具市場上占據了重要地位。
近年來,隨著環保意識的提高,電子行業對綠色發展的需求也日益迫切。BSI積極響應這一需求,推動了電子行業綠色標準的制定和實施。通過制定嚴格的環保標準,BSI引導電子產品制造企業采用更加環保的生產工藝和材料,減少了對環境的污染。同時,BSI還為企業提供了碳排放核查等服務,幫助企業了解自身的碳排放情況,制定了減排措施,推動了電子行業的綠色發展。
在電子行業中,產品質量是企業生存和發展的關鍵。Armel Electronics Inc公司深知此道,始終堅持品質至上的原則。公司從原材料采購到生產流程,再到產品出廠,每一個環節都嚴格把控,確保產品質量的穩定性和可靠性。這種對品質的執著追求,使得Armel的產品在市場上贏得了良好的口碑,并逐漸樹立了公司的品牌形象。
隨著汽車工業的快速發展,對熔斷器的需求也急劇增加。Bussmann五兄弟敏銳地抓住了這一市場機遇,開始專注于汽車熔斷器的研發和生產。他們深入研究汽車電路的特點,不斷優化熔斷器的設計和性能,使其能夠更好地適應汽車的工作環境。憑借這一創新,Bussmann的汽車熔斷器迅速占領了市場,為公司的發展奠定了堅實的基礎。
隨著電子行業的快速發展,艾邁斯(AMASS)公司意識到只有不斷創新才能保持領先地位。為此,公司加大了對研發的投入,引進了一批高素質的研發人才,并建立了完善的研發體系。經過多年的努力,艾邁斯成功研發出了多款具有創新性的連接器產品,其中包括高性能、高安全性的智能設備動力連接器。這些產品的推出不僅提升了公司的技術實力和市場競爭力,也為整個行業的發展帶來了積極的影響。
除了數據通訊和電信市場外,CyOptics的光學產品還逐漸拓展至其他領域。例如,公司的光學組件已集成至光學收發器、轉發器及線卡等設備中,為數據中心、高性能計算和企業存儲網絡等應用提供了強有力的支持。此外,CyOptics還積極開拓新興市場,如數據庫、地鐵及長途干線市場等,為客戶提供定制化的光學解決方案。
virtual BOOL ExtTextOut ( int x, int y, UINT nOptions, LPCRECT lpRect, LPCTSTR lpszString, UINT nCount, LPINT lpDxWidths ); 想請教一下參數nOptions是否有效?本人通過測試,覺得ETO-CLIPPED、ETO-OPAQUE、NULL三者之間沒有 ...… 查看全部問答∨ |
|
VC++關于directshow圖像旋轉90度輸出花屏的問題 VC++關于directshow圖像旋轉90度輸出花屏的問題 我在transfilter對圖像做了一個90度的旋轉,再傳給第三個filter,發現圖像是花屏,解析度為176x144 如果解析度為高,寬相等就是正常的(如:240x240) 請問是什么原因?… 查看全部問答∨ |
|
急救 !!!!!!!!!!!!萬里求救!傳感器 單片機LED顯示設計電路圖 通過485 通信到485接口接收數據然后用(單片機)LED顯示 氣體濃度在0-0.5%是綠燈亮 0.5%-1%黃燈亮 蜂鳴器響且響的頻率慢 >=1%紅燈亮 蜂鳴器響且響的頻率快 用AT89c2051做 ...… 查看全部問答∨ |
|
一般情況下,電阻網絡的測試通常采用下列三類測量方法中的一類: 標準四線開氏測量 六線防護式歐姆或德爾塔電阻測量 “Y”型或埋入式節點電阻測量(也稱為分離開 ...… 查看全部問答∨ |
為什么我在C2000培訓中考了很多次試,查看答卷和查看成績里邊都是空的,而且只有首... 為什么我在C2000培訓中考了很多次試,查看答卷和查看成績里邊都是空的,而且只有首次考試成績… 查看全部問答∨ |