1. 程式人生 > >PC通過串列埠助手如何給單片機發送小數,微控制器接收後如何處理?

PC通過串列埠助手如何給單片機發送小數,微控制器接收後如何處理?

兩種思路,供參考。
1. 原始位元組
按原始位元組資料傳送,這也是我個人比較傾向的方式。首先,位、位元組和位元組流本身沒有任何意義,如果按約定的方式去解析,才能有具體的含義。
用什麼約定方式呢?使用符合IEEE 754的浮點數標準,每個浮點數為4個位元組,按標準解析就可以了。
其實這個標準,包括STM32在內的很多微控制器,都是支援的,內部的表達方式都是一致的,而且效率很快。
技巧就是定義好一個聯合體,這一步很關鍵:

  1. union ByteDouble
  2. {
  3.     float x;
  4.     struct SB
  5.     {
  6.         uint8_t b3;
  7.         uint8_t b2;
  8.         uint8_t b1;
  9.         uint8_t b0;
  10.     }bb; 
  11. }bd;

複製程式碼

然後在USART的串列埠中斷中,用4個uint8_t獲取這四個位元組,最後用float表示出來。

  1. //獲取資料中斷處理函式
  2. void USART1_IRQHandler(void)
  3. {
  4.     
  5.     if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)//Got Data
  6.     {
  7.         USART1_RX_BUFFER[USART1_RX_CNT++]=USART_ReceiveData(USART1);
  8.     }
  9.     else if(USART_GetITStatus(USART1,USART_IT_IDLE)!=RESET)
  10.     {
  11.         //Clear USART_IT_RXNE Flag
  12.         USART1->DR;
  13.         //Clear USART_IT_IDLE Flag
  14.         USART1->SR;
  15.         //Process Receive DATA Here
  16.         ////////////////////////////////////////////////
  17.         //Example:
  18.         //printf("%s\r\n",USART1_RX_BUFFER);
  19.         bd.bb.b0=USART1_RX_BUFFER[0];
  20.         bd.bb.b1=USART1_RX_BUFFER[1];
  21.         bd.bb.b2=USART1_RX_BUFFER[2];
  22.         bd.bb.b3=USART1_RX_BUFFER[3];
  23.         printf("%f\r\n",bd.x);
  24.         ////////////////////////////////////////////////    
  25.         //Finally Clear Buffer
  26.         memset(USART1_RX_BUFFER,0x00,USART1_RX_CNT);
  27.         USART1_RX_CNT=0;
  28.     }   
  29. }

複製程式碼

測試如下:
 
這個是浮點數的表示形式,123.456按IEEE754的規範,表示成十六進位制就是42 F6 E9 79。

然後使用串列埠程式傳送給STM32:
 
兩個注意的地方:
a. 浮點數是近似表示,所以你看STM32解析的是123.456001,而不是精確的123.456,這並不違反IEEE 754標準,尤其是涉及到最後一個bit的四捨五入方法,在IEEE 754 中並沒有明確規定。
b. 位元組順序和對齊。你所有的工作只是定義好聯合體,然後填充好聯合體,STM32會自動替你完成轉換。不過需要注意的是,一些上位機採用的是大端對齊的方式, 傳送的位元組順序會相反。

2. 字串方式
如果是字串或者其他方式傳送,那就可以自定義一套轉換機制,甚至你的上位機在傳送2/5的分數,或者40%這樣的字串,都可以解析為0.4的浮點數,這種方式的靈活度非常高,但是對程式設計要求更復雜,而且相對而言,比較佔用MCU的CPU時間和Flash。

#include<stdlib.h>    // 使用 atof()函式 需要包含此標頭檔案
#include<stdio.h>
int main()
{
double d;
char str[] = "123.456";
d=atof(str);
printf("string=%s,double=%lf\n",str,d);
return 0;
}

 

轉自http://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&tid=615818