主题:C2000WARE 中讨论的其他器件
工具/软件:
大家好!
我在这里分享了我在处理 canbus TX 中断时遇到的一个问题。
我正在使用 F280025C Launchpad、它具有一个 CAN 总线通道 CANA 及其两个可能的中断线路 (CANINT0 和 CANINT1)。
我设置外设和中断表、以便触发:
Rx - CANINT0
TX—CANINT1
此外、关于接口寄存器、我选择使用 IF1 进行数据发送、使用 IF2 进行接收。
我同时启用了 TxIE、RxIE 位文件和 CANbus 的全局中断线路。
关于接收中断一切工作正常,当我尝试发送 CANbus 消息时,传输总是失败(我一直使用 CAN 分析仪作为其他节点)。
从字面上说、就好像什么都没有发生。
之后、我尝试从代码中排除 Rx 中断(第 0 行)并侧重于仅 Tx(第 1 行)。
通过调试 CANbus 寄存器本身、我可以看到一个非常奇怪的事情:触发的传输线为 0(应该从设置中链接到 Rx)。
我不知道为什么。
然后、另一个非常奇怪的事情是 IPEN_21 寄存器标识了正确的消息对象、TxOk 位为高电平、LEC 1 不显示任何警告。
在这种情况下、会生成 TX 中断、但无法通过常规方式 (IntClrPnd = 1) 清除它。 实际上、TX 中断是 永无休止地进入的。
为什么就在我 排除 Rx 时触发 Tx 中断?
有人能帮我解决这个问题吗?
我附加了一些我一直在写的代码、希望它有助于捕捉问题。
请告诉我:)
Elia
=======================================
PIE SETUP
=======================================
EALLOW;
PieVectTable.CANA0_INT =&cana_rx_ISR;
PieVectTable.CANA1_INT =&cana_TX_ISR;
PieCtrlRegs.PIEIER9.bit.INTx6 = 1;
PieCtrlRegs.PIEIER9.bit.INTx5 = 1;
//PieCtrlRegs.PIEIER9.bit.INTx6 = 1;
IER |= M_INT9;
EDIS;
=======================================
初始化
=======================================
void InitCAN (void)
{
int16_t iMsg;
//
//将 CAN 控制器置于初始化状态、无论先前的状态如何。 减少
//将使控制器处于空闲状态、并允许消息对象 RAM 处于空闲状态
//已编程。
//
CanaRegs.can_CTL.bit.Init = 1;
CanaRegs.CAN_CTL.bit.CCE = 1;
CanarRegs.can_CTL.bit.SWR = 1;//软件复位 (si attiva solo se Init è settato)
//
//等待 BUSY 位清除
//
while (canRegs.can_IF1CMD.bit.busy)// c'μ s un trasferrimento in corso tra è 寄存器 e la ram
{
}
//
//清除仲裁寄存器中的消息值位。 这一指示
//消息无效、是离开消息的“安全“条件
//对象。 同一 ARB reg 用于对所有消息对象进行编程。
//
CanaRegs.can_IF1CMD.bit.DIR = 1;// 0 读、1 写:0 legge dalla 邮箱 verso l'interface 寄存器、反之亦然
CanaRegs.can_IF1CMD.bit.arb = 1;//仲裁位(标识符+ Dir + XTD + MsgVal)传输位 if -> Mailbox (se write、反之亦然、se read)
CanaRegs.can_IF1CMD.bit.Control = 1;//控制位出现 sopra
CanaRegs.can_IF1ARB.all = 0;
CanaRegs.can_IF1MCTL.all = 0;
CanaRegs.CAN_IF2CMD.bit.DIR = 1;
CanaRegs.can_IF2CMD.bit.arb = 1;
CanaRegs.CAN_IF2CMD.bit.Control = 1;
CanaRegs.can_IF2ARB.all = 0;
CanaRegs.can_IF2MCTL.all = 0;
//
//循环以对所有 32 个消息对象进行编程
//
For (iMsg = 1;iMsg <= 32;iMsg +=2)
{
//
//等待 BUSY 位清除
//
while (CanaRegs.can_IF1CMD.bit.busy)
{
}
//
//启动消息对象编程
//
CanaRegs.CAN_IF1CMD.bit.MSG_NUM = iMsg;
//
//等待 BUSY 位清除
//
while (CanaRegs.can_IF2CMD.bit.busy)
{
}
//
//启动消息对象编程
//
CanaRegs.CAN_IF2CMD.bit.MSG_NUM = iMsg + 1;
}
CanaRegs.CAN_IF1CMD.bit.DATA_A = 1;
CanaRegs.CAN_IF1CMD.bit.DATA_B = 1;
CanaRegs.CAN_IF2CMD.bit.DATA_A = 1;
CanaRegs.CAN_IF2CMD.bit.DATA_B = 1;
//
//确认任何挂起的状态中断。
//
易失性 uint32_t 丢弃读取= CanaRegs.CAN_ES.all;//错误和状态寄存器
}
=======================================
CAN ENABLE
=======================================
Void CAN_Enable (void){
//
//启用 CAN 以运行。
//
CanaRegs.can_CTL.bit.DAR = 1;//禁用自动重新传输
CanaRegs.can_CTL.bit.Test = 0;//启用测试模式并选择外部环回
CanaRegs.can_test.bit.exl = 0;//外部环回
CanarRegs.can_CTL.bit.IE0 = 1;// Abilito 中断
CanaRegs.CAN_GLB_INT_EN.bit.GLBINT0_EN = 1;
CanaRegs.can_CTL.bit.IE1 = 1;
CanaRegs.can_GLB_INT_EN.bit.GLBINT1_EN = 1;
Canares.can_CTL.bit.Init = 0;//启用 CAN 以进行操作 (0 个处理 i messaggi normalmente)
}
=======================================
Tx 邮箱设置
=======================================
void can_objid (uint32_t Mailbox_Setup_、uint32_t msgid、uint16_t DLC)
{
//
//为 IF1CMD 使用 Shadow 变量。 IF1CMD 应写入中
//单个 32 位写入。
//
UNION CAN_IF1CMD_REG CAN_IF1CMD_SHADOW;
//
//等待 BUSY 位清除。
//
while (CanaRegs.can_IF1CMD.bit.busy)
{
}
//
//清除和写入寄存器以对消息对象进行编程。
//
CAN_IF1CMD_SHADOL.ALL = 0;
CanaRegs.can_IF1Msk.all = 0;
CanaRegs.can_IF1ARB.all = 0;
CanaRegs.can_IF1MCTL.all = 0;
//
//设置控制位、遮罩位和 ARB 位、以便将其传输到
//消息对象。
//
CAN_IF1CMD_Shadow.bit.Control = 1;
CAN_IF1CMD_SHADOL.BIT.ARB = 1;
CAN_IF1CMD_Shadow.bit.Mask = 1;
CAN_IF1CMD_Shadow.bit.DIR = 1;
CanaRegs.can_IF1ARB.bit.Dir = 1;// se non lo forzo ad 1 manda un messaggio vuoto(远程帧 RTR)
CanaRegs.CAN_IF1MCTL.bit.TxIE = 1;
//
//设置消息 ID(本示例假设 ID 掩码为 11 位)
//
CanaRegs.CAN_IF1ARB.bit.ID =(msgid << CAN_MSG_ID_SHIFT);
CanaRegs.can_IF1ARB.bit.MsgVal = 1;
//
//为所有传输设置数据长度。 这是
//也是单次传输而不是 FIFO 传输、因此设置 EOB 位。
//
CanaRegs.can_IF1MCTL.bit.DLC = DLC;
CanaRegs.can_IF1MCTL.bit.EOB = 1;
//
//将数据传输到消息对象 RAM
//
CAN_IF1CMD_SHADOL.BIT.MSG_NUM = Objid;
CanaRegs.CAN_IF1CMD.ALL = CAN_IF1CMD_SHADOL.ALL;
}
=======================================
Tx 中断处理
=======================================
// devo riuscire a farlo funzionare!
__ interrupt void cana_TX_ISR (void){
dbg.can_tx++;
#if 0
while(!CanaRegs.can_es.bit.TxOk){
}
#endif
#if 0
if(!CanaRegs.can_es.bit.TxOk){
CanaRegs.can_es.bit.TxOk = 0;
GpioDataRegs.GPATOGGLE.bit.GPIO31 = 1;
Comando_feeder = 0;
}
#endif
if ((CanaRegs.CAN_IPEN_21 &&(1 <<(CAN_TX_LOCK-1)))&&(CanaRegs.CAN_INT.bit.INT1ID == CAN_TX_LOCK)){
GpioDataRegs.GPATOGGLE.bit.GPIO31 = 1;
CanaRegs.CAN_IF1CMD.bit.ClrIntPnd = 1;
}
//volatile uint32_t status = CanaRegs.CAN_ES.all;//错误和状态寄存器
CanaRegs.CAN_GLB_INT_CLR.bit.IN1_FLG_CLR = 1;
PieCtrlRegs.PIEACK.bit.ACK9 = 1;
}