#include \"DSP2833x_Device.h\" // DSP2833x Headerfile Include File
#include \"DSP2833x_Examples.h\" // DSP2833x 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;
// eCAN控制寄存器需要使用32位的读/写访问。 因此,为此示例创建一组影子寄存器。 这些影子寄存器将用于确保访问是32位而不是16位。
struct ECAN_REGS ECanbShadow;
// 步骤1.初始化系统控制:PLL,看门狗,启用外设时钟。该示例功能可在DSP2833x_SysCtrl.c文件中找到。
InitSysCtrl();
// 步骤2.初始化GPIO:在DSP2833x Gpio.c文件中找到该示例函数,并说明如何将GPIO设置为默认状态。
// InitGpio(); // Skipped for this example
// 在这个例子中,使用GPIO寄存器在这里配置CAN引脚。这个函数在DSP2833x_ECan.c中找到
InitECanGpio();
// 步骤3。清除所有中断并初始化PIE矢量表:禁用CPU中断
DINT;
// 将PIE控制寄存器初始化为默认状态。 默认状态是禁止所有的PIE中断并清除标志。 这个函数可以在DSP2833x_PieCtrl.c文件中找到。
InitPieCtrl();
// 禁用CPU中断并清除所有CPU中断标志:
IER = 0x0000;
IFR = 0x0000;
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in DSP2833x_DefaultIsr.c.
// This function is found in DSP2833x_PieVect.c.
InitPieVectTable();
// 步骤4.初始化所有器件外设:此功能可在DSP2833x_InitPeripherals.c中找到.
// InitPeripherals(); // Not required for this example
// 第5步。用户特定的代码,启用中断:
MessageReceivedCount = 0;
ErrorCount = 0;
PassCount = 0;
// eCAN控制寄存器需要32位访问。 如果要写入单个位,编译器可能会将此访问分解为16位访问。此处介绍的一种解决方案是使用影子寄存器来强制32位访问。
// 将整个寄存器读入一个影子寄存器。 这个访问将是32位。 更改所需的位并将其
值复制到32位写入的eCAN寄存器。
// 为eCAN传输配置eCAN RX和TX引脚
EALLOW;
ECanbShadow.CANTIOC.all = ECanbRegs.CANTIOC.all; 器
ECanbShadow.CANTIOC.bit.TXFUNC = 1; CAN发送功能
ECanbRegs.CANTIOC.all = ECanbShadow.CANTIOC.all;
ECanbShadow.CANRIOC.all = ECanbRegs.CANRIOC.all; 器
ECanbShadow.CANRIOC.bit.RXFUNC = 1; CAN发送功能
ECanbRegs.CANRIOC.all = ECanbShadow.CANRIOC.all;EDIS;
//eCAN I/O控制寄存//CANTX引脚用于//eCAN I/O控制寄存//CANRX引脚用于
//禁用所有的邮箱。
//因为写入整个寄存器(而不是一个位域),影子寄存器是不需要的。
ECanbRegs.CANME.all = 0; //邮箱激活寄存器:激活或者屏蔽的邮箱
//邮箱可以一次写入16位或32位。写入TRANSMIT邮箱的MSGID字段MBOX0-15。
ECanbMboxes.MBOX0.MSGID.all = 0x9555AAA0; //邮箱标识符寄存器
ECanbMboxes.MBOX1.MSGID.all = 0x9555AAA1;
ECanbMboxes.MBOX2.MSGID.all = 0x9555AAA2;
ECanbMboxes.MBOX3.MSGID.all = 0x9555AAA3;
ECanbMboxes.MBOX4.MSGID.all = 0x9555AAA4;
ECanbMboxes.MBOX5.MSGID.all = 0x9555AAA5;
ECanbMboxes.MBOX6.MSGID.all = 0x9555AAA6;
ECanbMboxes.MBOX7.MSGID.all = 0x9555AAA7;
ECanbMboxes.MBOX8.MSGID.all = 0x9555AAA8;
ECanbMboxes.MBOX9.MSGID.all = 0x9555AAA9;
ECanbMboxes.MBOX10.MSGID.all = 0x9555AAAA;
ECanbMboxes.MBOX11.MSGID.all = 0x9555AAAB;
ECanbMboxes.MBOX12.MSGID.all = 0x9555AAAC;
ECanbMboxes.MBOX13.MSGID.all = 0x9555AAAD;
ECanbMboxes.MBOX14.MSGID.all = 0x9555AAAE;
ECanbMboxes.MBOX15.MSGID.all = 0x9555AAAF;
// 写入RECEIVE邮箱的MSGID字段MBOX16-31
ECanbMboxes.MBOX16.MSGID.all = 0x9555AAA0;
ECanbMboxes.MBOX17.MSGID.all = 0x9555AAA1;
ECanbMboxes.MBOX18.MSGID.all = 0x9555AAA2;
ECanbMboxes.MBOX19.MSGID.all = 0x9555AAA3;
ECanbMboxes.MBOX20.MSGID.all = 0x9555AAA4;
ECanbMboxes.MBOX21.MSGID.all = 0x9555AAA5;
ECanbMboxes.MBOX22.MSGID.all = 0x9555AAA6;
ECanbMboxes.MBOX23.MSGID.all = 0x9555AAA7;
ECanbMboxes.MBOX24.MSGID.all = 0x9555AAA8;
ECanbMboxes.MBOX25.MSGID.all = 0x9555AAA9;
ECanbMboxes.MBOX26.MSGID.all = 0x9555AAAA;
ECanbMboxes.MBOX27.MSGID.all = 0x9555AAAB;
ECanbMboxes.MBOX28.MSGID.all = 0x9555AAAC;
ECanbMboxes.MBOX29.MSGID.all = 0x9555AAAD;
ECanbMboxes.MBOX30.MSGID.all = 0x9555AAAE;
ECanbMboxes.MBOX31.MSGID.all = 0x9555AAAF;
// 将邮箱0-15配置为Tx,将16-31配置为Rx
// 由于这是写入整个寄存器(而不是位字段),所以不需要影子寄存器。
ECanbRegs.CANMD.all = 0xFFFF0000; //邮箱方向寄存器
// 启用所有邮箱
// 由于这是写入整个寄存器(而不是位字段),所以不需要影子寄存器。
ECanbRegs.CANME.all = 0xFFFFFFFF;
// 指定8位将被发送/接收
ECanbMboxes.MBOX0.MSGCTRL.bit.DLC = 8; //消息控制寄存器,DLC位中的数字决定了被发送或接受的字节数,合适的范围是0-8.
ECanbMboxes.MBOX1.MSGCTRL.bit.DLC = 8;
ECanbMboxes.MBOX2.MSGCTRL.bit.DLC = 8;
ECanbMboxes.MBOX3.MSGCTRL.bit.DLC = 8;
ECanbMboxes.MBOX4.MSGCTRL.bit.DLC = 8;
ECanbMboxes.MBOX5.MSGCTRL.bit.DLC = 8;
ECanbMboxes.MBOX6.MSGCTRL.bit.DLC = 8;
ECanbMboxes.MBOX7.MSGCTRL.bit.DLC = 8;
ECanbMboxes.MBOX8.MSGCTRL.bit.DLC = 8;
ECanbMboxes.MBOX9.MSGCTRL.bit.DLC = 8;
ECanbMboxes.MBOX10.MSGCTRL.bit.DLC = 8;
ECanbMboxes.MBOX11.MSGCTRL.bit.DLC = 8;
ECanbMboxes.MBOX12.MSGCTRL.bit.DLC = 8;
ECanbMboxes.MBOX13.MSGCTRL.bit.DLC = 8;
ECanbMboxes.MBOX14.MSGCTRL.bit.DLC = 8;
ECanbMboxes.MBOX15.MSGCTRL.bit.DLC = 8;
// 设置为没有请求远程帧
// 由于RTR位在复位时未定义,因此必须将其初始化为适当的值
ECanbMboxes.MBOX0.MSGCTRL.bit.RTR = 0; 位
ECanbMboxes.MBOX1.MSGCTRL.bit.RTR = 0; ECanbMboxes.MBOX2.MSGCTRL.bit.RTR = 0; ECanbMboxes.MBOX3.MSGCTRL.bit.RTR = 0;
ECanbMboxes.MBOX4.MSGCTRL.bit.RTR = 0;
ECanbMboxes.MBOX5.MSGCTRL.bit.RTR = 0;
ECanbMboxes.MBOX6.MSGCTRL.bit.RTR = 0;
ECanbMboxes.MBOX7.MSGCTRL.bit.RTR = 0;
ECanbMboxes.MBOX8.MSGCTRL.bit.RTR = 0;
//消息控制寄存器远程发送请求
ECanbMboxes.MBOX9.MSGCTRL.bit.RTR = 0;
ECanbMboxes.MBOX10.MSGCTRL.bit.RTR = 0;
ECanbMboxes.MBOX11.MSGCTRL.bit.RTR = 0;
ECanbMboxes.MBOX12.MSGCTRL.bit.RTR = 0;
ECanbMboxes.MBOX13.MSGCTRL.bit.RTR = 0;
ECanbMboxes.MBOX14.MSGCTRL.bit.RTR = 0;
ECanbMboxes.MBOX15.MSGCTRL.bit.RTR = 0;
// 写入邮箱MBOX0-15的RAM字段
// 消息数据寄存器
ECanbMboxes.MBOX0.MDL.all = 0x9555AAA0;
ECanbMboxes.MBOX0.MDH.all = 0xABCDEF;
ECanbMboxes.MBOX1.MDL.all = 0x9555AAA1;
ECanbMboxes.MBOX1.MDH.all = 0xABCDEF;
ECanbMboxes.MBOX2.MDL.all = 0x9555AAA2;
ECanbMboxes.MBOX2.MDH.all = 0xABCDEF;
ECanbMboxes.MBOX3.MDL.all = 0x9555AAA3;
ECanbMboxes.MBOX3.MDH.all = 0xABCDEF;
ECanbMboxes.MBOX4.MDL.all = 0x9555AAA4;
ECanbMboxes.MBOX4.MDH.all = 0xABCDEF;
ECanbMboxes.MBOX5.MDL.all = 0x9555AAA5;
ECanbMboxes.MBOX5.MDH.all = 0xABCDEF;
ECanbMboxes.MBOX6.MDL.all = 0x9555AAA6;
ECanbMboxes.MBOX6.MDH.all = 0xABCDEF;
ECanbMboxes.MBOX7.MDL.all = 0x9555AAA7;
ECanbMboxes.MBOX7.MDH.all = 0xABCDEF;
ECanbMboxes.MBOX8.MDL.all = 0x9555AAA8;
ECanbMboxes.MBOX8.MDH.all = 0xABCDEF;
ECanbMboxes.MBOX9.MDL.all = 0x9555AAA9;
ECanbMboxes.MBOX9.MDH.all = 0xABCDEF;
ECanbMboxes.MBOX10.MDL.all = 0x9555AAAA;
ECanbMboxes.MBOX10.MDH.all = 0xABCDEF;
ECanbMboxes.MBOX11.MDL.all = 0x9555AAAB;
ECanbMboxes.MBOX11.MDH.all = 0xABCDEF;
ECanbMboxes.MBOX12.MDL.all = 0x9555AAAC;
ECanbMboxes.MBOX12.MDH.all = 0xABCDEF;
ECanbMboxes.MBOX13.MDL.all = 0x9555AAAD;
ECanbMboxes.MBOX13.MDH.all = 0xABCDEF;
ECanbMboxes.MBOX14.MDL.all = 0x9555AAAE;
ECanbMboxes.MBOX14.MDH.all = 0xABCDEF;
ECanbMboxes.MBOX15.MDL.all = 0x9555AAAF;
ECanbMboxes.MBOX15.MDH.all = 0xABCDEF;
// 由于这是写入整个寄存器(而不是位字段),所以不需要影子寄存器。
EALLOW;
ECanbRegs.CANMIM.all = 0xFFFFFFFF; //邮箱中断屏蔽寄存器,该寄存器受EALLOE保护。邮箱中断使能。
// 请求权限来更改配置寄存器
ECanbShadow.CANMC.all = ECanbRegs.CANMC.all; //主控制寄存器
ECanbShadow.CANMC.bit.CCR = 1; //改变配置请求位
ECanbRegs.CANMC.all = ECanbShadow.CANMC.all;
EDIS;
// 等待CPU被授予更改配置寄存器的权限
// 等待CCE位置位
do
{
ECanbShadow.CANES.all = ECanbRegs.CANES.all; //错误和状态寄存器
} while(ECanbShadow.CANES.bit.CCE != 1 ); //更改配置使能位,该位显示了配置访问权限。
// 配置eCAN时间
EALLOW;
ECanbShadow.CANBTC.all = ECanbRegs.CANBTC.all; //位时序配置寄存器,该寄存器在用户模式下是写保护的,并只能在初始化模式下进行写入。
ECanbShadow.CANBTC.bit.BRPREG = 9; // 波特率欲调节。该寄存器为波特率设置进行预定义。(BRPREG+1)=10 提供一个15MHz的CAN时钟 (150/10=15)
ECanbShadow.CANBTC.bit.TSEG2REG = 5; // 位定时 bit-time=(TSEG1+1)+(TSEG1 +1)+1
ECanbShadow.CANBTC.bit.TSEG1REG = 7; // Bit time = 15
ECanbRegs.CANBTC.all = ECanbShadow.CANBTC.all;
ECanbShadow.CANMC.all = ECanbRegs.CANMC.all;
ECanbShadow.CANMC.bit.CCR = 0;
ECanbRegs.CANMC.all = ECanbShadow.CANMC.all;
EDIS;
// 等到CPU不再有权更改配置寄存器
do
{
ECanbShadow.CANES.all = ECanbRegs.CANES.all;
} while(ECanbShadow.CANES.bit.CCE != 0 );
// 将eCAN配置为自检模式
// 启用eCAN的增强功能。
EALLOW;
ECanbShadow.CANMC.all = ECanbRegs.CANMC.all;
ECanbShadow.CANMC.bit.STM = 1; // 将CAN配置为自检模式。在这种模式下,CAN模块能够产生它自己的应答信号(ACK),从而允许在没有总线连接到模块的情况下进行操作。
ECanbShadow.CANMC.bit.SCB = 1; // SCC兼容性位:选择eCAN模式(需要访问32个邮箱)
ECanbRegs.CANMC.all = ECanbShadow.CANMC.all;
EDIS;
// 开始传输
for(;;)
{
ECanbRegs.CANTRS.all = 0x0000FFFF; // 为所有传输邮箱设置TRS。发送请求置位寄存器:置位为1,启动发送。
while(ECanbRegs.CANTA.all != 0x0000FFFF ) {} // 等待所有的TAn位被设置。发送应答寄存器:如果邮箱n的消息被成功发送,该寄存器的第n位置位。
ECanbRegs.CANTA.all = 0x0000FFFF; // 写1清零,准备判别下一次发送与否
MessageReceivedCount++;
//从接收邮箱中读取并开始检查数据
for(j=0; j<16; j++) // 阅读并检查16个邮箱
{
mailbox_read(j); // 这个函数读取指示的邮箱数据
mailbox_check(TestMbox1,TestMbox2,TestMbox3); // 检查收到的数据
}
if(MessageReceivedCount > 100)
{
if(ErrorCount == 0)
{
asm(\" }
else
{
asm(\" }
}
}
); // OK
); // ERROR
ESTOP0\" ESTOP0\"
}
// 该功能读出邮箱号码(MBXnbr)所指示的内容。
void mailbox_read(int16 MBXnbr)
{
volatile struct MBOX *Mailbox;
Mailbox = &ECanbMboxes.MBOX0 + MBXnbr;
TestMbox1 = Mailbox->MDL.all; // = 0x9555AAAn (n is the MBX number)
TestMbox2 = Mailbox->MDH.all; // = 0xABCDEF (a constant)
TestMbox3 = Mailbox->MSGID.all;// = 0x9555AAAn (n is the MBX number)
} // 接受邮箱MBX的MSGID作为MDL数据传输
void mailbox_check(int32 T1, int32 T2, int32 T3)
{
if((T1 != T3) || ( T2 != 0xABCDEF))
{
ErrorCount++;
}
else
{
PassCount++;
}
}
//===========================================================================
// No more.
//================================================
===========================
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- niushuan.com 版权所有 赣ICP备2024042780号-2
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务