主题中讨论的其他器件:C2000WARE
大家好,
任何人帮助我在 CAN 接口,我做了初始化与示例代码 bitfield 可以并尝试回送,在回送它的工作完美,并进入中断也,但一旦我删除回送模式,意味着回送模式是0和测试寄存器也是0。 然后它停止工作,它将不会进行 CAN 中断,任何人请引导我,并更多的说明使用 GPIO 32和 GPIO 33 ,所以任何细节规范需要在这些 GPIO 初始化作为 CAN TX 和 CANRX
。
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.
大家好,
任何人帮助我在 CAN 接口,我做了初始化与示例代码 bitfield 可以并尝试回送,在回送它的工作完美,并进入中断也,但一旦我删除回送模式,意味着回送模式是0和测试寄存器也是0。 然后它停止工作,它将不会进行 CAN 中断,任何人请引导我,并更多的说明使用 GPIO 32和 GPIO 33 ,所以任何细节规范需要在这些 GPIO 初始化作为 CAN TX 和 CANRX
。
大家好,Sahil,
所有与 CAN 相关的硬件都已在板上添加 ,但不会发生 CAN 中断,请参考 以下配置
GPIO_SetupPinMux (32、GPIO_MUX_CPU1、10);
GPIO_SetupPinOptions (32、GPIO_output、GPIO_PushPull);
GPIO_SetupPinMux (33、GPIO_MUX_CPU1、10);
GPIO_SetupPinOptions (33、GPIO_output、GPIO_ASYNC);
空 InitCAN (空)
{
ClkCfgRegs.CLKSRCCTL2.bit.CANABCLKSEL = 0;
int16_t iMsg;
//
//将 CAN 控制器置于初始化状态,而不考虑之前的状态。 这个
//将控制器置于空闲状态,并允许消息对象 RAM
//已编程。
//
CanaRegs.CAN_CTL.bit.Init = 1;
CanaRegs.CAN_CTL.bit.SWR = 1;
//
//等待 BUSY 位清零
//
while (CanaRegs.CAN_IF1CMD.bit.BUSY)
{
}
//
//将仲裁寄存器中的报文值位清零 这表明
//消息无效,是离开消息的"安全"条件
//对象。 相同的 ARB 寄存器用于对所有消息对象进行编程。
//
CanaRegs.CAN_IF1CMD.bit.DIR = 1;
CanaRegs.CAN_IF1CMD.bit.ARB = 1;
CanaRegs.CAN_IF1CMD.bit.Control = 1;
CanaRegs.CAN_IF1ARB.all = 0;
CanaRegs.CAN_IF1MCTL.ALL = 0;
CanaRegs.CAN_CTL.bit.DAR = 1;
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;
CanaRegs.CAN_CTL.bit.ABO = 1;
CanaRegs.CAN_ABOTR = 0x02;
//循环遍历所有的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;
}
//
//确认任何挂起的状态中断。
//
易失性 uint32_t 丢弃 Read = CanaRegs.CAN_ES.all;
}
uint32_t status = setCANBitRate (100000,000,500000);
uint32_t setCANBitRate (uint32_t sourceClock、uint32_t bitrate)
{
uint32_t 设计速率;
uint32_t canBits;
uint32_t predivide;
uint32_t regValue;
uint16_t canControlValue;
//
//计算所需的时钟速率。
//
desedRatio =源时钟/比特率;
//
//确保所需的比率不会过大。 这将强制
//要求比特率大于请求的值。
//
if (((sourceClock / desiredRatio)> bitrate)
{
所需比率+=1;
}
//
//检查所有可能的值以查找匹配值。
//
while (desedRatio <= CAN_MAX_PRE_DIVENCH * CAN_MAX_BIT_DIVENCH)
{
//
//循环通过所有可能的 CAN 位分频。
//
for (canBits = CAN_MAX_bit_division;
canBits >= can_min_bit_division;
canBits--)
{
//
//对于给定的 CAN 位分频值,保存预分频值。
//
PreDivide = desiredRatio / canBits;
//
//如果计算出的分频值与所需的时钟比率相匹配,则
//返回这些比特率并设置 CAN 位时序。
//
if ((predivide * canBits)= desiredRatio)
{
//
//通过添加位定时开始构建位定时值
//时间份额。
//
regValue = canBitValues[canBits - CAN_MIN_BIT_DIVIDENS];
//
//要设置位定时寄存器,必须将控制器设置为
//已放置
//在初始化模式中(如果尚未),以及配置更改
//位被启用。 则应将寄存器的状态保存到
//这样就可以恢复它。
//
canControlValue = CanaRegs.CAN_CTL.all;
CanaRegs.CAN_CTL.bit.Init = 1;
CanaRegs.CAN_CTL.bit.CCE = 1;
//
//现在添加位速率的预分频。
//
regValue |=((predivide - 1)和 CAN_BTR_BRP_M)|
(((PreDivide - 1)<< 10)& CAN_BTR_BRPE_M);
//
//设置中的时钟位以及
//预分频。
//
CanaRegs.CAN_BTR.all = regValue;
//
//恢复保存的 CAN 控制寄存器。
//
CanaRegs.CAN_CTL.all = canControlValue;
//
//返回计算出的比特率。
//
return (sourceClock /(predivide * canBits);
}
}
//
//将分频值向上移动一个,然后再次查看。 只有在极少数情况下
//需要2个以上的循环来查找值。
//
desiredRatio++;
}
返回0;
}
//
// setupMessageObject -将消息对象设置为发送或接收
//
void setupMessageObject (uint32_t Objid、uint32_t msgid、msgObjType msgType、int16_t msgEnableInterrupt)
{
//
//等待 BUSY 位清零
//
while (CanaRegs.CAN_IF1CMD.bit.BUSY)
{
}
//
//清除并写入寄存器以对报文对象进行编程。
//
CanaRegs.CAN_IF1CMD.all = 0;
CanaRegs.CAN_IF1MSK.all = 0;
CanaRegs.CAN_IF1ARB.all = 0;
CanaRegs.CAN_IF1MCTL.ALL = 0;
//
//设置 Control、Mask 和 ARB 位,以便将其传输到
//消息对象。
//
CanaRegs.CAN_IF1CMD.bit.Control = 1;
CanaRegs.CAN_IF1CMD.bit.ARB = 1;
CanaRegs.CAN_IF1CMD.bit.Mask = 1;
CanaRegs.CAN_IF1CMD.bit.DIR = 1;
//
//设置发送方向
//
if (msgType == MSG_OBJ_TYPE_TRANSMIT_REMOTE)
{
CanaRegs.CAN_IF1ARB.bit.Dir = 0;
CanaRegs.CAN_IF1MCTL.bit.TxRqst =1;
}
if (msgType == MSG_OBJ_TYPE_RECEIVE)
{
CanaRegs.CAN_IF1ARB.bit.Dir = 0;
CanaRegs.CAN_IF1MCTL.bit.TxRqst =0;
}
if (msgType == MSG_OBJ_TYPE_RxTx_REMOTE)
{
CanaRegs.CAN_IF1ARB.bit.Dir = 1;
CanaRegs.CAN_IF1ARB.bit.XTD = 0;
CanaRegs.CAN_IF1MCTL.bit.RmtEn =1;
CanaRegs.CAN_IF1MCTL.bit.umask =1;
CanaRegs.CAN_IF1MSK.bit.MDir = 1;
CanaRegs.CAN_IF1MSK.bit.MXtd =0;
CanaRegs.CAN_IF1MSK.bit.MSK = 0x1FFFFFFF;//msgid;
}
if (msgEnableInterrupt == Enable_Rxinterrupt)
{
CanaRegs.CAN_IF1MCTL.bit.RxIE =1;
CanaRegs.CAN_CTL.bit.IE0 =1;
CanaRegs.CAN_GLB_INT_EN.bit.GLBINT0_EN =1;
}
//
//设置消息 ID (此示例假定11位 ID 掩码)
CanaRegs.CAN_IF1ARB.bit.ID = msgid;
CanaRegs.CAN_IF1ARB.bit.MsgVal = 1;
//
//设置数据长度,因为这是针对所有传输设置的。 这是
//同时也是单次传输而不是 FIFO 传输,因此应设置 EOB 位。
//
CanaRegs.CAN_IF1MCTL.bit.DLC = messageSize;
CanaRegs.CAN_IF1MCTL.bit.EOB = 1;
//将数据传输到消息对象 RAM
CanaRegs.CAN_IF1CMD.bit.MSG_NUM = Objid;
}
Sanmati,
使用位字段而不使用 Driverlib 是有原因的吗? 请注意、弃用了对位字段的支持、以后将只支持/更新 Driverlib。
我强烈建议您查看 SPRACE5A 中的调试提示。 并在您的硬件上尝试使用 C2000ware Driverlib 示例。 由于这些都是经过测试的示例、因此您可以使用它们来确定 H/W 中是否存在任何问题。 确定您是硬件问题还是软件问题非常重要。
Sanmati,
在 setupMessageObject 函数中、需要注意的一点是、IF1CMD 应以单个32位写入的方式写入。 这是因为、在对该寄存器进行写操作后、BUSY 位置位、使得从 IFx 寄存器到报文 RAM 的数据传输需要特定数量的周期。
特别是在下面提到的情况中、这可能会导致错误写入。
但是、可以定义影子变量、将所有值输入到影子变量中、并且可以在32位单次写入中写入、如下所示:
谢谢。
大家好,Sahil,
我们也已尝试过此功能,如果需要更改,请返回以下配置。
void setupMessageObject (uint32_t Objid、uint32_t msgid、msgObjType msgType、int16_t msgEnableInterrupt)
{
联合 CAN_IF1CMD_REG CAN_IF1CMD_shadow;
//
//等待 BUSY 位清零
//
while (CanaRegs.CAN_IF1CMD.bit.BUSY)
{
}
//
//清除并写入寄存器以对报文对象进行编程。
//
CAN_IF1CMD_shadow.all = 0;
CanaRegs.CAN_IF1CMD.all = 0;
CanaRegs.CAN_IF1MSK.all = 0;
CanaRegs.CAN_IF1ARB.all = 0;
CanaRegs.CAN_IF1MCTL.ALL = 0;
//
//设置 Control、Mask 和 ARB 位,以便将其传输到
//消息对象。
//
CAN_IF1CMD_shadow.bit.Control = 1;
can_IF1CMD_shadow.bit.arb = 1;
CAN_IF1CMD_shadow.bit.Mask = 1;
CAN_IF1CMD_SHADD.bit.DIR = 1;
// CanaRegs.CAN_IF1CMD.bit.Control = 1;
// CanaRegs.CAN_IF1CMD.bit.ARB = 1;
// CanaRegs.CAN_IF1CMD.bit.Mask = 1;
// CanaRegs.CAN_IF1CMD.bit.DIR = 1;
//
//设置发送方向
//
if (msgType == MSG_OBJ_TYPE_TRANSMIT)
{
CanaRegs.CAN_IF1ARB.bit.Dir = 1;
}
if (msgType == MSG_OBJ_TYPE_TRANSMIT_REMOTE)
{
CanaRegs.CAN_IF1ARB.bit.Dir = 0;
CanaRegs.CAN_IF1MCTL.bit.TxRqst =1;
}
if (msgType == MSG_OBJ_TYPE_RECEIVE)
{
CanaRegs.CAN_IF1ARB.bit.Dir = 0;
CanaRegs.CAN_IF1MCTL.bit.TxRqst =0;
}
if (msgType == MSG_OBJ_TYPE_RxTx_REMOTE)
{
CanaRegs.CAN_IF1ARB.bit.Dir = 1;
CanaRegs.CAN_IF1ARB.bit.XTD = 0;
CanaRegs.CAN_IF1MCTL.bit.RmtEn =1;
CanaRegs.CAN_IF1MCTL.bit.umask =1;
CanaRegs.CAN_IF1MSK.bit.MDir = 1;
CanaRegs.CAN_IF1MSK.bit.MXtd =0;
CanaRegs.CAN_IF1MSK.bit.MSK = 0x1FFFFFFF;//msgid;
}
if (msgEnableInterrupt == Enable_Rxinterrupt)
{
CanaRegs.CAN_IF1MCTL.bit.RxIE =1;
CanaRegs.CAN_CTL.bit.IE0 =1;
CanaRegs.CAN_GLB_INT_EN.bit.GLBINT0_EN =1;
CanaRegs.CAN_CTL.bit.EIE = 1;
CanaRegs.CAN_CTL.bit.SIE =1;// 3错误中断启用
}
否则
{
CanaRegs.CAN_IF1MCTL.bit.RxIE =0;
CanaRegs.CAN_CTL.bit.IE0 = 0;
CanaRegs.CAN_CTL.bit.EIE = 0;
CanaRegs.CAN_CTL.bit.SIE =0;// 3错误中断启用
CanaRegs.CAN_GLB_INT_EN.bit.GLBINT0_EN =0;
}
//
//设置消息 ID (此示例假定11位 ID 掩码)
//
CanaRegs.CAN_IF1ARB.bit.ID = msgid;
CanaRegs.CAN_IF1ARB.bit.MsgVal = 1;
//
//设置数据长度,因为这是针对所有传输设置的。 这是
//同时也是单次传输而不是 FIFO 传输,因此应设置 EOB 位。
//
CanaRegs.CAN_IF1MCTL.bit.DLC = messageSize;
CanaRegs.CAN_IF1MCTL.bit.EOB = 1;
//
//将数据传输到消息对象 RAM
//
CAN_IF1CMD_SHADD.bit.MSG_NUM = Objid;
CanaRegs.CAN_IF1CMD.all = CAN_IF1CMD_shadow.all;
谢谢。