一、串口的基本概念
- 【數(shù)據(jù)組成】串口的通訊協(xié)議由開始位,數(shù)據(jù)位,校驗位,結(jié)束位構成。
- 【數(shù)據(jù)結(jié)構】一般以一個低電平作為一幀數(shù)據(jù)的起始,接著跟隨 8 位或者 9 位數(shù)據(jù)位,之后為校驗位,分為奇校驗,偶校驗和無校驗,最后以一個先高后低的脈沖表示結(jié)束位,長度可以設置為 0.5,1,1.5 或 2 位長度。
- 【奇偶校驗原理】統(tǒng)計發(fā)送數(shù)據(jù)中高電平即’1’的奇偶,將結(jié)果記錄在奇偶校驗位中發(fā)送給接收方,接收方收到奇偶校驗位后和自己收到的數(shù)據(jù)進行對比,如果奇偶性一致就接受這幀數(shù)據(jù),否則認為這幀數(shù)據(jù)出錯。
如下圖所示:一個 8 位數(shù)據(jù)位,1 位奇偶校驗位,1 位結(jié)束位的串口數(shù)據(jù)幀。
上圖的解釋如下:
注意事項:
- 一般進行串口通訊時,收發(fā)雙方要保證遵守同樣的協(xié)議才能正確的完成收發(fā),除了協(xié)議要一致之外,還有一個非常重要的要素要保持一致,那就是通訊的速率,即波特率。
- 波特率是指發(fā)送數(shù)據(jù)的速率,單位為波特每秒,一般串口常用的波特率有 115200,38400,9600 等。
- 串口的波特率和總線時鐘周期(clock)成倒數(shù)關系,即總線時鐘周期越短,單位時間內(nèi)發(fā)送的碼元數(shù)量越多,串口波特率就越高。
二、使用 STM32 標準庫 實現(xiàn)任意長度數(shù)據(jù)的收發(fā)
示例程序功能說明:首先,通過串口一實現(xiàn)對任意長度數(shù)據(jù)的接收,接收到數(shù)據(jù)之后,將其存放到一個數(shù)組當中,方便后續(xù)調(diào)用;其次將STM32接收到的數(shù)據(jù)通過串口一發(fā)送出去。核心程序如下:(完整版程序詳見文末鏈接)
// 串口發(fā)送部分核心代碼如下:
int main(void)
{
delay_init(); //延時函數(shù)初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置NVIC中斷分組2:2位搶占優(yōu)先級,2位響應優(yōu)先級
uart_init(115200); //串口初始化為115200
// USART_SendData(USART1, 0x11);
// while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
while(1)
{
if(receive_flag == 1) //串口接收完成標志位
{
for(int i=0;i<8;i++)
{
USART_SendData(USART1, Receive_Data[i]);//向串口1發(fā)送數(shù)據(jù)
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待發(fā)送結(jié)束
}
receive_flag = 0; //一幀數(shù)據(jù)發(fā)送完畢之后,標志位置0
}
}
}
// 串口接收部分核心代碼如下:
void USART1_IRQHandler(void)
{
static u8 Count=0; //定義計數(shù)靜態(tài)變量
u8 Usart_Receive; //定義中間傳遞變量
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //判斷是否接收到數(shù)據(jù)
{
Usart_Receive = USART_ReceiveData(USART1); //讀取數(shù)據(jù)
if(receive_flag == 0)
{
//串口數(shù)據(jù)填入數(shù)組
Receive_Data[Count]=Usart_Receive;
//確保數(shù)組第一個數(shù)據(jù)為FRAME_HEADER(幀頭)
if(Usart_Receive == FRAME_HEADER||Count>0)
Count++;
else
Count=0;
if (Count == 8) //驗證數(shù)據(jù)包的長度
{
Count=0; //為串口數(shù)據(jù)重新填入數(shù)組做準備
if(Receive_Data[7] == FRAME_TAIL) //驗證數(shù)據(jù)包的幀尾
{
//接收到完整的一幀數(shù)據(jù)之后,在這里面進行處理
receive_flag = 1;
}
}
}
}
}
程序關鍵:
- 通過微小調(diào)整,可以實現(xiàn)任意長度數(shù)據(jù)的收發(fā),方便使用;
- 串口接收魯棒性高,采用校驗幀頭、幀尾以及數(shù)據(jù)長度的方式,確保接收數(shù)據(jù)的穩(wěn)定性。
STM32 標準庫 串口收發(fā)實驗展示(實驗中,幀頭設置為0x01,幀尾設置為0x02,數(shù)據(jù)長度為8個字節(jié))
【實驗結(jié)論】如上圖所示,發(fā)送端的數(shù)據(jù),接收端會完好收到。下面進行干擾性測試:
【實驗結(jié)論】如上圖所示,在引入幀頭、幀尾以及長度校驗后,程序的抗干擾能力較強。
三、使用 STM32 HAL庫 實現(xiàn)任意長度數(shù)據(jù)的收發(fā)
HAL庫程序使用CUBE MX生成
// 串口發(fā)送部分核心代碼如下:
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
//__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
HAL_UART_Receive_IT(&huart1,(uint8_t *)Usart_Receive,1); //這句話極為重要
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(receive_flag == 1)
{
HAL_UART_Transmit(&huart1,Receive_Data,8,100);
receive_flag = 0;
}
}
/* USER CODE END 3 */
}
// 串口接收部分核心代碼如下:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
static uint8_t Count=0; //定義計數(shù)靜態(tài)變量
if(huart->Instance==USART1)
{
HAL_UART_Receive_IT(&huart1,(uint8_t *)Usart_Receive,1);
if(receive_flag == 0)
{
//串口數(shù)據(jù)填入數(shù)組
Receive_Data[Count]=Usart_Receive[0];
//確保數(shù)組第一個數(shù)據(jù)為FRAME_HEADER(幀頭)
if(Usart_Receive[0] == FRAME_HEADER||Count>0)
Count++;
else
Count=0;
if (Count == 8) //驗證數(shù)據(jù)包的長度
{
Count=0; //為串口數(shù)據(jù)重新填入數(shù)組做準備
if(Receive_Data[7] == FRAME_TAIL) //驗證數(shù)據(jù)包的幀尾
{
//接收到完整的一幀數(shù)據(jù)之后,在這里面進行處理
receive_flag = 1;
}
}
}
}
}
STM32 HAL庫 串口收發(fā)實驗展示(實驗中,幀頭設置為0x01,幀尾設置為0x02,數(shù)據(jù)長度為8個字節(jié))
四、相關程序及總結(jié)
1.上述代碼已開源,開源鏈接:
https://e.coding.net/ehangtest01/stm32_explore/STM32_Explore.git文章來源:http://www.zghlxwxcb.cn/news/detail-621339.html
文件夾內(nèi)容如下:
2.不管是使用標準庫還是HAL庫,都需要對數(shù)據(jù)進行校驗,這樣才能保證數(shù)據(jù)傳輸?shù)姆€(wěn)定性。文章來源地址http://www.zghlxwxcb.cn/news/detail-621339.html
到了這里,關于【STM32通訊系列--串口通訊】使用標準庫、HAL庫實現(xiàn)任意長度數(shù)據(jù)的收發(fā)(包含幀頭、幀尾校驗,配套完整開源程序)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!