關于串口的讀取是有固定套路的,所以這里單獨拉出來講一下,后面用到串口時候,直接復制粘貼就可以了,
本文從cubmax配置到代碼的撰寫

點開串口8(其他串口一樣)
點開asynchronous
點開中斷,這個必須要點

點開dma,回圈模式 資料長度炫byte(這些引數需要自己網上查,還有dma的作用這些基礎的東西都要了解一下)
看要用多少波特率的串口,發送端接收端要一樣不然接收不到

時鐘點到最高,這里是168hz

1是專案名稱
2路徑不能有中文
3炫mdk右邊那個電5

四個點上去

生成代碼
main函式內2句話初始化一下
其中可以去查查UART_IT_IDLE空閑中斷跟其他幀中斷之間的區別,這里一半用空閑中斷
XYZ_BUFFER是陣列首地址
串口收到的訊息會放到這個陣列內
因為陀螺儀資料是11位所以這邊11位11位地收資料
unsigned char XYZ_BUFFER[20];//陀螺儀
中斷內的函式:
void UART8_IRQHandler(void)
{
/* USER CODE BEGIN UART8_IRQn 0 */
uint16_t temp;
uint8_t j=0,sum=0;
if(__HAL_UART_GET_FLAG(&huart8,UART_FLAG_IDLE)==SET)//標志位:如果檢測到收到資料了就進入這個if
{
__HAL_UART_CLEAR_IDLEFLAG(&huart8);//清除標志位,方便下次收資料
HAL_UART_DMAStop(&huart8);// 1
temp=11-hdma_uart8_rx.Instance->NDTR;// 2
HAL_UART_Transmit_DMA(&huart8,XYZ_BUFFER,temp); //3
for(j=0;j<10;j++)
sum+=XYZ_BUFFER[j];
if(sum==XYZ_BUFFER[10]&&XYZ_BUFFER[1]==0x53)
{
Roll=(float)((XYZ_BUFFER[3]<<8)|XYZ_BUFFER[2])/32768*180;
// Pich=(float)((XYZ_BUFFER[5]<<8)|XYZ_BUFFER[4])/32768*180;
Yaw =(float)((XYZ_BUFFER[7]<<8)|XYZ_BUFFER[6])/32768*180;
}}
HAL_UART_Receive_DMA(&huart8,XYZ_BUFFER,11); //4
/* USER CODE END UART8_IRQn 0 */
HAL_UART_IRQHandler(&huart8);
/* USER CODE BEGIN UART8_IRQn 1 */
/* USER CODE END UART8_IRQn 1 */
}
代碼中分為1234部
1:前面說了,單片機接收到串口的資料之后,會通過dma直接把資料送到cpu,這樣操作大大提高了資訊傳輸速度,但是有一個小問題,就是串口可能沒發夠11位資料,所以第一步要暫停dma接收,
2:因為我們要11byte資料,所以用11減去ndtr暫存器(這個暫存器記錄當前代碼收到幾個資料)比如收到5個,temp就=11-5=6
3:湊齊11個byte資料,所以向CPU再發送temp個,比如前面只有5個,這里發送6個
至此,CPU內也就是XYZ_BUFFER這個陣列內已經有11個資料了,但是,還沒完,我們是隨便抽取了一段連續的11位元組資料,所以會遇到這種情況,就是這11位資料不是一段有效幀,而是無效幀(無效幀:比如傳感器的資料為1 2 3 4 … 11 ,而我們接收到的資料卻是:8 9 10 11 1 …7;也就是截取到前一半和后一半)為了判斷這一幀資料是不是有效資料,在3和4之間做的就是判斷,具體如何判斷有效幀一般產品介紹書會說,陀螺儀這11幀資料有個資料校驗幀
懶得找說明書,我直接貼了:從第一個資料到底10個資料累加會等于底11個資料校驗幀
串口讀取結束,我們拿到了需要的資料,并且將它存入結構體xyz
4:重新發送11幀
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/302298.html
標籤:其他
上一篇:通信協議定義
下一篇:嵌入式硬體設計:三極管
