- 单片机使用联合体发送浮点数
union floatTypePosition
{
struct xyValueStructure
{
float xValue;
float yValue;
}xyValueStruct;
uint8_t para[8];
};//接下来只需给两个float数据赋值,相同位置偏移里的para数组则会存储float内存中的值;
//在发送数据的函数中写下面语句
union floatTypePosition FloatTypePosition;
FloatTypePosition.xyValueStruct.xValue = 100;
FloatTypePosition.xyValueStruct.yValue = 200;
HAL_UART_Transmit(&huart1,(uint8_t *)FloatTypePosition.para,sizeof(FloatTypePosition.para),1000);
//强制类型转换
/*强制类型转化*/
发送数据函数:HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
uint8_t *pData:pData是 uint8_t 类型的指针,指针加1地址移动一个字节
int *pData:指针加1地址移动四个字节
所以对于 int para[10];串口发送其数据时需先将数组名强制类型转化为uint8_t型的指针;
或是直接:
uint8_t *p;
p = (uint8_t *)para;
HAL_UART_Transmit(..., p,....);
or
uint8_t sendbuff[10];
HAL_UART_Transmit(..., sendbuff,....);
//在实际使用中自己总喜欢避开使用指针,但确实方便,要积累下来
//注意此处,一开始这么写的,结构xValue与yValue实际存储值一样,测试时通过发现para的后四个元素值总变化发现错误的;
union floatTypePosition
{
float xValue;
float yValue;
uint8_t para[8];
};
/*注意:因为在WPF中写的是一次读取一定长度的数据,一开始把数据头分开时接收总是错误,
然后合在一起发就没问题了,虽然感觉分开发也行,但是,,,,,,*/
HAL_UART_Transmit(&huart1,(uint8_t *)sendDataHead[0],sizeof(sendDataHead[0]),1000);//这里不要拆开发,目前上位机接收是一次读的一段数据
HAL_UART_Transmit(&huart1,sendDataWpf,sizeof(sendDataWpf),1000);
HAL_UART_Transmit(&huart1,(uint8_t *)sendDataHead[1],sizeof(sendDataHead[0]),1000);
- WPF使用field Offset接收
using System.Runtime.InteropServices;//需要额外引入的程序集
public byte dataReceivedLengthCommended = 10; //设定串口接收数据的长度,这样好一次读几个字节数据
[StructLayout(LayoutKind.Explicit)] //显示指定位置偏移必须的
public struct union
{
[FieldOffset(0)] //值类型与引用类型不能同时用,数据头
public byte temple0;
[FieldOffset(1)]
public byte temple1;
[FieldOffset(2)]
public byte temple2;
[FieldOffset(3)]
public byte temple3;
[FieldOffset(4)]
public byte temple4;
[FieldOffset(5)]
public byte temple5;
[FieldOffset(6)]
public byte temple6;
[FieldOffset(7)]
public byte temple7;
[FieldOffset(8)]
public byte temple8;
[FieldOffset(9)] //数据尾
public byte temple9;
[FieldOffset(1)] //偏移量回归
public float dataGpsLng;
[FieldOffset(5)]
public float dataGpsLat;
}
public void portDataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
try
{
union reData = new union();
/*一次读一个字节数据PORT.ReadByte(),当读到每一中数据对应的数据头后在相应的在读一定数目的数据,并还进行一下数据校验*/
byte[] ReDatasTemp = new byte[dataReceivedLengthCommended]; //用于先存储一次发过来的数据,byte即是无符号整形
Port.Read(ReDatasTemp, 0, ReDatasTemp.Length);
if ((ReDatasTemp[0] == 0x65) && (ReDatasTemp[9] == 0x66))
{
reData.temple1 = ReDatasTemp[1];
reData.temple2 = ReDatasTemp[2];
reData.temple3 = ReDatasTemp[3];
reData.temple4 = ReDatasTemp[4];
reData.temple5 = ReDatasTemp[5];
reData.temple6 = ReDatasTemp[6];
reData.temple7 = ReDatasTemp[7];
reData.temple8 = ReDatasTemp[8];
//则浮点数就可以这么使用:reData.dataGpsLng,reData.dataGpsLat
receiveGPSDataDelagate = new ReceiveGPSDataDelagate(ChangeGPSText);
Dispatcher.Invoke(receiveGPSDataDelagate, reData.dataGpsLng, reData.dataGpsLat); }
}
catch (Exception ex)
{
System.Media.SystemSounds.Beep.Play();
MessageBox.Show(ex.Message, "error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
- 单片机使用“原始的”串口发送
int16_t sendDataWpf[5] = {0x45,0x55,RemoteCh[0],RemoteCh[1],0x46}; //数据头和数据尾,左右油门
HAL_UART_Transmit(&huart1,(uint8_t *)sendDataWpf,sizeof(sendDataWpf),1000); //内存偏移量变为8
- WPF使用字节合并接收
public byte dataReceivedLengthCommended = 10;
public short[] speedYX = new short[2]; //油门数据;
public void portDataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
try
{
union reData = new union();
byte[] ReDatasTemp = new byte[dataReceivedLengthCommended];
Port.Read(ReDatasTemp, 0, ReDatasTemp.Length);
if ( ((ReDatasTemp[0] | ((short)ReDatasTemp[1] << 8)) == 0x45)
&& ((ReDatasTemp[2] | ((short)ReDatasTemp[3] << 8)) == 0x55)
&& ((ReDatasTemp[8] | ((short)ReDatasTemp[9] << 8)) == 0x46))
{
speedYX[0] = (short)(ReDatasTemp[4] | ((short)ReDatasTemp[5] << 8)); //不太清楚为什么要(short)
speedYX[1] = (short)(ReDatasTemp[6] | ((short)ReDatasTemp[7] << 8));
receiveSpeedDataDelagate = new ReceiveSpeedDataDelagate(ChangeSpeedYXText);
Dispatcher.Invoke(receiveSpeedDataDelagate, speedYX[0], speedYX[1]);
}
}
catch (Exception ex)
{
System.Media.SystemSounds.Beep.Play();
MessageBox.Show(ex.Message, "error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
Tips:这里不太清楚为什么移位后自动合并会变为int型,还需要自己转换回short
/*注意此处通过使用移位合并数据的方式
单片机Hal_UART_Transmit(); 函数本身就是差分数据为一个字节一个字节的再发送数据,因此可以这样合并;
对于一个数据,不是byte长度会进行拆分,此数据先发其低字节,再发送其高字节,再发下一个数据的低字节、高字节;
注意合并时需先将要移位的数据进行强制类型转换,不然一移位,那个移位的数据低位自动补0数据就没了;
*/
Tips:在进行bool值的比较时 & 和 &&的效果一样的,但是后者更好,后者有短路的功能;