DSP C2000中char占2个字节
最近在用TMS320F28335的eCAN功能,MailBox只能收发BYTE类型的数据。
由于头文件中没有定义BYTE类型的数据,所以刚开始想用unsigned char来声明一个8位的变量,如下:
#define Uint8 unsigned char
Uint8 ucData;
下载好程序后,跑仿真的时候发现unsigned char 编译后竟然单独占用2个字节,在网上看大家说是因为DSP 没有8位的寄存器,只有16位寄存器引起的。
8位数据读写的目的
之前eCAN的数据发送程序中,如果需要发送16位数据,数据与MailBox的数据寄存器关联方式如下:
//Send data
unsigned short usTxData, usRxData;
Mailbox->MDL.byte.BYTE0 = usTxData& 0xFF;
Mailbox->MDL.byte.BYTE1 = (usTxData>> 8) & 0xFF;
//receive data
usRxData = (Mailbox->MDL.byte.BYTE1<<8) | Mailbox->MDL.byte.BYTE0;
这样虽然实现了读写的功能,但是程序的可读性较差,所以如果能将unsigne int 转换为两个独立的BYTE数据,在eCAN的读写过程中,数据结构会更加清晰,程序可读性会有一定的提升。
8位数据读写的实现过程
俗话说官方文档是程序员的第一学习指导手册,古人诚不欺我!
通过研究了TI的头文件里一些对register的定义,发现了Bit Field这种数据结构,可以对数据的任意Bit进行定义。例如:
/* eCAN Message ID (MSGID) bit definitions */
struct CANMSGID_BITS { // bits description
Uint16 EXTMSGID_L:16; // 0:15
Uint16 EXTMSGID_H:2; // 16:17
Uint16 STDMSGID:11; // 18:28
Uint16 AAM:1; // 29
Uint16 AME:1; // 30
Uint16 IDE:1; // 31
};
这个结构体由占16个Bits的EXTMSGID_L, 2个Bits的EXTMSGID_H, 11个Bits的STDMSGID和各占1个Bit的AAM, AME,IDE共同组成,结构体整体占4个字节(32位)
根据上面的例子,重构了用于eCAN收发的数据结构:
//
typedef struct
{
Uint16 ucDataL:8;
Uint16 ucDataH:8;
}CAN_usData_BITS;
union CAN_usData
{
Uint16 ulData;
CAN_usData_BITS usData;
};
通过上面的结构体和共同体的定义,即可将一个16位的无符号整型数据分裂为ucDataH,ucDataL两个8位数据。如果需要对数据整体赋值,则直接进行如下操作:
CAN_usData.ulData = 0x0123;
这时候通过仿真可以观察到:
CAN_usData.usData.ucDataL的值为0x23;
CAN_usData.usData.ucDataH 的值为0x01;
与此相反,如果进行如下操作:
CAN_usData.usData.ucDataL = 0x23;
CAN_usData.usData.ucDataH = 0x01;
通过仿真可以发现:
CAN_usData.ulData的值为0x0123;
至此,将16位数据分为两个8位数,进行读写的功能已经实现了。
8位数据读写的实际应用
上面提到了之前eCAN发数据的时候,是通过将16位的数据向右移8位后得到高BYTE和低BYTE后进行发送;接收时,需要将高BYTE左移8位后与低BTYE相或得到16位数据的实际值。
通过将16位数据转换为两个8位数据,用于eCAN数据的收发程序段可改写为:
typedef struct
{
Uint16 ucDataL:8;
Uint16 ucDataH:8;
}CAN_usData_BITS;
typedef union
{
Uint16 ulData;
CAN_usData_BITS usData;
}CAN_usData;
CAN_usData CAN_usData_Rx, CAN_usData_Tx;
//Send data
Mailbox->MDL.byte.BYTE0 = CAN_usData_Rx.usData.ucDataL;
Mailbox->MDL.byte.BYTE1 = CAN_usData_Rx.usData.ucDataH;
//receive data
CAN_usData_Rx.usData.ucDataL = Mailbox->MDL.byte.BYTE0;
CAN_usData_Rx.usData.ucDataH = Mailbox->MDL.byte.BYTE1;
这样就实现了eCAN通讯中按照8位进行读写数据,个人感觉程序的可读性比之前用位移符号好了一些,数据读写也会更方便一些
|