STM32
直播中

李宛蔓

7年用户 981经验值
私信 关注
[问答]

平衡显示小车是如何与上位机进行通信的

平衡显示小车是如何与上位机进行通信的?如何对其进行测试?

回帖(1)

刘翔宇

2021-11-18 09:19:25
  这几天在学平衡小车之家的平衡车,才意识到上位机显示小车参数的方便性,且平衡小车之家的上位机代码易移植。
  上位机通信协议
  与上位机通信的数据帧长度固定为 4*N+1,帧数据字节之间传输延时不可超过 1ms,否则将认为当前帧结束。UI 刷新没有限制显示延时。
  STM32上位机库文件
  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];
  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
  主函数
  #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
  }
  }
  串口发送数据缓冲区一共有了42个字节,只用到的只有41个(0~40)。每个channel占用4个,共10个channel,再加一个帧头$ (用来区分不同数据的标记)。
  用到几个channel,Channel_Number就写几,比如用到2个channel,Channel_Number=2,这时候DataScope_Data_Generate(2)=9,DataScope_OutPut_Buffer[9]赋值为9,便于统计(4*N+1格式),但其实只发送DataScope_OutPut_Buffer[0~8]。
  验证
  channel 1 500sin(a)
  channel 2 500 tan(a)
  channel 3 500cos(a)
  channel 4 100a
  channel 5~8 0
  
  看得出上位机波形基本一致。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分