主题中讨论的其他部件:C2000WARE
工具/软件:Code Composer Studio
您好,
我正在尝试通过CAN在2个微控制器2.8035万和2.8075万之间进行通信。 我是CAN通信的新手,我看到2.8035万有eCAN,2.8075万有CAN。 我尝试了两个2.8035万处理器之间的通信,它的工作原理与gem类似,但当我尝试在2.8035万和2.8075万之间通信时,我是否应该在2.8075万中配置邮箱ID?如果是,如何配置?
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
工具/软件:Code Composer Studio
您好,
我正在尝试通过CAN在2个微控制器2.8035万和2.8075万之间进行通信。 我是CAN通信的新手,我看到2.8035万有eCAN,2.8075万有CAN。 我尝试了两个2.8035万处理器之间的通信,它的工作原理与gem类似,但当我尝试在2.8035万和2.8075万之间通信时,我是否应该在2.8075万中配置邮箱ID?如果是,如何配置?
您好,Chris:
我向这两个发送相同的ID,我写了类似这样的消息。
在2.8035万中
void main (void)
{
UINT16 j;
InitSysCtrl();
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectorTable();
MessageReceivedCount =0;
ErrorCount = 0;
PassCount = 0;
InitECanGpio();
InitECana();//初始化eCAAN-A模块
ECanaMboxes.MBOX0.MSGID.ALL = 0x9555AAA0;
ECanaMboxes.MBOX1.MSGID.ALL = 0x9555AAA1;
ECanaMboxes.MBOX2.MSGID.ALL = 0x9555AAA2;
ECanaMboxes.MBOX3.MSGID.ALL = 0x9555AAA3;
ECanaMMboxes.MBOX4.MSGID.ALL = 0x9555AAA4;
ECanaMboxes.MBOX5.MSGID.ALL = 0x9555AAA5;
ECanaMbboxes.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;
ECanaMbboxes.MBOX12.MSGID.ALL = 0x9555AAAC;
ECanaMbboxes.MBOX13.MSGID.ALL = 0x9555AAAD;
ECanaMbboxes.MBOX14.MSGID.ALL = 0x9555AAAE;
ECanaMboxes.MBOX15.MSGID.ALL = 0x9555AAAF;
//写入接收邮箱MBOX16 -31的MSGID字段
ECanaMMboxes.MBOX16.MSGID.ALL = 0x9555AAA1;//正在接收邮箱位31,30,29用于配置。因此,邮件ID为1555AAA1
ECanaMbboxes.MBOX17.MSGID.ALL = 0x9555AAA1;
ECanaMboxes.MBOX18.MSGID.ALL = 0x9555AAA2;
ECanaMMboxes.MBOX19.MSGID.ALL = 0x9555AAA3;
ECanaMboxes.MBOX20.MSGID.ALL = 0x9555AAA4;
ECanaMMboxes.MBOX21.MSGID.ALL = 0x9555AAA5;
ECanaMbboxes.MBOX22.MSGID.ALL = 0x9555AAA6;
ECanaMMboxes.MBOX23.MSGID.ALL = 0x9555AAA7;
ECanaMboxes.MBOX24.MSGID.ALL = 0x9555AAA8;
ECanaMboxes.MBOX25.MSGID.ALL = 0x9555AAA9;
ECanaMbboxes.MBOX26.MSGID.ALL = 0x9555AAAA;
ECanaMbboxes.MBOX27.MSGID.ALL = 0x9555AAAB;
ECanaMbboxes.MBOX28.MSGID.ALL = 0x9555AAAC;
ECanaMbboxes.MBOX29.MSGID.ALL = 0x9555AAAD;
ECanaMbboxes.MBOX30.MSGID.ALL = 0x9555AAAE;
ECanaMMboxes.MBOX31.MSGID.ALL = 0x9555AAAF;
//将邮箱0-15配置为Tx,将16-31配置为Rx
//因为此写入是到整个寄存器(而不是位
//字段)不需要影子寄存器。
ECanaRegs.CANMD.ALL = 0xFFFF0000;
//启用所有邮箱*/
//因为此写入是到整个寄存器(而不是位
//字段)不需要影子寄存器。
ECanaRegs.CANME.ALL = 0xFFFFFFFF;
//指定将发送/接收8位
ECanaMcboxes.MBOX0.MSGCTRL.bit.DLC = 8;
//因为此写入是到整个寄存器(而不是位
//字段)不需要影子寄存器。
EALLOW;
ECanaRegs.CANMIM.ALL = 0xFFFFFFFF;
//将eCAN配置为自检模式
//启用eCAN的增强功能。
GpioCtrlRegs.GPAPUD.bit.GPIO20 = 0;//在GPIO6上启用上拉
GpioDataRegs.GPACLEAR.bit.GPIO20 = 1;//加载输出锁存器
GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 0;// GPIO6 = GPIO6
gpioCtrlRegs.GPADIR.bit.GPIO20 = 1;// GPIO6 =输出
//开始传输
对于(;;)
{
while (ECanaRegs.CANRMP.bit.RMP15!=1){}//等待设置所有RMPn位。
ECanaRegs.CANRMP.bit.RMP15 = 1;//清除所有RMPn
mailbox_read(16);
}
}//
此函数通过
邮箱号(MBXnbr)读取指定//的内容。
void mailbox_read(Int16 MBXnbr)
{
volatile struct MBOX *邮箱;
Mailbox =&ECanaMboxes.MBOX0 + MBXnbr;
TestMbox1 = Mailbox->MDL.all;//= 0x9555AAXx
=邮箱数MDSx2=全部MMDbon //= 0x89ABCDEF (A常量)
TestMbox3 = Mailbox->MSGID.ALL;//= 0x9555AAAn (n是MBX编号)
}// rcv MBX的MSGID作为MDL数据传输。
void mailbox_check(Int32 T1, Int32 T2, Int32 T3)
{
IF ((T1 != T3)||(T2 != 0x89ABCDEF))
{
ErrorCount++;
}
否则
{
PassCount++;}
}
在2.8075万中
void main (void)
{
////
初始化系统控制:
// PLL,看门狗,启用外设时钟
//
InitSysCtrl();
////
为
模块A和B上的CANTX/CANRX //初始化GPIO引脚并配置GPIO引脚
//
InitGPIO();
////
为CAN-A TX/RX和CAN-X_MU1设置GPIO引脚m/
MR/MU1;// //GPIO30 - CANRXA
GPIO_SetupPinOptions (70,GPIO输入,GPIO _异步);
GPIO_SetupPinMux (71,GPIO _MUX_CPU1, 5);//GPIO31 - CANTXA
GPIO设置引脚选项(71,GPIO输出,GPIO推送);
// GPIO设置引脚Mux (13,GPIO _MUX_CPU1, 2);//GPIO10 - CANRXB
// gPIO_SetupPinOptions (13,gPIO_INPUT,gPIO_Async);
// gPIO_SetupPinMux (12,gPIO_MUX_CPU1, 2);//GPIO8 - CANTXB
// gPIO_SetupPinOptions (12,gPIO_OUTPUT,gPIO_PushPull);
////
初始化CAN控制器
//
CANInit (Cana_base);
// CANInit (CANB_BASE);
////
设置可从PLL输出时钟//
CANClkkHz
,CANB_Source0,选择CANB_0 // 500kHz CAN时钟
////
为每个模块将CAN总线比特率设置为500kHz
//此功能为标称配置设置CAN总线定时。
//如果
需要,您可以使用//功能CANBitTimingSet()代替这一功能来实现对CAN总线定时的更多控制。
//此外,有关
// CAN模块时钟的更多信息,请参阅设备数据表。
//
CANBitRateSet (Cana_base,2000万0,50万);
// CANBitRateSet (CANB_BASE,2亿, 50万);
//
//在CAN B外围设备上启用中断。
//
//// CANIntEnable (CANB_BASE,CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
////
清除所有中断并初始化PIE矢量表:
//禁用CPU中断
//
DINT;
////
将PIE控制寄存器初始化到其默认状态。
//默认状态是禁用所有PIE中断,
并清除标志//。
//
InitPieCtrl();
////
禁用CPU中断并清除所有CPU中断标志
//
IER = 0x0000;
IFR = 0x0000;
////
初始化PIE矢量表,其中包含指向shell Interrupt
//服务例程(ISR)的指针。
//这将填充整个表,即使在此
示例中未使用中断//。 这对于调试非常有用。
//
InitPieVectorTable();
////
本示例中使用的中断被重新映射到此
文件中找到的// ISR函数。
//这将在PIE矢量表中注册中断处理程序。
//
// EALLOW;
// PieVectorTable.CANB0_INT = canbISR;
// EDIS;
////
在处理器上启用CAN-B中断(PIE)。
//
//// PieCtrlRegs.PIEIER9.bit.INTx7 = 1;
// IER |= M_INT9;
// EINT;
////
启用CAN-B中断信号
////
CANGlobalIntEnable (CANB_Base,CAN_GLB_INT_CANINT0);
////
初始化用于发送消息的传输对象CAN发送消息。
//消息对象参数:
//消息标识符:0x5555
//消息ID掩码:0x0
//消息对象标志:无
//消息数据长度:4字节
//消息传输数据:txgData
//
sTXCANMessage.ui32MsgID = 0x1555TXA0;
sTXCANMessage.ui32MsgIDMask = 0;sTXgMsg_CAUgMessage
=消息
=
//
//初始化要发送的传输消息对象数据缓冲区
//
txMsgData[0]= 0x1A;
txMsgData[1]= 0xA4;
txMsgData[2]= 0x5A;
txMsgData[3]= 0xA8;
//
//启动CAN模块A和B操作
//
CANEnable(Cana_base);
// CANB_Base;
//
//将消息从CAN-A传输到CAN-B
//
while (1)
{////
查看错误标志是否发生
//
if (errorFlag)
{
ASM ("ESTOP0");
}
CANMessageSet (Cana_base,TX_OBJ_MSG_ID,&sTXCANMessage,
MSG_OBJ_TYPE_TX);
int i;
for (i=0;i<1万;i++);
for (i=0;i<1万;i++);
for (i=0;i<1万;i++);
for (i=0;i<1万;i++);
对于(i=0;i<1万;i+);
对于(i=0;i<1万;i+);
对于(i=0;i<1万;i+);
对于(i=0;i<1万;i+);}////
停止应用
程序//
ASM("ESTOP0");对于(i=0;i<1万;i+);对于(i<1万;i++);}}}///停止应用程序//停止应用程序// ASM ("ESTOP0"?ISR("ESTOP0");中断
///
中断时,可以调用B;
中断_ISR_Ub_INV;中断时,可以调用B
=中断
//
//读取CAN-B中断状态以查找中断原因
//
状态= CANIntStatus (CANB_BASE,CAN_INT_STS_CAUSE);
////
如果原因是控制器状态中断,则获取状态
//
if (status == CAN_INT_INT0ID_STATUS)
{
////
读取控制器状态。 这将返回状态
//错误位的字段,该字段可以指示各种错误。 为了
简单起见,本示例中不执行错误处理//。 有关
错误状态位的详细信息,请参阅// API文档。
//读取此状态的操作将清除中断。
//
status = CANStatusGet (CANB_BASE,CAN_STS_CONTROL);
////
检查是否发生错误。
//
if (((status &~(CAN_ES_RXOK))!= 7)&&
(status &~(CAN_ES_RXOK))!= 0)
){
////
设置一个标志以指示可能发生的某些错误。
//
errorFlag =1;
}////
检查原因是否为CAN-B接收消息对象1//
否则,如果(status == RX_MSG_OBJ_ID)
{////
获取收到的消息
//
CANMessageGet(CANB_BASE,RX_MSG_OBJ_ID,&sRXCANMessage, TRUE);
////
达到此点意味着RX中断发生在
//消息对象1上,并且消息RX已完成。 清除
//消息对象中断。
//
CANIntClear (CANB_BASE,RX_MSG_OBJ_ID);
////
递增计数器以跟踪
收到的消息数量。 在实际应用程序中,这可用于将标志设置为
//指示何时收到邮件。
//
rxMsgCount+;////
自收到消息以来,清除所有错误标志。
//
errorFlag =0;
}////
如果中断是由意外引起的,此操作将处理中断。
//
否则
{////
寄生中断处理可以在此处进行。
//
}////
清除CAN中断行的全局中断标志
//
CANGlobalIntClear (CANB_Base,CAN_GLB_INT_CANINT0);
////
确认位于组9中的此中断
//
PieCtrlRegs.PIEACK/ALL = PIEACK_group9;
}
您能看到什么是错误吗?
Lakshmi,
由于您在两端都使用的是精确的MSGID,因此调试应该非常简单。 请仔细查看我的(修订版) app.note SPRA876B中的调试提示。 我相信你一定能够解决这个问题。 快速提示:
确保在2.8035万端启用了到eCAN的时钟,并且MSGID正确地写入了接收MBX中。 使用CCS进行验证。
确保两个模块配置为相同的比特率。
探测2.8035万侧的CANRX引脚,确保在该引脚上实际收到您的消息。 如果可能,请附上示波器截图。 如果您的示波器能够解码CAN消息,请附加示波器图解的缩放版本,以清楚地显示MSGID。