平衡小車之家PC端上位機協議程式碼解讀
阿新 • • 發佈:2018-12-22
平臺是基於STM32F103C8T6,資料可從這裡下載連結:連結,提取碼:qskh
一、程式碼再現
DataScope_DP.c
#include "DataScope_DP.h" unsigned char DataScope_OutPut_Buffer[42] = {0}; //串列埠傳送緩衝區 //函式說明:將單精度浮點資料轉成4位元組資料並存入指定地址 //附加說明:使用者無需直接操作此函式 //target:目標單精度資料 //buf:待寫入陣列 //beg:指定從陣列第幾個元素開始寫入 //函式無返回 void Float2Byte(float *target,unsigned char *buf,unsigned char beg) { unsigned char *point; point = (unsigned char*)target; //得到float的地址 buf[beg] = point[0];//同時也也可以看出STM32是小端模式 buf[beg+1] = point[1]; buf[beg+2] = point[2]; buf[beg+3] = point[3]; } //函式說明:將待發送通道的單精度浮點資料寫入傳送緩衝區 //Data:通道資料 //Channel:選擇通道(1-10) //函式無返回 void DataScope_Get_Channel_Data(float Data,unsigned char Channel) { if ( (Channel > 10) || (Channel == 0) ) return; //通道個數大於10或等於0,直接跳出,不執行函式 else { switch (Channel) { case 1: Float2Byte(&Data,DataScope_OutPut_Buffer,1); break; case 2: Float2Byte(&Data,DataScope_OutPut_Buffer,5); break; case 3: Float2Byte(&Data,DataScope_OutPut_Buffer,9); break; case 4: Float2Byte(&Data,DataScope_OutPut_Buffer,13); break; case 5: Float2Byte(&Data,DataScope_OutPut_Buffer,17); break; case 6: Float2Byte(&Data,DataScope_OutPut_Buffer,21); break; case 7: Float2Byte(&Data,DataScope_OutPut_Buffer,25); break; case 8: Float2Byte(&Data,DataScope_OutPut_Buffer,29); break; case 9: Float2Byte(&Data,DataScope_OutPut_Buffer,33); break; case 10: Float2Byte(&Data,DataScope_OutPut_Buffer,37); break; } } } //函式說明:生成 DataScopeV1.0 能正確識別的幀格式 //Channel_Number,需要傳送的通道個數 //返回傳送緩衝區資料個數 //返回0表示幀格式生成失敗 unsigned char DataScope_Data_Generate(unsigned char Channel_Number) { if ( (Channel_Number > 10) || (Channel_Number == 0) ) { return 0; } //通道個數大於10或等於0,直接跳出,不執行函式 else { DataScope_OutPut_Buffer[0] = '$'; //幀頭 switch(Channel_Number) { case 1: DataScope_OutPut_Buffer[5] = 5; return 6; case 2: DataScope_OutPut_Buffer[9] = 9; return 10; case 3: DataScope_OutPut_Buffer[13] = 13; return 14; case 4: DataScope_OutPut_Buffer[17] = 17; return 18; case 5: DataScope_OutPut_Buffer[21] = 21; return 22; case 6: DataScope_OutPut_Buffer[25] = 25; return 26; case 7: DataScope_OutPut_Buffer[29] = 29; return 30; case 8: DataScope_OutPut_Buffer[33] = 33; return 34; case 9: DataScope_OutPut_Buffer[37] = 37; return 38; case 10: DataScope_OutPut_Buffer[41] = 41; return 42; } } return 0; }
DataScope_DP.h
#ifndef __DATA_PRTOCOL_H #define __DATA_PRTOCOL_H extern unsigned char DataScope_OutPut_Buffer[42]; //待發送幀資料快取區 void DataScope_Get_Channel_Data(float Data,unsigned char Channel); // 寫通道資料至 待發送幀資料快取區 unsigned char DataScope_Data_Generate(unsigned char Channel_Number); // 傳送幀資料生成函式 #endif
Minibalance.c
#include "sys.h" #include "DataScope_DP.h" unsigned char i; //計數變數 unsigned char Send_Count; //串列埠需要傳送的資料個數 static float a; int main(void) { Stm32_Clock_Init(9); //系統時鐘設定 delay_init(72); //延時初始化 uart_init(72,128000); //初始化串列埠1 while(1) { a+=0.1; if(a>3.14) a=-3.14; DataScope_Get_Channel_Data(500*sin(a), 1 ); DataScope_Get_Channel_Data(500*tan(a), 2 ); DataScope_Get_Channel_Data(500*cos(a), 3 ); DataScope_Get_Channel_Data(100*a , 4 ); DataScope_Get_Channel_Data(0, 5 ); DataScope_Get_Channel_Data(0, 6 ); DataScope_Get_Channel_Data(0, 7 ); DataScope_Get_Channel_Data(0, 8 ); DataScope_Get_Channel_Data(0, 9 ); DataScope_Get_Channel_Data(0, 10); Send_Count = DataScope_Data_Generate(10); for( i = 0 ; i < Send_Count; i++) { while((USART1->SR&0X40)==0); USART1->DR = DataScope_OutPut_Buffer[i]; } delay_ms(50); //20HZ } }
二、快速上手
波特率 128000
①
處對應10個通道要顯示的資料。
②
處對應要顯示的總共通道數!
三、程式碼解讀
協議:
-
上位機通訊的資料幀長度固定為
4*N+1
,幀資料位元組之間傳輸延時不可超過1ms
,否則將認為當前幀結束,UI 重新整理沒有限制顯示延時。 -
串列埠傳送緩衝區一共開了42個位元組,其實用到的只有41個。每個channel佔用4個,共10個channel,再加一個幀頭
$
。 然後用哪個通道,就不斷哪個通道對應的4位元組就行。比如我一直用4通道(1~10),那麼對應的串列埠傳送緩衝區的位置是13-16!
知道上面兩條,以上的程式碼就很好理解了!