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.

[参考译文] TMS320F28377S:将 ECAN 从 F28335移植到 F28377S 上的 DCAN - CAN#39;t transmit

Guru**** 2348500 points
Other Parts Discussed in Thread: C2000WARE
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/672367/tms320f28377s-porting-ecan-from-f28335-to-dcan-on-f28377s---can-t-transmit

器件型号:TMS320F28377S
主题中讨论的其他器件:C2000WARE

您好-

我最终获得了硬件、并尝试启动和运行 CAN 通信。  F28377S 可以接收 CAN 数据包。  我在 CCS 调试器中看到它们进入我的应用。  我无法使传输正常工作。  我将数据加载到接口中-我看到了这一点、但消息不会进入 RAM。  我在范围内看不到任何活动。   

我的问题可能是仲裁或屏蔽寄存器。  对于接收、我设置了仲裁接受和屏蔽寄存器、这似乎是有效的。  我也尝试过在传输端这样做-没有乐趣。  此外、我只尝试使用 TX 的仲裁寄存器-同样、没有乐趣。   

如果有一些见解、我将不胜感激。  随附了我的335和377S 代码。

--------------------------------------------------
//文件:CANModule.c
//
//说明:CAN 驱动
程序//
//版本:1.0 (2015年2月5日)
//
目标:TMS320F28335
//
//详细信息:到 ECAN 硬件的外设接口
//硬件支持扩展 CAN (ECAN)和标准 CAN
//(SCC)。 此驱动程序使用 SCC CAN。
////
参考:sprue1 - TMS320F2833x、2823x 增强型控制器局域
网//网络(eCAN)参考指南
//////../../---------------增强型控制器局域网//网络(eCAN)参考指南



///------------------ 包括--------------------------------
#include "Defs.h"
#include "processormodule.h"
#include "PeripheralHeaderIninclude.h"
#include "GMNIAddeding.h"
#include "CANModule.h"

#include "Errors.h"#include "ParamDB.h"
#include "DebugModule.h"
#include "CommandProtocol.h"
#include "---"include--
#include "--/-"ines.h"

定义了-------------------------------------------------------
#define LOOP_Counts(((uint32) 10000)//取消循环计数以便我们不会永远被卡住
#define NUM_POOFFER((int) 16)//标准 CAN 模式中允许的邮箱数
#define ACCEITY_MASK0xFF03FFFF//位18到28用于标准 CAN、屏蔽用0来完成
//在本应用中, 节点 ID 用作消息 ID。 它存储在6位中、因此...
//位18到23必须匹配消息 ID -(位31) xxxx、xxxx、000000、00xx、xxxx、xxxx、xxxx、xxxx (位0)
#define MAX_TX_Attempts((UINT32) 2)



//--- 全局变量--------------------------------------------
CANQueue canQueue;//存储来自总线
CANQueue LocalCommQueue 的 CAN 消息;//存储来自与发送方相同 CAN 节点的 CAN 消息。
//每个节点都可以看到来自所有其他节点的所有消息,但无法看到自己的消息。
//参考:  www.keil.com/.../canprimer_v2.pdf

静态 uint16 currDestID;

// Ecanb 接口用于与 Encore
静态易失性结构 ECAN_REGS 上的主仪器 CAN 总线进行通信*ECANRegs=&ECANbRegs;
静态易失性结构 ECAN_MBOXES *ECANMbox=&ECanbMboxes;
静态易失性 Regstruct EAM----


//注意:访问 ECAN 控制和状态寄存器
//
//只允许对这些寄存器进行32位访问。 对
这些寄存
器的16位访问//可能会破坏寄存器内容或返回//假数据。 当写入
/读取位16 - 31之间的位//(或位组)时尤其如此
//
这适用于以下寄存器:
// CANMECANMDCANTRSCANTRRCANTA CANAACANRMPCANRML
// CANRFPCANGAMCANMCCANBTCCANTECCANRECCANNGIF0
// CANGIMCANGIF1CANMIM CANMIM CANMIL CANTIOCCANRIOCCANTSC
// CANTOC CANTSC CANTSC CANTSC //

//////采用影子寄存器进行32位读操作以进行读操作。
///----------------------------------
静态易失性结构 ECAN_REGS EDANRegsShadow;


//---------------
// eCAN-Init
//
//标准 CAN 初始化。 使用控制器板上的 CAN-B。
//与主控制器总线通信。
///----------------------------------
void eCAN-Init (uint16 bcastAddr)
{
volatile struct MBOX *邮箱;
int i;

canQueue.size= 0;
localCommQueue.size= 0;

EALLOW;// EALLOW 启用对受保护位的访问

//使用 eCAN 寄存器为 CAN 操作配置 eCAN RX 和 TX 引脚
//请参阅文件
ECANRegsShading.CANTIOC.all =ECANRegs->CANTIOC.all 顶部的注释;
ECANRegsShading.CANTIOC.bit.TXFUNC= 1;//启用发送
ECANRegs->CANTIOC.all= ECANRegsShading.CANTIOC.all;

ECANRegsShading.CANRIOC.all= ECANRegs->CANRIOC.all;
ECANRegsShading.CANRIOC.bit.RXFUNC= 1;//启用接收
ECANRegs->CANRIOC.ALL= ECANRegsShadow。CANRIOC.ALL;

//将 CAN 配置为 SCC 模式(标准 CAN 控制器模式)-(要访问邮箱15至0)
//我们不使用 eCAN,我们使用
影子(邮箱0至15) ECANRegsSCN.CANMC.ALL= ESCRegs->CANCLA.USC.B
;CANCLUSC.AB.USC.T= CANSDC.TANCE.USC.D/ CAN.CANCLUSC.TL.MC.CAN.USC.TABTBIT.CAN.ABT= CANESC.D/ CANCR.CANESC.D/ CANCR.CANCR.CANCR.CAN
//启用
ECANRegs->CANMC.ALL上的自动总线= ECANRegsShading.CANMC.ALL;

//将“消息控制寄存器”的所有位初始化为零
//MSGCTRL 寄存器的某些位出现在未知状态。 为了正确操作,
//MSGCTRL 的所有位(包括保留位)必须初始化为零
Mailbox =&ECanMboxs->MBOX0;
for (i = 0;i < NUM_mailbox;++I)
{
Mailbox->MSGCTRL.ALL= 0x00000000;
+Mailbox;
}

// CANCCR MC 位设置为1:
// CPU 请求到配置寄存器 CANBTC 和 SCC 的接受屏蔽
//寄存器(CANGAM、LAM [0]和 LAM [3])的写入访问。 置位该位后、CPU 必须等到
CANES 寄存器的 CCE 标志为1、然后再进入 CANBTC 寄存器。
ECANRegsShadure.CANMC.ALL= ECANRegs->CANMC.ALL;
ECANRegsShading.CANMC.bit.CCR= 1;//更改配置请求位
ECANRegs->CANMC.ALL= ECANRegsShading.CANMC.ALL;

//等待 CCE 位被置位。
// CCE = 1、当 CPU 对配置寄存器具有写访问权限时。
// CCE 是更改配置使能位
DO
{
ECanRegsShading.canes.all = ECanRegs->canes.all;
} while (ECANRegsShading.canes.bit.CCE!= 1);

//清除位时序配置寄存
器 ECANRegs->CANBTC.all= 0;

//配置位时序
//位速率=(SYSCLKOUT / 2)/((BRPreg + 1)* BitEG)
//其中 SYSCLKOUT = 150MHz
//位时间=(TSEG1REG + 1)+(TSEG2REG + 1)+ 1
EDANRegsShading.CANBTC.all= ESEG1REG + 1)+(TCCANREG2REG +
1)+ CANBRCN.CANRegDIDT.CANTC.ALL = ECANBRTC.TC.TC.TCC.Tc = CANTCC.TCC.TB.Tc = CANTBC// 4 for 1Mbps 提供15MHz CAN 模块时钟
ECANRegsShadow。CANBTC.bit.TSEG2REG= 2;// 15个时间份额每位- 80%采样点
ECANRegsShadow。CANBTC.bit.TSEG1REG= 10;// 15个时间份额每位- 80%采样点 ECANRegsShadow。CANBTC.TCCS.bit.TSEG1REG = 10;// 15个时间份额:
//采样3次并获取多数读取
ECANRegsShading.CANBTC.bit.SJWREG= 0;// 0:SJW (同步跳转宽度、扩展段1和缩短段2);1:SJW = 2 (1表示800KB)
ECANRegs->CANBTC.ALL= ECANRegsShading.CANBTC.ALL

;1 = CANCANGAM.ALL 用于全局接受屏蔽6;CANGANGAM = 6 = CANGANGAM.MASK 接收邮箱
//位18到23必须与 msg ID
EDANRegsShading.CANGAM.all= ECANRegs->CANGAM.all;
ECANRegsShading.CANGAM.bit.AMI= 1;//接受屏蔽标识符- 1:CAN 将接受标准和扩展帧。
//接收邮箱的 IDE 是“无关”。 被发送的消息覆盖。
//使用 CANGAM 的位18至28在标准 CAN 模式
下进行 msg 过滤 EDANRegs->CANGAM.all= ECANRegsShading.CANGAM.all;

// LAM0 (本地访问掩码)用于邮箱0至2
ECANLAMRegs->LAM0.all= Accepting_mask;// LAM23位必须匹配
1至 ECANLAMID;//接受屏蔽标识符- 1:CAN 将接受标准和扩展帧。
//使用 CANGAM 的位18至28在标准 CAN 模式下进行 msg 过滤


// LAM3 (本地访问掩码)用于邮箱3至5
ECANLARegs->LAM3.all= Accepting_mask;//位18至23必须与 msg ID
EDANLAM Regs->LAM3.bit.Lami= 1匹配;//接受掩码://标识符掩码: CAN 将接受标准和扩展帧。
//在标准 CAN 模式中使用 CANGAM 的位18至28进行 msg 过滤

// CANMC CCR 位设置为0:
//在配置寄存器 CANBTC 和
SCC 的接受屏蔽//寄存器(CANGAM、LAM[0]和 LAM[3])完成后,CPU 请求正常运行。
ECANRegsShadure.CANMC.ALL= ECANRegs->CANMC.ALL;
ECANRegsShading.CANMC.bit.CCR= 0;//更改配置请求位
ECANRegs->CANMC.ALL= ECANRegsShading.CANMC.ALL;

//等待 CCE 位被清除。
// CCE = 0当 CPU 没有到配置寄存器的写入访问权限时。
执行
{
ECanRegsShading.canes.all = ECanRegs->canes.all;
} while (ECANRegsShading.canes.bit.CCE!= 0);

currDestID= 0x3F;//初始化后续-此处使用的虚拟值

ECANRegs->CANME.all= 0;//禁用所有邮箱,写入 MSGID 前需要
;邮箱=&ECANMboxs->MBOX0;//在第一个邮箱开始

/
邮箱传输位 IDE->MSGID-邮箱设置邮箱//无扩展 ID,使用 SCC (statndard CAN)
邮箱->MSGID.bit.STDMSGID=(currDestID & 0x3F);//目标 ID -在此处使用虚拟值。 在发送时设置为目的
// STDMSGID 为11位(bit 10至 bit 0),对应于 MSGID
++Mailbox 的 bit 28至 bit 18;

//为
(i = 0;i < 5;++I)
{
Mailbox->MSGID.bit.ide= 0设置5个接收邮箱;// IDE 是一个“无关”,当 AMI=1时被发送的消息覆盖
//仍然在这里设置-在这里设置它没有任何危害
邮箱->MSGID.bit.AME=1;//接受屏蔽被启用
邮箱->MSGID.bit.STDMSGID= cntrlrNodeAddr;//消息 ID,cntrlrNodeAddr 是控制器节点 ID
++Mailbox;
}

//为
(i = 0;i < 10;+i)
{
Mailbox->MSGID.bit.ide= 0设置10个广播接收邮箱;// IDE 是一个“无关”,当 AMI=1时被发送的消息覆盖
//仍然在这里设置-在这里设置它没有任何损害
邮箱->MSGID.bit.AME= 1;//接受屏蔽被启用
邮箱->MSGID.bit.STDMD= bCastAddr;//消息 ID
+Mailbox;
}ECANRegs->0x0000FFGID.all
;}CANGID.STDMD = 0x0000FFMD//为接收
ECANRegs->CANOPC.ALL= 0x0000FFBD 设置邮箱;//保护数据,除了最后一个接收邮箱
ECANRegs->CANME.all= 0x0000FFFF;//启用邮箱

EDIS;
}//------------------



// EcanRX
//
CAN 接口上的接收消息。
///----------------------------------
void EcanRX (void)
{
uint32 rcvMask、mask;
volatile struct MBOX *邮箱;

//检查溢出
(如果(ECANRegs->CANRML.all!= 0)
{
DEBUG_log (0xFC100000);
}

do
{
//检查 RMP =接收待处理消息
rcvMask= ECanRegs->CANRcml;

如果所有
数据都可以读取到邮箱中)
邮箱=&ECANMboxs->MBOX15;
掩码= 0x00008000;
while (mask!= 0)
{
//如果有消息,请将其放入 CAN Q
if ((mask & rcvMask)!= 0)
{
if (canQueue.size < CAN_queue_queue)
{
canQueue.data[canQueue.size].mdl.mc邮箱=
低位数;mdlc= cand.cmc.mbl.micro.micro.rc.mcand.dl.micro.rc.mced.r.r.r.r.r.r.rc.mblu.mcand//低消息数据
canQueue.data[canQueue.size].high=邮箱->mDH.all;//高消息数据
+canQueue.size;
}
else
{
//可以队列溢出
debug_log (0xFC200000 | rcvMask);
}
}-->
邮箱;
掩码>=1;
}

//允许进一步接收数据包 EcRegs->CANvMask
;}//将所有接收位设置为1以清除 CANRMP
rcvMask=~rcvMask;
while ((ECANRegs->CANRMP.ALL 和 rcvMask)!= ECANRegs->CANRMP.ALL){}//等待位清除
}
while (ECANRegs->CANRMP.ALL)}--> CANRMP.ALL!------------------------------------------------------------------




// EcanTX
//
//将数据传输到 CAN 总线上的目标位置,或者如果
节点是自消息传送,则将其放入//本地通信队列中。
///----------------------------------
void EcanTX (uint16 destID、uint32 low、uint32 high、uint16 len)
{
uint32 i、j、k;
BOOL tryRecover= true;

如果(destID =cntrlrNodeAddr || GMNI_ADDR_BCAST == destID)
{//
本地节点单播或要广播到自身的数据包,请将其放入本地消息通信队列
中,如果(localCommQueue.size < CAN_Queue_size)
{localCommQueue.data[localCommQueue.size].low
= low.localCommQueu.= low.= localCommQueu.s/sime.size.s/sime.s/sime.data];[localCommQueu.Commsize.s=localCommQueu.localComms/sime.data];[localCommsize.s=localCommque




否则
{
//本地邮箱溢出
debug_log (0xFC300000);
}
}

//else//将所有传出消息发送到 CAN 总线-单播和广播
IF (destID!= cntrlrNodeAddr)
{
//如果目标从上一条消息更改为(
currdestID!= CANdestID)
{
EDANRegsShading.CANME.all= ECANRegs->CANRegme.all;CANest.all
= CANCand.0;CANME.0;//禁用 TX 邮箱
ECANRegs->CANME.all= ECANRegsShading.CANME.all;

ECANMboxs->MBOX0.MSGID.STDMSGID =(DestID & 0x3F);//目标 ID

ECANRegsShading.CANME.ALL= ECMDR.ALL = CANDRES.0>EMCMBE0>EMCMDR.UME




;// EMR0>EMCMDR.UME =


低字节0>EMCMDR.UME =高字节0>EMCMOS.REDME;////写入高字节
ECANRegs->CANTRS.All= 0x00000001;//开始传输

(i = 0;i < MAX_TX_Attempts;+i)//尝试发送,然后在出错
时再次尝试发送{
//如果发送 ACK 未在通过此循环的合理次数内设置,
//退出循环。 如果发生超时、控制器可能无法连接到系统。
//我们不想在该循环中卡住。
//在控制器中设置 CANTA 的典型时间小于~130 μ s。
//典型循环计数小于229。
ECanRegsShadow.Canta.all = ECanRegs->CANTa.all;
for (j = 0;j < LOOP_Counts && ECANRegsShadow.CANTAM.TA0 = 0;+j)
{
ECanRegsShadow.Canta. all = ECanRegs->CANTA.all;
}

(如果


您尝试全部恢复、

则为1){ECanRegsShadow / CANTANRegs.all = 1;允许全部恢复(如果是)
if (ECANRegsShading.canes.bit.SA1)//检查显性错误时卡住
{
//尝试清除其显性位错误
ECANRegsShading.CANMC.ALL= ECANRegs->CANMC.ALL;
ECANRegsShadow CANMC.bit.CCR= 1;//更改配置请求-写入访问 ECANRegs->CANRegs.eCan.all;ECANRegsShadow = CANMC.CANCR.CANCR.CANCR.CANCR.CN.0=CANCR.CANCR.CANCR.CANCR.NOR



= ECANCR.CANCR.CANCR.CANCR.CANCR.CANCR.RECN.0; ECANCR.CANCR.CANCR.CANCR.CANCR.CANCR.CANCR.NOP=0=ECANCR. +k)
{//等待 CCE 为1,CPU 将具有对配置寄存
器 ECanRegsShading.canes.all的写入访问


权限= ECanRegs->CANES.all;}ECanRegsShading.CANMC.ALL = ECanRegs->CANMC.ALL;
ECanRegsCCR.bit.alk= 0;
= CANReakradr.CANMC.u.all
=
0;= CANReakralu.CANReakr.CANMC.u.CANMC.u.u.CANReakeMC 配置
= 0;= 0;= CANReakr.CANCR.CANReakr.CANReakr.CANReakr.CANCR.CAN
否则
{
//报告错误
debug_log (0xFC400000);
debug_log (ECanRegsShading.canes.all);

instrstates[0].errCode= ERRCODE (ERRCODE_HI_CAN、ERRCODE_LOW_NO_MSG_TX);
return;
}
}
否则
{
//获取传输确认-一切都是精细
中断;
}
}

EDANRegsShadure.CANTA 全部= 0;
ECANRegsShading.CANTA 位.TA0= 1;//清除传输确认下一个传输
ECANRegs->CANTA 全部= EDANRegs.CANTA 全部;

ECANRegsShadow
= 0<& ECANTA 全部= 1;ECAN.I = CANTA 全部= CANTANRegsShadow ++i)
{//等待传输确认清除
ECanRegsShading.Canta.all= ECanRegs->Canta.all;
}

}//---------------




//文件结尾
///-------------------------------------------------------




///----------------------------------
//文件:CANModule.c
//
//说明:CAN 驱动
程序//
//版本:1.0 (2015年2月5日)
//
目标:TMS320F28377S
//
详细信息:到 DCAN 硬件的外设接口
//硬件支持扩展 CAN (ECAN)和标准 CAN
//(SCC)。 该驱动程序使用 SCC CAN。
//
//参考:spruhx5d - TMS320x2837x、2837x 技术
//参考指南
//
/../../-----------


///------------------ 包括--------------------------------
#include "Defs.h"
#include "processormodule.h"
#include "F2837xS_device.h"
#include "hw_types.h"
#include "hw_CAN.h"
#include "GMNIAddings.h"
#include "Errors.h"

#include "Parameters.h"#include "paramdB.h"#include "ines.h"
-"include "influe.h-"-"#include -"ines.h"#-"--#include -"inue.mandion-"-"-"#include -"-"#-"#include -"-"dictionnation.h"-"-"-"-"-"-"-"#include -"#-"-"#-




定义了-------------------------------------------------------
#define LOOP_Counts((UINT32) 20000)//取消循环计数以便我们不会永远被卡住
#define NUM_POMSG((int) 16)//标准 CAN 模式中允许的邮箱数
#define CAN_BRP_REG(19)
#define CAN_BRP_EX_REG(0)
#define CAN_TSEG1_REG(6)#define CAN_CAN_BR_8



(6)#define CK_REG_18 (#define CAN_CK_REG_1)#define CAN_REG_1 (#define CK_REG_18)#define CAN_CK_REG_1 (#define CAN_CK_REG_1 到28用于标准 CAN、屏蔽由1s 完成
//在此应用中、节点 ID 用作消息 ID。 它存储在6位中、因此...
//位18到23必须与消息 ID 匹配- (位31) xxxx、xxxx、111111xx、xxxx、xxxx、xxxx (位0)
#define CAN_IF3ARB_STD_ID_M (0x1FFC0000U)
#define IF3_mailbox(0x0000FFFE)
#define FIRST_OSSIT_MB(2)//第一个 CAN 单播邮箱
#define LAST_MB_MB(6)- cCAN
/ LAST_M_BONMOD-

(cast-32-)/cast-/ cast_mailbox #define (casteast-/cast_mb)



全局变量--------------------------------------------
CANQueue canQueue;//存储来自总线
CANQueue LocalCommQueue 的 CAN 消息;//存储来自与发送方相同 CAN 节点的 CAN 消息。
//每个节点都可以看到来自所有其他节点的所有消息,但无法看到自己的消息。
//参考:  www.keil.com/.../canprimer_v2.pdf

静态 uint16 currDestID = 0x3F;//虚拟初始值,将在第一个 TX 上更改

//---------------
//注:访问 DCAN 控制和状态寄存器
//
// 32位 DCAN 寄存器必须读/写为32位值。 如果
使用16位//访问、则值可能会损坏。 编译器提供
//内在函数__bit_peripheral_32。 提供了一个宏来提供对
内在函数的访问// HWREG_BP
//
//////../../---------------


///----------------------------------
// DCanInit
//
//标准 CAN 初始化。 使用控制器板上的 CAN-B。
//与主控制器总线通信。
///----------------------------------
void DCANInit (uint16 bcastAddr、uint32 base)
{
uint16 mailbox;//消息对象(mailbox)索引
uint32 mailBoxID;
uint16 endOfBlock;//接收 FIFO 结束-单播块或广播块
uint32 bitReg;
uint32 maskReg;

canQueue.size = 0;
---

启动 DCan init-------------------------------------------------------
//将 CAN 控制器置于初始化状态,与之前的状态无关。 这个
//将使控制器空闲、并且允许对消息对象 RAM
进行//编程。
// CAN_CTL 寄存器
// CAN_O_CTL 相对于寄存器基址偏移
//位:init (b0)= 1;
//ABO Auto-Bus_ON (b9):启用
//PMD 奇偶校验(B10-B13)= 0101 (复位时的默认值)
//DAR 禁用自动重传:0我们想要重传|CAN_INIT_CTL
(CAN_INIT)| INTO_CTL (CAN_INIT
)| INT_CTL (CAN_INT_INIT
(UCTL) 16)| INT_INIT (CAN_INT_CTL (CAN_INT_INT_CTL)

//设置脱离总线计时器值-发生脱离总线和恢复启动后的时钟周期数
// CAN_ABOTR 寄存器
// CAN_O_ABOTR 相对于寄存器基址偏移
//位:Abo_Time (b0-B31)
HWREG_BP (base + CAN_O_ABOTR)= 2;//尝试0、5、10?

//在使用消息 RAM 之前初始化消息 RAM
// CAN_init 寄存器
// CAN_O_RAM_init 与基址偏移
//位:CAN_RAM_init (b4)= 1;键(b0-b3)= 1010
HWREinit (base + CAN_O_RAM_init)= CAN_RAM_CAN_RAM_INIT (b4)= 1;CAN_INIT



(while + CAN_RAM_INIT)+ HW_INIT (+ CAN_RAM INIT + CAN_RAM_INIT)+ CAN_RAM INIT (while + CAN_RAM_COMPLETE)+ CAN_RAM_INIT (+ CAN_RAM_INIT + HW_RAM_INIT (CAN_RAM_INIT_RAM_INIT_DONE | CAN_RAM_INIT_Key2 | CAN_RAM_INIT_KEY0))
{
// RAM_INIT_DONE 将为1
// CAN_RAM_INIT 将为0
//键将为0101
}

//强制模块复位//
CAN_CTL 寄存
器// CAN_O_O_INIT
位为1位:ALLOW 位= 1位(ALLOW 位)

HWREGH (base + CAN_O_CTL)|= CAN_CTL_SWR;
EDIS;

//延迟14个周期- 1us
DELAY_US (1);

//启用对配置寄存器的写入访问
// CAN_CTL 寄存
器// CAN_O_CTL 从寄存器基址偏移
//位:
GH (B6):1 REGH (HWL)-|-——————


————CAN_CTL 寄存器 设置位定时---
//将 CAN 总线位速率设置为1Mbps
//有关如何设置
更严格的时序控制的信息,请参阅驱动程序库用户指南。 此外、请参阅器件数据表
//以了解有关 CAN 模块计时的更多信息。

//要设置位时序寄存器,必须将控制器置于初始
化//模式(如果尚未), 并且配置更改(CCE)位被使能
//这在上面完成

//配置位时序
//位速率=(SYSCLKOUT)/(((BRPreg + 1)* BitTime)= 1、000、000、000Mb/s
//其中 SYSCLKOUT = 200 MHz;BRPreg = 19;TSEG1reg = 1;TSEG2reg = 1; SJWreg = 1
//位时间=(TSEG1REG + 1)+(TSEG2REG + 1)+ 1 = 10
//默认情况下、复位时使用外设时钟(SYSCLKOUT)
bitReg =(UINT32)(

(UINT32) CAN_BRP_REG & CAN_BR_BR_BR_CAN_TR_CK_32)< TR_CAN_TR_TR_TR_TR_TR_TR_TR_TR_CK_TR_TR_TR_TR_CK_32 (UTR_TR_TR_TR_TR_TR_TR_TR_TR_TR_TR_TR_TR_TR_TR_TR_TR_TR_TR_TR_CK_32)|(TTR_TR_TR_TR_TR_TR_TR_TR_TR_TR_TR_TR_TR_TR_TR_TR_TR_TR_
bitReg |=(uINT32)(((uint32) CAN_TSEG2_REG << CAN_BTR_TSEG2_S)& CAN_BTR_TSEG2_M);
bitReg |=(uINT32)(CAN_BRP_REG_REG << CAN_BTR_TSEG2_M);CAN_CTR_BUCTL


寄存器+ CC_0 (UINT_CTL)+ CCTR_CL_CL_CL_BIT_B_6)+ CAN_CL_CL_CL_BIT_BIT_BIT_CL/


(CAN_CTL + CAN_CL_CL_CL_BIT_BIT_BCTL (CAN_6)+ CAN_CTL + CAN_CL_CL_CL_BIT_BIT_BIT_BIT_BIT_BCTL 寄存器/(CAN_CL_6)/ CAN_CL_CL_CL_CL_BIT_BIT_BIT_BIT_BCTL (CAN_CL_CL_CL/ CAN
~

///---------------- 设置邮箱---
// 1个发送邮箱
// 5个单播接收邮箱
// 10个广播接收邮箱

//确保接口1不忙
((HWREGH (base + CAN_O_IF1CMD)& CAN_IF1CMD_BUSY)== CAN_IF1CMD_BUSY)
{
}

// TX 邮箱---

// CAN_IF1MSK 寄存器-接口1掩码寄存
器// CAN_O_IF1MSK 相对于寄存器基址偏移
//位:dir (B29):dir:1 = TX;
//MessageID (b0-B28):0x00FC0000 Filter on Acceptance mask
//mDir (B30):0 -不按方向进行滤波
//MX31: 0 -请勿在扩展 ID
HWREG_BP (base + CAN_O_IF1MSK)= 0;
//HWREG_BP (base + CAN_O_IF1MSK)=(Acceptance_MASK & CAN_IF1ARB_STD_ID_M);

// CAN_IF1BARB 寄存器-接口1仲裁寄存
器// CAN_O_IF1MSK
= 0 (bARB):b3dir_dir (bID:b29):bd2)
虚拟(0x3f << 18) TX msg 的占位 DESID。 发送时将用目标地址填充;
//XTD (B30):0 -标准标识符(11位)
//MsgVal (B31):1 -使用邮箱
HWREG_BP (base + CAN_O_IF1ARB)=CAN_IF1ARB_DIR |
(ACCESTIVE_MASK & CAN_IF1ARB_ID_M)| CAN_IF1ARB_STD_GV1ARB
;

// CAN_IF1MCTL -接口1消息控制
// CAN_O_IF1MCTL 相对于寄存器基址偏移
//位:DLC (b0-B3):8 -数据长度;
//EOB (B7):1 -块末尾;
//umask (B12): 0 -请勿使用掩码在发送
/HWREG_BP (base + CAN_O_IF1MCTL)= CAN_IF1MCTL_UMASK |
HWREG_BP (base + CAN_O_IF1MCTL)=((uint32) MSG_DATA_LENGTH 和 CAN_IF1MCTL_DLC_M)| HWREG_WCA_MASK



| CAN_1D/ CAN_IF1D/CAN_MASK | CMD/ CAN_MASK | CAN_CMO_MASK | CAN_CMO_MASK | CAN_CMO_CMD/ CAN_CONTRAM| CMO_INT_LK | CAN_CMO_MASK | CAN_CMO_MASK | CAN_CMO_CMO_MASK | CAN_CMO_MASK | CAN_CMO_CMO_MASK | CAN_CMO_CMO_CMO_CMO_





5个单播 RX 邮箱和10个广播 Rx 邮箱---
//使用 IF1或 IF2设置消息对象(邮箱)-我们将使用 IF1
//设置消息对象后,我们可以使用 IF3接收
(邮箱= FIRST_OSSON_MB;邮箱<= LAST_BCast_MB; ++mailbox)
{
//确保接口1在
(((HWREGH (base + CAN_O_IF1CMD)& CAN_IF1CMD_BUSY)=CAN_IF1CMD_BUSY)
{
//

CAN_IF1MSK 寄存器-接口1屏蔽寄存
器// CAN_O_IF1MSK 是标准
帧掩码(b31)的偏移
(bMX28位/bd/ bmask)0 -不使用扩展 ID 进行验收滤波
//MDir (B30):0 -不使用方向进行验收滤波
HWREG_BP (BASE + CAN_O_IF1MSK)=(ACCESTIVE_MASK & CAN_IF1ARB_STD_ID_M);

// CAN_IF1DIR 寄存器-接口1仲裁寄存
器// CAN_O_IF1ARB 寄存
器0 -来自 RX 寄存器的位数:0
//MessageID (b0-B28):MSG ID 是控制器节点 addr;
//MsgVal (B31):1 -如果
(邮箱<= LAST_unicast_MB)
{
//设置单播邮箱
mailBoxID = cntrlrNodeAddr;
}
否则
{
//设置广播邮箱
mailBoxID = bcastAddr
;}
HWREG_BP (base + CAN_O_IF1ARB)=((mailBoxID << CAN_IF1ARB_STD_ID_S)和 CAN_IF1ARB_STD_ID_M)|
CAN_IF1ARB_MSGVAL;

// CAN_IF1MCTL -接口1消息控制
// CAN_O_IF1MCTL (
B8位)-从 BOB
1到 B8的数据位数(0);/ B8位数:1) 使用 FIFO 为最后一个单播邮箱和最后一个广播邮箱设置 EOB
//umask (B12):1 -如果

(LAST_OST_MB =mailbox || LAST_BCast_MB == mailbox){
endOfBlock =CAN_IF1MCTL_EOB;
}
否则
{
endOfBlock =0;
}

HWREG_BP (base + CAN_O_IF1MCTL)= CAN_IF1MCTL_UMASK |
((uint32) MSG_DATA_LENGTH & CAN_IF1MCTL_DLC_M)|
endDIR Block;

//将数据传输到消息对象 RAM
HWREG_BP (base + CAN_O_IF1CMD)= CAN_IF1M_BMSG |CAN_IF1M| CAN_CMIF1M| CAN_MASK



| CAN_CMIF1M| CAN_CMIF1M| CAN_CMIF1M| CAN_CMIF1M| CAN_CMIF1M| CAN_CMIF1MK_CONTROL_CMD_CMING_CMD| CAN_MASK |


//启用 IF3以接收所有 RX 消息,无论是单播还是广播
HWREG_BP (base + CAN_O_IF3UPD)= IF3_mailboxes;//邮箱2到16

//设置 IF3,以便在从接口读取所有数据之前不会发生下一次 IF3更新
// CAN_IF3OBS 寄存器- IF3观察寄存器
// CAN_O_IF3OBS 是寄存器基址的偏移
//位:DATA_A (B3): 1 -在数据被读取前没有新的 IF3更新
//Data_B (b4):1 -在数据被读取前没有新的 IF3更新
HWREGH (base + CAN_O_IF3OBS)= CAN_IF3OBS_DATA_A |
CAN_IF3OBS_DATA_B;
//CAN_IF3OBS_IF3SM;//要求论坛执行

//清除所有未使用的邮箱的消息有效位
(邮箱=(LAST_BCast_MB + 1);邮箱<= LAST_CAN_MB;+mailbox)
{
HWREG_BP (base + CAN_O_IF1ARB)= 0;//将 MsgVal 设置为0
HWREG_BP (base + CAN_MSG_IFM_BM
)
| CMO_IFD_邮箱= 1);CMIFD_CMD_CMD_CMD_CMD_CMD_CMD_CMD_CMD_CMD_CMD_CMD_CMD_CMD_CMD_CM

//初始化后启动 CAN 模块
HWREGH (base + CAN_O_CTL)&=~(CAN_CTL_init | CAN_CTL_CCE);
}


//---
// DcanRX
//
CAN 接口上的接收消息。
///----------------------------------
#define RCV_POMS_MASK (0x0000FFFE)
void DcanRX (UINT32 base)
{
volatile UINT32 msgsPending = 0;
volatile UINT16 msgCtrl;
volatile UINT16 msgObs;

msgObs = HWREGH (base + CAN_O_IF3OBS);

//通过 IF3 (CAN 接口3)读取消息 RAM 中的所有传入消息
、同时((msgObs & CAN_IF3OBS_IF3UPD)=CAN_IF3OBS_IF3UPD)
{
//do
//检查
消息 RAM 中设置了 NewData 位的
邮箱// msgsbs_rbp + HW21 (HW_MASK +)

//检查 IF3观察寄存器以查看新数据是否显示在 IF3 - IF3Upd 位
//msgObs = HWREGH (base + CAN_O_IF3OBS);

//检查 IF3以查看消息是否已自动传输到接口
//msgCtrl = HWREGH (base + CAN_O_IF3MCTL);

//如果在 IF3中有消息,则将其放入 CAN Q
//if (msgCtrl & CAN_IF3MCTL_NEWDAT)=CAN_IF3MCTL_NEWDAT)
if (msgObs & CAN_IF3OBS_IF3PDD)=CAN_IF3OBS_IF3LD_NEWDAT)=CAN_3MCTL_NEWDAT (msgObs & CAN_QUEST_END)=cine.t_QUEST_CAN.trl.trl.t

=cannu.trl.trl_cin_cinu.trl.trl.trl =cinu.trl.trl.c&can32.t_trl.trl_can32.t_canc (cannu.trl =can32.t_trl.trl.trl


//低消息数据-字节0到3
canQueue.data[canQueue.size].high = HWREG_BP (base + CAN_O_IF3DATB);//高消息数据-字节4到7
+canQueue.size;
}
else
{
// CAN 队列溢出
DEBUG_log (0xFC200000 | msgObsGH);}-->---/---/---/---/----








// DcanTX
//
//将数据传输到 CAN 总线上的目标位置,或者如果
节点是自消息传送,则将其放入//本地通信队列中。
///----------------------------------
void DcanTX (uint32 base、uint32 destID、uint32 low、uint32 high、uint16 len)
{
//在 IF1和 IF2之间切换每次发送 TODO 都可以执行此
操作//canIF =(canIFToggle)? 1:2;
//canIFToggle =(canIFToggle)? 0:1;
易失性 UINT32 CANStatus;
UINT16 loopCounts;//针对超时
易失性 UINT32 msgArb;

//针对此控制器节点的消息-如果
(destID == cntrlRNodeAddr || AMST_ADDR_BCNI ==destID),请勿将其发送到总线,将其放入本地 CAN 队列中
{
//本地节点单播或广播到自身的数据包,如果
(localCommQueue.size < CAN_queue_size)
{{
CommQueue.data[localCommQueue.size].low = low;






溢出 CommQueue.data[localCommQueue_Queue.size].high = high;localCommQueue.data[localCommQueue.size]= 0x000+localCommLog.size];localCommlog.size.size];{//
debug = localCommlog.size.size.size.s/size];{// localCommQueue_mailbox+0x000

}

//将所有传出的消息发送到 CAN 总线-单播和广播
//使用 IF1 (接口1)作为 CAN TXS
IF (destID != cntrlrNodeAddr)
{//

//设置 if 命令以读取仲裁值
//
//设置对消息对象数据的请求。
//将报文对象传输到 IF 寄存器。
//
HWREG_BP (base + CAN_O_IF1CMD)= CAN_IF1CMD_ARB |
(TX_mailbox & CAN_IF1CMD_MSG_NUM_M);

//确保 IF1不会忙于 IF1和 CAN RAM 之间的前一个传输
(HWREGH (base + CAN_O_IF1ARB)
= CAN_WAIT + CAN_INUST_BIST_BID/ CAN_BID/ CAN_BIST_COMPB= BUSY (BUSY)



= CAN_ING_BIST_CAN_IND/ CANIF1CMD/ CAN_BIST_BIST_CAN_CAN_BIST_CAN_CAN_COMPB)


//将数据写入接口1
HWREG_BP (base + CAN_O_IF1DATA)=低电平;
HWREG_BP (base + CAN_O_IF1DATB)=高电平;

//如果(currdestID
!= destID)
{
HWREG_BP (base + CAN_O_IF1DATB)=高电平、则重置目标消息 ID (current-stdb!= destinb)
| db = 1arb
)| CAN_i_i_i_iDb (CAN_1stb)

//在 RAM 中将 IF 消息对象传输到 TX 邮箱
//不更改方向、长度或邮箱 ID
HWREG_BP (base + CAN_O_IF1CMD)=(CAN_IF1CMD_DATA_B |
CAN_IF1CMD_DATA_A |/ HWCAN_IF1CMD_CONTROL | CAN_IF1CMD_QST



| CAN_CMD_QST | CAN_CMD_QST | CAN_CMIF1QST | CAN_CMD_PRBQ | CAN_Q1CMD_QCMD_| CAN_CMD_QST | CAN_CMD_PRBQ



//HWREG_BP (base + CAN_O_IF1CMD)= 1;
//CanbRegs.CANIF1CMD.bit.MSG_NUM = 1;
//HWREG_BP (base + CAN_O_IF1CMD)|=(1 & CAN_IF1CMD_MSG_MSG_M);

//检查总线
是否一直等待
或不确认任何恢复/至少在此处进行任何传输/不会在此处进行。 让我们通过
以下方式进行恢复并获取消息:/*loopCounts = 0;
canStatus = HWREG (base + CAN_O_ES);
while (!(CANStatus & CAN_ES_Es_TXOK)&& loopCount++< LOOP_Counts)
{
canStatus = HWREG (base + CAN_O_ES);
if (loopCounts + 1 >= ROLOCK_RECORECORECODE_RECO0_RECODE_COUNT[0x000]





(LOCK_RECORECORECODE_COUNT_RECODEBUG);
}CANTRIGNOT_COUNT_RECORECORECODE_COUNT_RECORECODE_COUNT_LK = 0x000_COUNT_RECORECORECORECORECORECO
}
*/}
}//------------------




//文件结尾
///-------------------------------------------------------


谢谢-

Mary

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Mary、

               DCAN 遵循与 eCAN 不同的编程模型。 在 DCAN 中、我们使用 IFx 寄存器作为访问邮箱(MBX) RAM 的"窗口"。 也就是说,您不会像使用 eCAN 那样“直接”访问 MBX RAM。 此外、DCAN 中的 MBX RAM 区域没有"直接可见性"(除非 RDA = 1)。

     

    您说您能够接收数据。 如果确实如此、则可以假设您的设置中没有硬件问题。

     

    您是否在 c2000ware 中尝试过示例代码? 将您的代码与(成熟的)示例代码进行比较是找出代码错误的最快方法。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好-

    我完全意识到 DCAN 采用的模型与 ECAN 不同。  我使用接口(IFx 寄存器) 作为邮箱 RAM 的窗口。   我的代码就证明了这一点。  我发布了335和377S 代码。  我使用 TI 示例代码来编写代码。  我正在寻找一个具体的原因、您可能会知道传输数据为什么不会输出。

    谢谢-

    Mary