Other Parts Discussed in Thread: C2000WARE
你好!附件是我使用寄存器配置F280049 DCAN收发的工程,但是收发失败,监控寄存器没有数据,请帮忙分析一下原因,看看配置哪里出了问题,谢谢!
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.
你好!附件是我使用寄存器配置F280049 DCAN收发的工程,但是收发失败,监控寄存器没有数据,请帮忙分析一下原因,看看配置哪里出了问题,谢谢!
#include "F28x_Project.h"
#include "device.h"
#include "math.h"
///////////DCan////////////////////////////
typedef struct{
Uint32 cob_id_ext:18;
Uint32 cob_id:11;
Uint32 rtr:1;
Uint32 rsvd1:2;
}CanFrameIdStr;
typedef union{
Uint32 frame_id;
CanFrameIdStr strct;
}CanFrameId;
typedef struct{
CanFrameId id;
Uint8 len;
Uint32 hdata;
Uint32 ldata;
}CanFrame;
//////////////////////////////////////////////////
void InitCan(void);
int CanAppTx(int no,CanFrame *tx_frame);
int CanAppRx(int no,CanFrame *rx_frame);
//
uint16_t Save_data;
uint16_t can_tx_result;
uint16_t can_rx_result;
CanFrame tx_data;
CanFrame rx_data;
void main(void)
{
// 初始化时钟和外设 Initialize device clock and peripherals
Device_init();
// InitSysCtrl(); //本工程不能使用寄存器的InitSysCtrl();函数初始化。
/*//库函数版配置
// 初始化GPIO并设置为推挽输出 Initialize GPIO and configure the GPIO pin as a push-pull output
Device_initGPIO();
*/
InitGpio(); //寄存器指令配置
//
InitCan();
// 初始化PIE并清空PIE寄存器,关闭CPU中断
// Initialize PIE and clear PIE registers. Disables CPU interrupts.
Interrupt_initModule();
// 初始化PIE向量表
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
Interrupt_initVectorTable();
// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
EINT;
ERTM;
for(;;)
{
//
tx_data.ldata =0x1234;
tx_data.hdata =0x4567;
tx_data.len =8;
tx_data.id.frame_id = 0x256;
can_tx_result = CanAppTx(0,&tx_data);
//
can_rx_result = CanAppRx(0,&rx_data);
}
}
/////////////////////////////DCan////////////////////////////
void InitCan( void )
{
int i;
EALLOW;
//引脚配置*************************************************
//CAN_B_RX
//mux = 2(0010)
GpioCtrlRegs.GPAGMUX1.bit.GPIO13 = 0x0;//10
GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 0x2;//10
GpioCtrlRegs.GPADIR.bit.GPIO13 = 0x0; //设置为输入
GpioCtrlRegs.GPAPUD.bit.GPIO13 = 0x0; //使能上拉电阻
//CAN_B_TX
//mux = 2(0010)
GpioCtrlRegs.GPAGMUX1.bit.GPIO12 = 0x0;//10
GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0x2;//10
GpioCtrlRegs.GPADIR.bit.GPIO12 = 0x1; //设置为输出
GpioCtrlRegs.GPAPUD.bit.GPIO12 = 0x0; //使能上拉电阻
//初始化开始*************************************************
CanbRegs.CAN_CTL.bit.Init = 1;
CanbRegs.CAN_CTL.bit.CCE = 1;
/*设置寄存器写方向,将arb和mctl写入消息对象*/
//CAN_IF1CMD
while(CanbRegs.CAN_IF1CMD.bit.Busy)
{
;
}
CanbRegs.CAN_IF1CMD.bit.DIR = 1;
CanbRegs.CAN_IF1CMD.bit.Mask = 1;
CanbRegs.CAN_IF1CMD.bit.Arb = 1;
CanbRegs.CAN_IF1CMD.bit.Control = 1;
CanbRegs.CAN_IF1MSK.all = 0;
CanbRegs.CAN_IF1ARB.bit.MsgVal = 1;
CanbRegs.CAN_IF1MCTL.bit.UMask = 1;
//CAN_IF2CMD
while(CanbRegs.CAN_IF2CMD.bit.Busy)
{
;
}
CanbRegs.CAN_IF2CMD.bit.DIR = 1;
CanbRegs.CAN_IF2CMD.bit.Mask = 1;
CanbRegs.CAN_IF2CMD.bit.Arb = 1;
CanbRegs.CAN_IF2CMD.bit.Control = 1;
CanbRegs.CAN_IF2MSK.all = 0;
CanbRegs.CAN_IF2ARB.bit.MsgVal = 1;
CanbRegs.CAN_IF2ARB.bit.Dir = 1;
CanbRegs.CAN_IF2MCTL.bit.UMask = 1;
CanbRegs.CAN_IF2MCTL.bit.RmtEn = 1;
/*1-16是接收,17-32是发送*/
for(i=1;i<=16;i++)
{
CanbRegs.CAN_IF1CMD.bit.MSG_NUM =i;
while(CanbRegs.CAN_IF1CMD.bit.Busy)
{
;
}
CanbRegs.CAN_IF2CMD.bit.MSG_NUM =i + 16;
while(CanbRegs.CAN_IF2CMD.bit.Busy)
{
;
}
}
/*最后一个设置为EOB,表示fifo的末尾*/
CanbRegs.CAN_IF1MCTL.bit.EoB = 1;
CanbRegs.CAN_IF2MCTL.bit.EoB = 1;
CanbRegs.CAN_IF1CMD.bit.MSG_NUM =16;
while(CanbRegs.CAN_IF1CMD.bit.Busy)
{
;
}
CanbRegs.CAN_IF2CMD.bit.MSG_NUM =32;
while(CanbRegs.CAN_IF2CMD.bit.Busy)
{
;
}
/*设置寄存器读方向,清除mctl的intpnd和newdat位*/
CanbRegs.CAN_IF1CMD.bit.TXRQST = 1;
CanbRegs.CAN_IF1CMD.bit.ClrIntPnd = 1;
CanbRegs.CAN_IF2CMD.bit.TxRqst = 1;
CanbRegs.CAN_IF2CMD.bit.ClrIntPnd = 1;
for(i=1;i<=16;i++)
{
CanbRegs.CAN_IF1CMD.bit.MSG_NUM =i;
while(CanbRegs.CAN_IF1CMD.bit.Busy)
{
;
}
CanbRegs.CAN_IF2CMD.bit.MSG_NUM =i + 16;
while(CanbRegs.CAN_IF2CMD.bit.Busy)
{
;
}
}
volatile Uint32 discardRead = CanbRegs.CAN_ES.all; //错误信息
/*波特率设置500k*/
ClkCfgRegs.CLKSRCCTL2.bit.CANBBCLKSEL = 0; //内部时钟100MHz
CanbRegs.CAN_BTR.bit.BRP = 9;
CanbRegs.CAN_BTR.bit.TSEG1 = 10;
CanbRegs.CAN_BTR.bit.TSEG2 = 7;
CanbRegs.CAN_BTR.bit.SJW =3;
//
CanbRegs.CAN_CTL.bit.DAR = 1;
CanbRegs.CAN_CTL.bit.ABO = 1;
//完成复位
CanbRegs.CAN_CTL.bit.Init = 0;
CanbRegs.CAN_CTL.bit.CCE = 0;
EDIS;
}
//*************接收数据***************************************
int CanAppTx(int no,CanFrame *tx_frame)
{
Uint32 regbase;
Uint32 cmd_regdata=0;
Uint32 arb_regdata=0;
Uint32 mctl_regdata=0;
Uint32 dataA=0,dataB=0;
int i,j;
if(no==0)
{
//regbase = CANA_BASE;
}
else
{
//regbase = CANB_BASE;
}
//错误复位
if(CanbRegs.CAN_ES.bit.EWarn)
{
CanbRegs.CAN_CTL.bit.Init = 1;
CanbRegs.CAN_CTL.bit.SWR = 1;
CanbRegs.CAN_CTL.bit.DAR = 1;
CanbRegs.CAN_CTL.bit.ABO = 1;
CanbRegs.CAN_CTL.bit.Init = 0;
return(0);
}
//
while(CanbRegs.CAN_IF1CMD.bit.Busy)
{
;
}
CanbRegs.CAN_IF1CMD.bit.Arb = 1;
CanbRegs.CAN_IF1CMD.bit.Mask = 1;
CanbRegs.CAN_IF1CMD.bit.Control = 1;
/*从17-32中寻找可以发送的邮箱*/
for(i=17;i<=32;i++)
{
CanbRegs.CAN_IF1CMD.bit.MSG_NUM = i;
while(CanbRegs.CAN_IF1CMD.bit.Busy)
{
;
}
if(CanbRegs.CAN_IF1MCTL.bit.TxRqst==0)
{
break;
}
}
if(i>=33)
{
return(-1);
}
/*读取当前邮箱配置信息*/
CanbRegs.CAN_IF1CMD.bit.Control = 1;
CanbRegs.CAN_IF1CMD.bit.MSG_NUM = i;
while(CanbRegs.CAN_IF1CMD.bit.Busy)
{
;
}
//
CanbRegs.CAN_IF1CMD.bit.DIR = 1;
CanbRegs.CAN_IF1CMD.bit.Arb = 1;
CanbRegs.CAN_IF1CMD.bit.Control = 1;
CanbRegs.CAN_IF1CMD.bit.DATA_A =1;
CanbRegs.CAN_IF1CMD.bit.DATA_B =1;
if(tx_frame->id.strct.rtr==0)
{
CanbRegs.CAN_IF1ARB.bit.Dir =1;
CanbRegs.CAN_IF1ARB.bit.MsgVal =1;
CanbRegs.CAN_IF1ARB.bit.ID = tx_frame->id.frame_id;
CanbRegs.CAN_IF1MCTL.bit.TxRqst =0;
CanbRegs.CAN_IF1MCTL.bit.DLC = tx_frame->len;
CanbRegs.CAN_IF1MCTL.bit.TxRqst =1;
//
for(j=0;j<4;j++)
{
dataA = dataA<<8;
dataA |= (tx_frame->hdata>>(j<<3))&0x0FF;
}
for(j=0;j<4;j++)
{
dataB = dataB<<8;
dataB |= (tx_frame->ldata>>(j<<3))&0x0FF;
}
}
else
{
CanbRegs.CAN_IF1MCTL.bit.DLC = tx_frame->len;
CanbRegs.CAN_IF1MCTL.bit.TxRqst = 1;
}
//
CanbRegs.CAN_IF1CMD.bit.MSG_NUM = i;
while(CanbRegs.CAN_IF1CMD.bit.Busy)
{
;
}
}
//*************接收数据*******************************************
/*1---rcv ok 0---no msg -1---msg lost*/
int CanAppRx(int no,CanFrame *rx_frame)
{
Uint32 cmd_regdata=0;
Uint32 arb_regdata=0;
Uint32 mctl_regdata=0;
Uint32 regbase;
int i,j;
//错误复位
if(CanbRegs.CAN_ES.bit.EWarn)
{
CanbRegs.CAN_CTL.bit.Init = 1;
CanbRegs.CAN_CTL.bit.SWR = 1;
CanbRegs.CAN_CTL.bit.DAR = 1;
CanbRegs.CAN_CTL.bit.ABO = 1;
CanbRegs.CAN_CTL.bit.Init = 0;
return(0);
}
//
while(CanbRegs.CAN_IF2CMD.bit.Busy)
{
;
}
CanbRegs.CAN_IF2CMD.bit.Arb = 1;
CanbRegs.CAN_IF2CMD.bit.Control = 1;
CanbRegs.CAN_IF2CMD.bit.DATA_A = 1;
CanbRegs.CAN_IF2CMD.bit.DATA_B = 1;
//
for(i=1;i<=32;i++)
{
CanbRegs.CAN_IF2CMD.bit.MSG_NUM = i;
while(CanbRegs.CAN_IF2CMD.bit.Busy)
{
;
}
if(CanbRegs.CAN_IF2MCTL.bit.NewDat !=0)
{
break;
}
}
//
if(i>=17)
{
return(0);
}
if(CanbRegs.CAN_IF2MCTL.bit.MsgLst!=0)
{
return(-1);
}
//
CanbRegs.CAN_IF2CMD.bit.Arb = 1;
CanbRegs.CAN_IF2CMD.bit.Mask = 1;
CanbRegs.CAN_IF2CMD.bit.Control = 1;
CanbRegs.CAN_IF2CMD.bit.DATA_A = 1;
CanbRegs.CAN_IF2CMD.bit.DATA_B = 1;
CanbRegs.CAN_IF2CMD.bit.MSG_NUM = i;
while(CanbRegs.CAN_IF2CMD.bit.Busy)
{
;
}
//
rx_frame->id.frame_id = 0;
if(((CanbRegs.CAN_IF2ARB.bit.Dir)&&(!(CanbRegs.CAN_IF2MCTL.bit.TxRqst)))||
((!(CanbRegs.CAN_IF2ARB.bit.Dir))&&(CanbRegs.CAN_IF2MCTL.bit.TxRqst)))
{
rx_frame->id.strct.rtr = 1;
}
//
rx_frame->id.frame_id |= CanbRegs.CAN_IF2ARB.bit.ID; //获取报文ID
rx_frame->len = CanbRegs.CAN_IF2MCTL.bit.DLC; //获取报文长度
//获取数据
if(rx_frame->id.strct.rtr==0)
{
for(j=0;j<4;j++)
{
rx_frame->hdata = CanbRegs.CAN_IF2DATB.all;
}
for(j=0;j<4;j++)
{
rx_frame->ldata = CanbRegs.CAN_IF2DATA.all;;
}
}
else
{
rx_frame->hdata = 0;
rx_frame->ldata = 0;
}
//
CanbRegs.CAN_IF2CMD.bit.TxRqst = 1;
CanbRegs.CAN_IF2CMD.bit.MSG_NUM = i;
while(CanbRegs.CAN_IF2CMD.bit.Busy)
{
;
}
return(1);
}
你好,具体是transmit还是receive的寄存器没有反应?
一般这款芯片都是基于driverlib编写的,看寄存器的话得花点时间,你有大概的方向说明一下吗?
你好,因为没经手过这款芯片的DCAN寄存器方式编程,我将你的工程的关键代码发送到英文E2E论坛咨询了一下,但是对方也没给出具体的问题所在,但是给出了2点建议,你可以参考一下:
https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1026132/tms320f280049-configure-can-module-in-register-mode
其实有些模块是有寄存器版本的,比如SCI,寄l存器版本的例程可以在这个路径找到:C:\ti\c2000\C2000Ware_3_04_00_00\device_support\f28004x\examples
但是例程不多,而且没有CAN模块的,不知道后续会不会更新。