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.

[参考译文] CCS/TMS320F28377S:DCAN 模块。 有关掩码和 FIFO 使用的代码示例。

Guru**** 2484615 points
Other Parts Discussed in Thread: TMS320F28377S, TMS320F28234, C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/823417/ccs-tms320f28377s-dcan-module-code-example-about-mask-and-fifo-use

器件型号:TMS320F28377S
Thread 中讨论的其他器件: TMS320F28234、C2000WARE

工具/软件:Code Composer Studio

您好!

我正在尝试调整一个 CanOpen 堆栈、该堆栈在具有 DCAN 模块的新型 TMS320F28377S 上与 eCAN 模块一起在 DSP TMS320F28234上工作。

我要编写一些基本代码来将堆栈与新器件连接、但我有很多问题需要了解如何在接收邮箱中设置 FIFO、以及如何设置 MASK 位以便对特定器件进行硬件筛选。

下面是我用来设置 DCAN、管理 Msg 中断和状态中断的代码:

/*为20MHz 定义的值*/
DWORD const tCCanSpeed[9]={
10000、 /* 10K 位/s、*/
20000、 /* 20K 位/s */
50000、 /* 50K 位/s */
100000、 /* 100K 位/s */
125000、 /* 125K 位/s */
250000、 /* 250K 位/s */
50000、 /* 500K 位/s */
800000、 /* 800K 位/s */
1000000 /* 1M 位/s */
};

/*----------------- */
*私有数据 */
//*------------------------------------------------------------------------------------------------- //

CAN_MSG stCansgBuffer; /*!<用于存储一条 CAN 消息的本地缓冲区*/

静态无符号字符缓冲区 In[8];
静态 tCANMsgObject sMsgObjectRx;

/*--------------- */
/*私有函数 */
//*------------------------------------------------------------------------------------------------- */

//*------------------------------------------------------------------------------------------------- */
/*公共功能 */
//*------------------------------------------------------------------------------------------------- */

*!
初始化 CAN 控制器。
Esegue l'inizzazione del modulo can e resetta tuti messaggi

\param bIndex 选择位时序
*/
void gCan_CntrlInit (byte bIndex)
{
byte I; //每个记分器的计数器 i 缓冲器 da 3 A 32

EALLOW; /*禁用保护*/

//在复位后初始化 CAN 控制器。
//
//\param ui32Base 是 CAN 控制器的基地址。
//
////复位后、CAN 控制器保持禁用状态。 但是
、//用于报文对象的存储器包含未定义的值、
并且必须在第一次启用 CAN 控制器之前清零。 这可防止
//在
配置报文对象之前不必要地发送或接收数据。
必须在首次启用控制器//之前调用此函数。
CANInit (CAN_BASE_ADR); //初始化 CAN 控制器

//初始化 CAN 控制器//初始化时钟模块化 CAN 数据时钟模块否20MHz
CANClkSourceSelect (CAN_basic_ADR、CAN_CLK_EXT_OSC); //设置可由 X1、X2时钟(20MHz)计时

//设置波特率*//
设置 CAN 总线的位速率。 此函数为
标称配置设置 CAN //总线时序。 如果

需要,可以使用函数 CANBitTimingSet()代替这个函数//来实现对 CAN 总线时序的更多控制。
//在此示例中、CAN 总线设置为500kHz。 在下面的函数中、
//对 SysCtlClockGet ()的调用被用来确定//用来
为 CAN 外设计时的时钟速率。
如果您知道系统时钟的值、则可以将其替换为//固定值、从而节省额外
的//函数调用。 对于某些器

件、CAN 外设的时钟是固定的// 8MHz、与系统时钟无关、在这种情况下、对// SysCtlClockGet ()的调用应该被8000000取代。 有关
CAN 外设时钟的更多信息、请参阅数据//表。
CANBitRateSet (CAN_basic_ADR、20000000、tCCANSpeed[bIndex]);

//初始化消息邮箱
//消息1 -> 16接收
//消息29-30-31-32发送
//为
(I = 1;I <= 15;I++)
设置 RX 消息缓冲区{
//标识符零,设置 AME */
sMsgId.0; // CAN 消息 ID -使用0

sMsgObjectRx.ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER | MSG_OBJ_FIFO; //启用掩码和 Rx 中断且 FIFO

sMsgObjectRx.ui32MsgLen = 8;

*(unsigned long *) ucBufferIn = 0;
sMsgObjectRx.pucMsgData = ucBufferIn; // ptr 至消息内容

sMsgObjectRx.ui32MsgIDMask = 0x00000000UL;
CANMessageSet (CAN_basic_ADR、I、&sMsgObjectRx、MSG_OBJ_TYPE_RX);
} //

将消息16初始化为 FIFO 结束
sMsgObjectRx.ui32MsgID = 0; // CAN 消息 ID -使用0

sMsgObjectRx.ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER;//启用屏蔽和 Rx 中断并结束 FIFO

sMsgObjectRx.ui32MsgLen = 8;

*(unsigned long *) MsucerIn = 0;sMsgObjectRx.uiBufferIn
= 8;MsgBufferData // ptr 至消息内容

sMsgObjectRx.ui32MsgIDMask = 0x00000000UL;
CANMessageSet (CAN_basic_ADR、16、&sMsgObjectRx、MSG_OBJ_TYPE_RX);

/*启用中断线路0上的状态中断*/*
启用中断线路1上的消息中断*/
////////////针对总线关闭、错误无源和警告级别*/
CANIntEnable (CAN_basic_ADR、CAN_INT_IE1 | CAN_INT_ERROR | CAN_INT_IE0); //中断线路1使能、状态中断使能、错误中断使能、中断线路0使能

//将消息缓冲器中断连接到线路1 */
HWREG (CAN_BASIAL_ADR + CAN_O_IP_MUX21)= 0xFFFFFFFF; // Tuti gli 中断 delle 邮箱 su INT1

//启用消息缓冲器中断*/
CANGLalIntEnable (CAN_BASIAL_ADR、CAN_GLB_INT_CANINT1 | CAN_GLB_INT_CANINT0);//全局中断0和1启用

EDIS; /*启用保护*/
}/*

!
在总线上放置一条 CAN 消息。
\param ptMsg 指向缓冲区的指针
\return NO_ERR transmission in progress、
WAIT_ERR no transmission cause of inhibit time、
BUSY_ERR no transmission cause of other transmission in progress
*
/ byte gCAN_MSEM_Area * ptMsg)
{
byte returncode = NO_ERR;

unsigned long ulStatus;
tCANMsgObject sObgMsType;tObjectMsgMsg

unsigned char ucBufferOut[8]={0x00、0x00、0x00、0x00、0x00、 0x00、0x00、0x00};

if (ptMsg =0)
{
returncode = NO_ERR;
}// if
else
{
sMsgObjectTx.ui32Flags = MSG_OBJ_TX_INT_ENABLE;

//复制消息数据字节
BufferOut[0]= BDB[0];=BCC3>BUCUT=BUCNT<DB<2]=BCCMs缓冲



区<DB<2>BUT=BUT=BUT<DB>缓冲 区缓冲区缓冲区<DB<DB<2]=BUT=BUT<DB<DB>BUT=BUT=BUT<DB<DB>缓冲 区缓冲区<DB>BUT<DB<DB<PUT=2>BUT=BUT<DB<DB<DB>BUT<缓冲 区缓冲区<DB<DB<DB
ucBufferOut[5]= ptMsg->BDB[5];
ucBufferOut[6]= ptMsg->BDB[6];
ucBufferOut[7]= ptMsg->BDB[7];

sMsgObjectTx.ui32MsgID = ptMsg->qbId.dw; // CAN 消息 COB-ID
sMsgObjectTx.ui32MsgIDMask = 0; // TX
sMsgObjectTx.ui32MsgLen = ptMsg->DLC 不需要掩码; //设置 DLC 和 RTR 标志
sMsgObjectTx.pucMsgData = ucBufferOut; // ptr 至消息内容
if (ptMsg->rtr)
{sMsgObjectTx.ui32Flags
|= MSG_OBJ_REMOT_FRAME; //设置远程帧
MsgType = MSG_OBJ_TYPE_TX_REMOTE; //设置消息类型
}
否则
消息类型= MSG_OBJ_TYPE_TX; //设置 Msg 类型

//读取控制器 TX 状态。
ulStatus = CANStatusGet (CAN_basic_ADR、CAN_STS_TXREQUEST);

if ((ulStatus & 0x80000000UL)=0)
{
//使用对象32发送
// Il trasaggio vivene configurato e messo in Messageone dfunzione CANObjectSet
(CAN_basical_ADR);32、MsgType //使用对象32在总线上发送消息
}
否则(((ulStatus & 0x40000000UL)=0)
{
//使用对象31发送
// Il messaggio viene configurato e mso in trasmissionone dalla funzione CANMessageSet ()
CANMessageSet (CAN_basical_ADR、31、&sMsgObjectTx、MsgType); //使用对象31在总线上发送消息
}
否则(((ulStatus & 0x20000000UL)=0)
{
//使用对象30发送
// Il messaggio viene configurato e mso in trasmissionone dalla funzione CANMessageSet ()
CANMessageSet (CAN_basical_ADR、30、&sMsgObjectTx、MsgType); //使用对象30在总线上发送消息
}
否则(((ulStatus & 0x10000000UL)=0)
{
//使用对象29发送
// Il messaggio viene configurato e mso in trasmissionone dalla funzione CANMessageSet ()
CANMessageSet (CAN_basical_adr、29、&sMsgObjectTx、MsgType); //使用对象29在总线上发送消息
}
否则
{
返回码= BUSY_ERR; //输出:忙线错误
}


返回码; //输出:返回码
}/*

!
\brief CAN 消息缓冲器 ISR。

CAN 接收/发送中断服务例程。

此函数连接到 DCAN 中断1
*/
_interrupt void gCan_MsgIntHandler (void)
{
bBNr;/*消息缓冲器编号*/
#if ID_FILTER != 0
字 WID;/*接收到的标识符*/
#endif/* ID_filter */

unsigned long ulCANINT;
unsigned long ulCANNAT_21
;
unsigned long ulCANIPEN_21;

//设置中断优先级:
volatile UINT16 INTPIIER = PieCtrlRegs.PIEIER9.all;
IER |= MIN9
;= TIEMIR_9; //设置“全局”优先
级 PieCtrlRegs.PIEIER9.all &= MG9_6; //设置"组"优先级
PieCtrlRegs.PIEACK.all = 0xFFFF; //启用 PIE 中断
__asm (" NOP");
EINT;

//调试中断计数器
IrqMsgRicevuti++;

//读取 CAN 中断状态以查找中断原因
ulCANINT = CANIntStatus (CAN_basical_ADR、CAN_INT_STS_CAUSE);
CANulCANINT =(ulINT >> 16)

(同时

读取控制器状态);// 这将返回一个状态
//错误位字段,该字段可以指示各种错误。 为
简单起见、本示例中未执行错误处理//。 有关
错误状态位的详细信息、请参阅// API 文档。
//读取此状态的操作将清除中断。 如果
// CAN 外设未与其它 CAN 器件
//存在
的 CAN 总线连接,则会发生错误,并在//控制器状态中指示。
ulCANES = CANStatusGet (CAN_basic_ADR、CAN_STS_CONTROL);
ulCANES = ulCANES;

//读取新的数据位
ulCANNDAT_21 = CANStatusGet (CAN_basic_ADR、CAN_STS_NEWDAT);
//读取中断挂起位
ulCANIPEN_21 = CANStatusGet (CAN_BASIC +)

;CANNTR_IN+(CAN_BIPDADR = 0x21)+(CANIPBIPBLD+);CAN_IN+(CANIPBIPBLD+)(CAN+)(CAN000+)(CANNOR = CAN_IN+)(CANNOR +)(CAN_IN+)(CANIPBIPB000+)(CAN_IN+);CAN+(CAN+)

//如果中断挂起
{
if (bBNr >= 29)//发送中断?
{
//发送中断-上次传输成功
bFirstMsgTrans = true;
bCanStatus |= CAN_STS_TX_OK;

//清除消息对象中断。
CANIntClear (CAN_BASE_ADR、bBNr);

//调试:增加感应消息计数器
Rcantx++;
}
否则 if (ulCANNDAT_21和0x0001L)//接收中断?
{
//获取接收到的消息并清除 Interrutp 挂起标志
CANMessageGet (CAN_basic_adr、bBNr、&sMsgObjectRx、true);
//清除消息对象中断。
CANIntClear (CAN_BASE_ADR、bBNr);

// N.B.此 DO 循环仅用于在末尾使用"Continue"指令跳转
// 仅执行1次、因为 while 参数为"false"
如果



(sMsgObjectRx.ui32Flags & MSG_OBJ_EXDED_ID)
{
//释放接收缓冲
区继续;
}// if

//获取标识
符 WID =(word)(sMsgObjectRx.ui32FF & 0x07FF);

//如果
(GCB_PreCheckIdStd (WID)= false)
则检查标识符{
//释放接收缓冲
区继续;
}//如果

//标准帧接收
到 stCanMsgBuffer.Ext = 0;

//复制 COB ID
stCanMsgBuffer.qbId.dw = WID;
#else
//检查29位标识
符 if (sCanMsgBuffer.Ext


= 1)& Extended ObjectMsgobj = 1;//
//获取 COB ID
//stCanMsgBuffer.qbId.dw = ReadDword (CAN_MID + CAN_TX_BUF
// + bBNr * CAN_MSG_OFFSET
// + CAN_BASE_ADR)& 0x1FFFFFFFUL;
stCanMsgBuffer.qbId.dw =(sMsgObjectRx.ui32MsgID & 0x1FFFFFFFUL);
}// if
else{

//标准帧接收
到 stRx MsgBuffer.Ext = 0;
//获取 COB ID stMsgBuffer.&sq_diRFid

?(0x07_&dMsgId.h



) 1:0);

//获取 DLC
stCnMsgBuffer.DLC =(字节)(sMsgObjectRx.ui32MsgLen & 0x0F);

//检查 DLC
if (stCnMsgBuffer.DLC > 8)
{stCnMsgObjectMsMsgBuffer.DLC =
8;
}// if

//复制消息数据字节=

3[stCnMsgDcmsMsgDb

= 4.dcmsMsgDb = 4.dcmsMsgDbsMsgDb = 3.db;sMsgDbpcmsMsgData.Db
= 3.dbdb = 3.dbdb = 3.db = 0[stCngDbdcmsgDb = 3.dcmsgDb = 3.dcmsgDbpcmsgDb = 3.dcmsgDb = 0];
stCanMsgBuffer.BDB[5]= sMsgObjectRx.pucMsgData[5];
stCanMsgBuffer.BDB[6]= sMsgObjectRx.pucMsgData[6];
stCanMsMsgBuffer.BDB[7]= sMsgObjectRx.puccygData[7];

if





}

/ eMsgOverlash = sMsgobj (如果丢失)、则为0;如果为0、则为0、则为0;如果为0、则为1


、则为0、则为0;如果为1、则为1、则为1、则为1、则为1、则为1、2、2、2、2、2、2、2、1、2、2、2、2、2、2、2、1、1、2、1、2、2、2、1

//假中断
{
//假中断处理可以在此处进行。
CANIntClear (CAN_BASE_ADR、CAN_INT_INT0ID_STATUS);
}// if
}// if

ulCANNDAT_21 >=1;
ulCANIPEN_21 >=1;
}//

针对//读取 CAN 中断状态以查找中断原因
ulCANINT = TempStatus (CAN_BASE_BASE)








;CANINT_INCR_INTR_INT_INTRL = 0xCANINT_INT_INT_INT_INT_INT_INCRB;CANINCR_INT_INTR_INT_INT_INTR_INT_INT_INT_INTRIGN = 0xINT_INT_INT_INT_INT_INT_INT_INT_INT_INTRIP_INT_INT_INT_INT_INT_INT_INTRIP_INT_INTRIGN;}

/*!
\brief CAN 错误 ISR。

CAN 错误中断服务例程。

此函数连接到 DCAN 中断0
*/
__interrupt void gCan_SysIntHandler (void)
{
unsigned long ulCANINT;
unsigned long ulCANES;

//设置中断优先级:
volatile UINT16 TempPIEIER = PieCtrlRegs.PIEIER9.all;
IER |= M_INT9;
IER&= MINT9; //设置"global"优先级
PieCtrlRegs.PIEIER9.all &= MG9_5;//设置"group"优先级
PieCtrlRegs.PIEACK.all = 0xFFFF;//启用 PIE 中断
__asm (" NOP");
EINT;

//设置中断计数器
IrqSysRicevuti+= CANINT 中断

状态
;CAN_INT_CANINT 中断状态
= CAN_INT_INT_INT_CAUST_INT_INT_INT_CAUST;

//读取控制器状态。 这将返回一个状态
//错误位字段,该字段可以指示各种错误。 为
简单起见、本示例中未执行错误处理//。 有关
错误状态位的详细信息、请参阅// API 文档。
//读取此状态的操作将清除中断。 如果
// CAN 外设未与其它 CAN 器件
//存在
的 CAN 总线连接,则会发生错误,并在//控制器状态中指示。
ulCANES = CANStatusGet (CAN_BASE_ADR、CAN_STS_CONTROL);

if (ulCANES & CAN_STATUS_EWARN)
{
//警告级别中断
bCANStatus |= CAN_STS_WARNING;
//未检测到脱离总线
的 bCANStatus &=~







~CAN_STS_BUS_OFF;}// if (ulCAN_STS_OFF)| CANNOT_WARNING
| CANST_OFF = CANNOT_STS_CANNOT_ST_OFF;CANNOT_STS_CANNOWN // if

(ulCANES & CAN_STATUS_BUS_OFF)
{
//脱离总线中断
bCANStatus |= CAN_STS_BUS_OFF;
//保持警告级别
bCANStatus &=~CAN_STS_WARNING;
}//如果

//增加 CAN 错误计数
器 RCANERR++;

DINT;
CANGALIntClear (CAN_STOP_WARNING)


;}CANINTRIGN = CAN_INTRIBUS_INTRISK;CAN_INTRIGN = CAN_INTRUS_INTRIGN

----
我的问题如下:
1) 1) FIFO 不能按我的预期工作:所有消息都存储在第一个邮箱中、如果中断代码在短时间内未读取数据、则会生成溢出错误。
2)掩码不能按我的预期工作:如果我没有将 MSG_OBJ_USE_ID_FILTER 开关放在 sMsgObjectRx.ui32Flags 中、DCAN 不会接收任何消息。 我必须放置 MSG_OBJ_USE_ID_FILTER 并设置掩码
0x00000000、以便能够从总线接收消息。
3) 3)如果我想用硬件过滤 CANOpen 对象 NMT=0x00、SYNC=0x80、EMCY=0x81、RxPDO1=0x181、TxPDO1=0x201、 RxPDO2=0x281、TxPDO2=0x301、RxPDO3=0x381、TxPDO3=0x401、
RxPDO4=0x481、TxPDO4=0x501、TxSDO=0x581、RxPDO=0x601、NMTera=0x701、 我不明白为什么 RxPDO=0x601根本不被接收。

有人可以帮助我、说我使用的代码是否有任何错误、尤其是在 Rx FIFO 设置中、我可以在其中找到任何代码示例、而我在中找到的非常小的示例则是如此
F2837xS_examples_CPU1目录?

最后但同样重要的是、为什么我无法使用 CodeComposerStudio 8.3查看 CAN 寄存器值?
DCAN 寄存器窗口中显示的值无效。

感谢您的关注
此致

Giuseppe

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

    您好 

    C2000Ware 中提供了一些示例供您参考。


    此致

    Harshmeet

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

    您好!

    感谢您的提示。

    我在 C2000ware 中看到了该示例、但与 F2837xS_Examples_CPU1目录中的示例相同。

    关于 ID 滤波器和掩码设置、我在这里找到了一些信息:

    www.cse.dmu.ac.uk/~eg/tele/CanbusIDandMask.html
    os.mbed.com/questions/85183/How-to-use-CAN-filter-function

    此时、硬件滤波器似乎运行良好。

    此致

    Giuseppe

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

    您好、MiaooaiM、

    还有什么可以帮助您的吗?

    否则、我将关闭 e2e 查询。

    此致

    Harshmeet

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

    目前、我对 CCS DCAN 寄存器显示问题没有任何回答。

    但我可以与以下人生活在一起:)

    谢谢你

    此致

    Giuseppe

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

    您可以在"Registers"窗口中引用寄存器值、在"Memory Browser"窗口中引用消息 RAM。

    此更新将很快提供。

    此致

    Harshmeet