DSP新手自学中,TI公司DSPCANExample_2803xECanBack2Back.c解析

例程下载地址:http://www.ti.com.cn/tool/cn/controlsuite。
下载好后在controlSUITE\device_support\f2803x\v124\DSP2803x_examples_ccsv4\ecan_back2back可找到例程
#include “DSP28x_Project.h” // Device Headerfile and Examples Include File

// Prototype statements for functions found within this file.
void mailbox_check(int32 T1, int32 T2, int32 T3);
void mailbox_read(int16 i);
// Global variable for this example
Uint32 ErrorCount;
Uint32 PassCount;
Uint32 MessageReceivedCount;
Uint32 TestMbox1 = 0;
Uint32 TestMbox2 = 0;
Uint32 TestMbox3 = 0;
void main(void)
{
Uint16 j;
struct ECAN_REGS ECanaShadow;
ECanaShadow影子寄存器的作用:ECanaRegs不支持位操作,TI的例程中将ECanaRegs赋给ECanaShadow,对影子寄存器进行位操作,提高代码的可读性。
InitSysCtrl():
该函数将系统控制寄存器初始化为已知状态。
1-禁用看门狗
2-将PLLCR设置为适当的SYSCLKOUT频率
3-为高频和低频外设时钟设置预分频器
4-启用外设时钟

InitECanGpio();
InitECanGpio():初始化GPIO,此功能初始化GPIO引脚以用作eCAN引脚
DINT;
禁止CPU中断
InitPieCtrl();
该功能将PIE控制寄存器初始化为已知状态。PIE中断控制寄存器的功能可以参考下图。
在这里插入图片描述

IER = 0x0000;
IFR = 0x0000;
IER和IFR分别是CPU中断的使能寄存器和标志寄存器,IER的某一位为1,表示相应的中断使能,为0表示相应的中断禁止。IFR的某一位为1表示相应的中断标志置位,就是有相应的中断请求,为0表示无中断请求。
InitPieVectTable();
初始化所有设备外围设备:
此函数会将PIE向量表初始化为已知状态。
此功能必须在启动后执行。

MessageReceivedCount = 0;
ErrorCount = 0;
PassCount = 0;
邮件已接收次数,错误次数,通过次数
InitECana(); // Initialize eCAN-A module
此功能将eCAN模块初始化为已知状态。包括ECanaShadow(eCAN影子寄存器),ECanaMboxes(eCAN邮箱),ECanaRegs(eCAN控制和状态寄存器)的初始化。
ECanaMboxes.MBOX0.MSGID.all = 0x9555AAA0;
ECanaMboxes.MBOX1.MSGID.all = 0x9555AAA1;
ECanaMboxes.MBOX2.MSGID.all = 0x9555AAA2;
ECanaMboxes.MBOX3.MSGID.all = 0x9555AAA3;
ECanaMboxes.MBOX4.MSGID.all = 0x9555AAA4;
ECanaMboxes.MBOX5.MSGID.all = 0x9555AAA5;
ECanaMboxes.MBOX6.MSGID.all = 0x9555AAA6;
ECanaMboxes.MBOX7.MSGID.all = 0x9555AAA7;
ECanaMboxes.MBOX8.MSGID.all = 0x9555AAA8;
ECanaMboxes.MBOX9.MSGID.all = 0x9555AAA9;
ECanaMboxes.MBOX10.MSGID.all = 0x9555AAAA;
ECanaMboxes.MBOX11.MSGID.all = 0x9555AAAB;
ECanaMboxes.MBOX12.MSGID.all = 0x9555AAAC;
ECanaMboxes.MBOX13.MSGID.all = 0x9555AAAD;
ECanaMboxes.MBOX14.MSGID.all = 0x9555AAAE;
ECanaMboxes.MBOX15.MSGID.all = 0x9555AAAF;
ECanaMboxes.MBOX16.MSGID.all = 0x9555AAA0;
ECanaMboxes.MBOX17.MSGID.all = 0x9555AAA1;
ECanaMboxes.MBOX18.MSGID.all = 0x9555AAA2;
ECanaMboxes.MBOX19.MSGID.all = 0x9555AAA3;
ECanaMboxes.MBOX20.MSGID.all = 0x9555AAA4;
ECanaMboxes.MBOX21.MSGID.all = 0x9555AAA5;
ECanaMboxes.MBOX22.MSGID.all = 0x9555AAA6;
ECanaMboxes.MBOX23.MSGID.all = 0x9555AAA7;
ECanaMboxes.MBOX24.MSGID.all = 0x9555AAA8;
ECanaMboxes.MBOX25.MSGID.all = 0x9555AAA9;
ECanaMboxes.MBOX26.MSGID.all = 0x9555AAAA;
ECanaMboxes.MBOX27.MSGID.all = 0x9555AAAB;
ECanaMboxes.MBOX28.MSGID.all = 0x9555AAAC;
ECanaMboxes.MBOX29.MSGID.all = 0x9555AAAD;
ECanaMboxes.MBOX30.MSGID.all = 0x9555AAAE;
ECanaMboxes.MBOX31.MSGID.all = 0x9555AAAF;
配置0-31号邮箱的消息标识符寄存器(MSGID)。
消息标识符寄存器(MSGID)字段说明
在这里插入图片描述

以MBOX31.MSGID.all = 0x9555AAAF为例,0x9555AAAF的二进制为10 01010 10101 01011 01010 10101 01111,表示31号邮箱的消息是扩展标识符,不使用接受掩码,邮箱不回复远程请求。为什么需要29位消息标识符,及其含义暂未找到原因。
ECanaRegs.CANMD.all = 0xFFFF0000;
邮箱方向寄存器(CANMD):该寄存器用于配置邮箱的发送或接收操作。
0xFFFF0000表示0到15号的邮箱是发送邮箱,16到31号邮箱是接收邮箱。
在这里插入图片描述

ECanaRegs.CANME.all = 0xFFFFFFFF;
邮箱启用寄存器(CANME):此寄存器用于启用/禁用单个邮箱。
0xFFFFFFFF表示邮箱全部启用。

// Specify that 8 bits will be sent/received
ECanaMboxes.MBOX0.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX1.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX2.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX3.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX4.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX5.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX6.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX7.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX8.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX9.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX10.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX11.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX12.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX13.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX14.MSGCTRL.bit.DLC = 8;
ECanaMboxes.MBOX15.MSGCTRL.bit.DLC = 8;
指定将0-15号邮箱发送/接收8字节长度数据。
// Write to the mailbox RAM field of MBOX0 - 15
ECanaMboxes.MBOX0.MDL.all = 0x9555AAA0;
ECanaMboxes.MBOX0.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX1.MDL.all = 0x9555AAA1;
ECanaMboxes.MBOX1.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX2.MDL.all = 0x9555AAA2;
ECanaMboxes.MBOX2.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX3.MDL.all = 0x9555AAA3;
ECanaMboxes.MBOX3.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX4.MDL.all = 0x9555AAA4;
ECanaMboxes.MBOX4.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX5.MDL.all = 0x9555AAA5;
ECanaMboxes.MBOX5.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX6.MDL.all = 0x9555AAA6;
ECanaMboxes.MBOX6.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX7.MDL.all = 0x9555AAA7;
ECanaMboxes.MBOX7.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX8.MDL.all = 0x9555AAA8;
ECanaMboxes.MBOX8.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX9.MDL.all = 0x9555AAA9;
ECanaMboxes.MBOX9.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX10.MDL.all = 0x9555AAAA;
ECanaMboxes.MBOX10.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX11.MDL.all = 0x9555AAAB;
ECanaMboxes.MBOX11.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX12.MDL.all = 0x9555AAAC;
ECanaMboxes.MBOX12.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX13.MDL.all = 0x9555AAAD;
ECanaMboxes.MBOX13.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX14.MDL.all = 0x9555AAAE;
ECanaMboxes.MBOX14.MDH.all = 0x89ABCDEF;
ECanaMboxes.MBOX15.MDL.all = 0x9555AAAF;
ECanaMboxes.MBOX15.MDH.all = 0x89ABCDEF;
在这里插入图片描述
配置需要发送的数据,MDL,MDH各是4字节数据。不难看出MDL=MSGID,MDH都等于0x89ABCDEF。
// Since this write is to the entire register (instead of a bit
// field) a shadow register is not required.
EALLOW;
为了能够对这些特殊寄存器进行初始化,所以在对上述特殊寄存器进行改写之前,一定要执行汇编指令asm(“EALLOW”)或者宏定义EALLOW来设置状态寄存器1的C6位,在设置完寄存器之后,一定要注意执行汇编指令asm(“EDIS”)或者宏定义EDIS来清除状态寄存器1的C6位,来防止杂散代码或指针破坏寄存器内容。
ECanaRegs.CANMIM.all = 0xFFFFFFFF;
邮箱中断屏蔽寄存器(CANMIM)字段说明
在这里插入图片描述

EALLOW;
ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
ECanaShadow.CANMC.bit.STM = 1; // Configure CAN for self-test mode
ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
EDIS;
**主控寄存器(CANMC):该寄存器用于控制CAN模块的设置。
**
在这里插入图片描述

自测模式(STM):不存在另一个节点的要求。 在这种模式下,发送节点会生成自己的确认信号。 唯一的要求是为节点配置任何有效的比特率。 也就是说,位时序寄存器不应包含CAN协议不允许的值。
// Begin transmitting
for(;;)
{

   ECanaRegs.CANTRS.all = 0x0000FFFF;  // Set TRS for all transmit mailboxes

发送请求置位寄存器:当准备好发送时,CPU应将TRS [n]位设置为1以开始发送。如果将邮箱配置为接收邮箱,则除非将接收邮箱配置为处理远程帧,否则CANTRS中的相应位将被忽略。
设置CANTRS [n]将导致发送特定消息n。可以同时设置几个位。所有TRS位为1的消息都将依次发送,并且从具有最高邮箱编号(=最高优先级)的邮箱开始,除非TPL位另有规定。

while(ECanaRegs.CANTA.all != 0x0000FFFF ) {} // Wait for all TAn bits to be set…
ECanaRegs.CANTA.all = 0x0000FFFF; // Clear all TAn
MessageReceivedCount++;
CANTA:邮箱发送响应寄存器,CANTA[31:0]
1:如果邮箱n的消息发送成功,则该寄存器的位n置1。
0:消息未发送

//Read from Receive mailboxes and begin checking for data */
for(j=0; j<16; j++) // Read & check 16 mailboxes
{
mailbox_read(j); // This func reads the indicated mailbox data
mailbox_check(TestMbox1,TestMbox2,TestMbox3); // Checks the received data
}
}
}

void mailbox_read(int16 MBXnbr)
{
volatile struct MBOX *Mailbox;
Mailbox = &ECanaMboxes.MBOX0 MBXnbr;
ECanaMboxes是eCAN邮箱,MBOX0表示0号邮箱的指针,+MBXnbr则邮箱号加MBXnbr号。我最初以为应该通过16-31号邮箱读取消息,结果是用0-15号邮箱读取的,还没确定是为什么,可能和自测模式(STM)有关。
TestMbox1 = Mailbox->MDL.all; // = 0x9555AAAn (n is the MBX number)
TestMbox2 = Mailbox->MDH.all; // = 0x89ABCDEF (a constant)
TestMbox3 = Mailbox->MSGID.all;// = 0x9555AAAn (n is the MBX number)
} // MSGID of a rcv MBX is transmitted as the MDL data.

邮箱的八个字节用于存储CAN消息的数据字段。DBO(CANMC.10)的设置确定存储数据的顺序。从CAN总线发送或接收数据,从字节0开始。
当DBO(CANMC.10)= 1时,数据将从CANMDL寄存器的最低有效字节开始到CANMDH寄存器的最高有效字节结束进行存储或读取。
当DBO(CANMC.10)= 0时,数据将从CANMDL寄存器的最高有效字节开始到CANMDH寄存器的最低有效字节结束进行存储或读取。

void mailbox_check(int32 T1, int32 T2, int32 T3)
{
if((T1 != T3) || ( T2 != 0x89ABCDEF))
{
ErrorCount++;
}
else
{
PassCount++;
}
}
前面配置发送数据时,MDL=MSGID,MDH都等于0x89ABCDEF,收到的数据T1=MDL,T3 = MSGID,T2=MDH,所有T1应该等于T3,T2应该等于0x89ABCDEF。

  • 12
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值