该文档用以记录并说明DSP开发板TMDSEVM6678LE与PC机通信的内容,要达到的目的在于使DSP开发板能与PC中的Matlab对象实时交换数据,从而实现DSP里控制算法对Matlab里的对象模型的仿真控制。
- 实现C6678 DSP 与Matlab间的串口通信
目录
1 数据在PC与DSP内的存储形式
浮点数的存储 IEEE 754
浮点数的存储一般依据IEEE二进制浮点数算术标准(IEEE 754)进行存储,如图1所示,即最高位为符号位,中间为指数位,低位为尾数位。
以32位单精度浮点数为例,指数域为8个bit,即能表示的指数范围为 -127 ~ 128。尾数域有23个bit,同时由于隐藏位的存在,尾数域的精度为24个bit。
按照IEEE 754的格式,浮点数12.5的表示形式即为0100 0001 0100 1000 0000 0000 0000 0000
关于浮点数存储的详细讨论,可以参看:
浮点数在计算机中存储方式
Wiki
小端模式与大端模式
在几乎所有的机器上,多字节对象都被存储为连续的字节序列。关于字节序列的排列方式,有小端序和大端序两种模式。小端序就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。大端序就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
在一般小端序的PC机内,上面讨论的浮点数12.5的存储方式即为:
内存地址 |
小端序存储内容 |
0x4001
0000 0000
0x4002
0000 0000
0x4003
0100 1000
0x4004
0100 0001
在Matlab内,令f = 12.5,用f = single(f)将f从double型转换为single型,然后用typecast(f, ’uint8’)可以得到内存中的存储的内容,即[0 0 72 65],即从地址低位向高位读取转化为无符号整形。
DSP开发板可调整为小端模式或大端模式,当调为小端模式时,数据在内存中的存储形式如上表。
关于小端和大端的更多讨论可参见:
详解大端模式和小端模式
字节序
2 串口通信基本原理
串口一般用来在PC和其他设备之间传输ASCII码,按位(bit)发送和接收字节。
在通信时需要设置的参数包括:
波特率:为保证速度,DSP与PC间的波特率一般设为115200
校验:无 数据位:8 停止位:1
3 DSP端的串口通信函数与调用
在PDK6678的Post工程里,TI提供了两个用于串口读写的函数,分别是post_write_uart()和post_read_uart()。
其中,post_write_uart()可以将任意长度的一个字符串写到串口端口中去,post_read_uart()可以把任意长度的字符串从串口端口读出。
int post_write_uart(char* msg)
{
uint32_t i;
uint32_t msg_len = strlen(msg);
for (i = 0; i < msg_len; i++)
{
if (platform_uart_write(msg[i]) != Platform_EOK)
{
return -1;
}
}
return 0;
}
int post_read_uart(char * msg, uint32_t delay)
{
uint32_t i;
uint32_t msg_len = strlen(msg);
for(i=0;iif(platform_uart_read(&(msg[i]),delay) != Platform_EOK)
{
return -1;
}
}
return 0;
}
因为在DSP内部主要通过单精度浮点数进行计算,而串口只能按字节传输字符串。因此在DSP中要在串口写浮点数时要先将浮点数转换成字符串格式,然后将四个字节的字符串调用函数进行传送;在串口读取浮点数时要一次读入四个字节的字符串,在转成浮点数的格式。
浮点数转成字符串的过程为:
char write_char[sizeof(float)];
memcpy(write_char,&write_float,sizeof(float));
字符串转成浮点数的过程为:
float read_float;
memcpy(read_float,&read_char,sizeof(float));
因为DSP内的数据也是小端模式存储的,因此从PC端发来的四个字节可以直接转成float型。
在调用读写串口的函数前,要先加入以下语句
platform_init(&init_flags, &init_config);
platform_uart_init();
platform_uart_set_baudrate(115200);
4 Matlab端的串口通信函数与调用
关于串口通信,Matlab内置了如下函数:
s=serial('COM5');
set(s,'BaudRate',115200);
set(s,'Timeout',10);
fopen(s);
fwrite(s, buffer, 'uint32');
buffer=uint32(fread(s,12,'uint32'));
因为Matlab里的数值格式默认为64bit的双精度浮点型,因此在串口传送前要进行格式转换。以浮点数12.5为例,串口传送前的转换过程如下:
转换形式 |
Matlab命令 |
Matlab结果 |
内存内容 |
|
|
|
0x4001
0x4002
0x4003
0x4004
双精度到单精度
f = single(12.5);
f = 12.5000
00000000
00000000
01001000
01000001
强制转化为uint32格式
f_uint32=typecast(f,’uint32’);
f_uint32= 1095237632
00000000
00000000
01001000
01000001
同样的,对于从串口接收到的数据,也要用typecast(f_read, ’single’)进行格式转换。
5 主从通信模式
在通信过程中,DSP作主机,对串口发出读或写的指令,当Matlab收到相应的指令后,将准备好的数据写入串口中,或从串口中读出。
Matlab端的通信程序流程为: |
DSP端的通信流程为: |
参数说明:
Read指令:0xFF(1byte)
Write指令:0xF0(1byte)
count_read:DSP读校验。每个读周期加1,初始值为1.
count_write:DSP写校验。每个写周期加1,初始值为1.
根据以上流程图撰写Matlab端与DSP端的程序,并通过实验进行测试。
(上面的方法我自己做过几个测试,都没问题,测试内容有点繁琐,就不放上来了,有兴趣了解的再联系我。)