实现目的
使用DSP28335串口通信接口(Serial Communication Interface,SCI)发送浮点数到上位机,使用Vofa+进行数据可视化
JustFloat通信协议
根据IEEE754单精度浮点数(32位)标准进行浮点数据表示,其中符号位(1位)+指数位(8位)+尾数位(23位),具体如下图解释:
1.数据格式(浮点数在机器中存储格式):
2.指数等于255,尾数不等于0,表示NaN(not a number)
3.指数等于255,尾数等于0,表示+Inf(s=0)或-Inf(s=1)
4.0<指数<255,表示:
(
−
1
)
s
×
2
(指数
−
127
)
×
(
1.
尾数
)
(-1)^s\times2^{(指数-127)}\times(1.尾数)
(−1)s×2(指数−127)×(1.尾数)
5.指数等于0,尾数不等于0,表示:
(
−
1
)
s
×
2
(
−
126
)
×
(
0.
尾数
)
(-1)^s\times2^{(-126)}\times(0.尾数)
(−1)s×2(−126)×(0.尾数)
6.指数等于0,尾数等于0,表示:
(
−
1
)
s
×
(
0.0
)
(-1)^s\times(0.0)
(−1)s×(0.0)
为解析一帧数据,JustFloat使用+Inf表示数据尾,转化为二进制即0x7f800000,按照小端数据存储,所以发送一帧数据时,数据尾要发送0x00,0x00,0x80,0x7f四个字节。
DSP28335实现
利用共用体不同类型成员共用同一存储空间的特性,定义一个单精度浮点数(32位),和两个无符号整型数(16位),则浮点数自动按照IEEE754标准转化为二进制进行存储,通过读两个无符号整型数可以解析出四个字节(8位),然后按照小端方式通过SCI发送出去。
/* 共用体定义 */
typedef union
{
float32 DataFloat;
Uint16 DataUint16[2];
}BSP_FLOAT_UNION;
ps:共用体定义中使用两个Uint16数,而不是Unsigned char或者char,因为在DSP28335中数据最小存储单位是16位,char数据类型也是16位,可百度搜索相关内容
1.SCI配置
/*
* bsp_sci.c
*
* Created on: 2022年6月4日
* Author: zhouy
*/
#include "bsp_sci_fifo.h"
#include "DSP28x_Project.h"
void BspInitSciFifo(void)
{
// 配置通信协议
SciaRegs.SCICCR.all = 0x07; // 1位停止位,禁止奇偶校验,禁止回送测试,空闲线处理模式,8位字符长度
SciaRegs.SCICTL1.all = 0x03; // 使能发送和接收
// 波特率配置
SciaRegs.SCILBAUD = BAUDRATE_L;
SciaRegs.SCIHBAUD = BAUDRATE_H;
// FIFO配置
SciaRegs.SCIFFTX.bit.SCIRST = 1; // FIFO复位
SciaRegs.SCIFFTX.bit.SCIFFENA = 1; // 使能FIFO
SciaRegs.SCIFFTX.bit.TXFFIENA = 0; // 使能发送FIFO中断
SciaRegs.SCIFFTX.bit.TXFFIL = 8; // 发送FIFO中断级别(TXFFST值小于或等于TXFFIL值会产生中断)
SciaRegs.SCIFFRX.bit.RXFFIENA = 1; // 使能接收FIFO中断
SciaRegs.SCIFFRX.bit.RXFFIL = 8; // 接收FIFO中断级别
SciaRegs.SCIFFCT.all = 0x00; // FIFO传送延时为0
// 复位
SciaRegs.SCICTL1.bit.SWRESET = 1; // 重启SCIA
SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 1; // 重新使能发送FIFO的操作
SciaRegs.SCIFFRX.bit.RXFIFORESET = 1; // 重新使能接收FIFO的操作
}
2.数据发送函数
void BspSendCharFifo(Uint16 data)
{
while (SciaRegs.SCIFFTX.bit.TXFFST != 0); // 等待发送FIFO为空
SciaRegs.SCITXBUF = data;
}
void BspSendMsgFifo(char* msg)
{
int index = 0;
while(msg[index] != '\0')
{
BspSendCharFifo(msg[index]);
index++;
}
}
/* 浮点数发送函数 */
void BspSendFloatFifo(BSP_FLOAT_UNION* data,Uint16 len)
{
Uint16 i,j;
for(i = 0;i < len;i++)
{
for(j = 0;j < 2;j++)
{
BspSendCharFifo(((data+i)->DataUint16[j])&0x00ff);
BspSendCharFifo((((data+i)->DataUint16[j])>>8)&0x00ff);
}
}
/* 数据帧尾 */
BspSendCharFifo(0x00);
BspSendCharFifo(0x00);
BspSendCharFifo(0x80);
BspSendCharFifo(0x7f);
}
3.头文件
/*
* bsp_sci.h
*
* Created on: 2022年6月4日
* Author: zhouy
*/
#ifndef BSP_SCI_H_
#define BSP_SCI_H_
#include "DSP28x_Project.h"
/*
* 波特率 @LSPCLK = 37.5MHz
* Baud rate = LSPCLK/((BRR+1)*8)
* 7A0:2400
* 3D0:4800
* 1E7:9600
* F3:19200
* 79:38400
* */
#define BAUDRATE_L 0x79
#define BAUDRATE_H 0x00
/* 共用体定义 */
typedef union
{
float32 DataFloat;
Uint16 DataUint16[2];
}BSP_FLOAT_UNION;
/* 声明指针类型 */
typedef BSP_FLOAT_UNION *BSP_FLOAT_UNION_HANDLE;
/* 函数声明 */
void BspInitSciFifo(void);
void BspSendCharFifo(Uint16);
void BspSendMsgFifo(char*);
void BspSendFloatFifo(BSP_FLOAT_UNION_HANDLE,Uint16);
#endif /* BSP_SCI_H_ */
使用
定义需要发送的数据:
BSP_FLOAT_UNION DataSend[4]; // 发送数据
循环执行:
/* 为浮点数赋值 */
DataSend[0].DataFloat = 1.1;
DataSend[1].DataFloat = 2.12;
DataSend[2].DataFloat = 3.123;
DataSend[3].DataFloat = 4.1234;
BspSendFloatFifo(DataSend,4);
效果: