該文檔用以記錄並說明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);
/* Write the message to the UART */
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;i<msg_len;i++)
{
if(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'); % 創建串口對象s,串口端號COM5
set(s,'BaudRate',115200); % 設定串口s的波特率
set(s,'Timeout',10); % 設定串口s失效時間
fopen(s); % 打開串口s
fwrite(s, buffer, 'uint32'); % 將buffer裏的數據以'uint32'的格式寫入串口s
buffer=uint32(fread(s,12,'uint32'));
% 以'uint32'的格式從串口s讀出12個數據,並強制轉化成'uint32'格式寫入buffer
% 其中的12是指12個32位的數據,而不是12個字節
因爲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端的程序,並通過實驗進行測試。
(上面的方法我自己做過幾個測試,都沒問題,測試內容有點繁瑣,就不放上來了,有興趣瞭解的再聯繫我。)