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