CAN总线通讯问题
大家好,我用28335做发送器,stm32做接收器,但试验中,28335寄存器CANTA一直不置位,观察原因发现CANES.SMA位置1,CAN模块被激活挂起模式,控制器被冻结,我自己思考的原因是总线没有识别还有一个接收节点,所以将发送节点挂起,但问题是我之前用两块stm32做通讯的时候是成功的。为什么换了发送器后就变成这样了呢,我该怎么解决呢?求有经验的大神进来交流探讨一下。 "总线没有识别还有一个接收节点,所以将发送节点挂起"不应该是这样的, 总线不需要识别接收节点, 接收节点在正确收到数据后会自动给出应答. 主机也就知道了有节点收到了数据了. 所以你的问题很可能是从机没有正确收到数据包, 这种情况最可能出现的原因是波特率不一致. airwill 发表于 2015-6-22 15:13
"总线没有识别还有一个接收节点,所以将发送节点挂起"
不应该是这样的, 总线不需要识别接收节点, 接收节点 ...
谢谢你的回应,我的波特率应该是没问题,我想问一下,用示波器能看出波特率吗? 记得28335CAN通讯有两种模式吧,不知道你用的哪种。 JY-DX-JY 发表于 2015-6-23 15:18
记得28335CAN通讯有两种模式吧,不知道你用的哪种。
你是说回环和正常模式? 不是。28335的CAN是增强型的,我记得有增强模式和普通模式,你应该用普通模式。 JY-DX-JY 发表于 2015-6-23 17:30
不是。28335的CAN是增强型的,我记得有增强模式和普通模式,你应该用普通模式。 ...
你的意思是有16个和31个邮箱之分的?为什么不能用增强的,是ARM不接受吗 ARM应该不是增强模式,我以前试过。 JY-DX-JY 发表于 2015-6-23 18:26
ARM应该不是增强模式,我以前试过。
那CANMC.SCB赋值为0是不是就可以了呢?选择普通模式? 好像是的,手册上有说明,具体哪个寄存器我记不清了,现在不搞DSP了。你可以试一下。 JY-DX-JY 发表于 2015-6-23 18:43
好像是的,手册上有说明,具体哪个寄存器我记不清了,现在不搞DSP了。你可以试一下。 ...
先谢谢了,我试试,不懂再请教你 不客气。 JY-DX-JY 发表于 2015-6-23 19:49
不客气。
我试了一下,和之前情况一样,是不是还需要设置什么? 波特率,还有帧头,大概起始位的意思等。我也记不太清了,你最好贴出初始化代码。 JY-DX-JY 发表于 2015-6-23 21:09
波特率,还有帧头,大概起始位的意思等。我也记不太清了,你最好贴出初始化代码。 ...
这是DSP发送部分
void main()
{
struct ECAN_REGS ECanaShadow;
InitSysCtrl();
InitECanaGpio();
DINT;
InitPieCtrl();
IER=0x0000;
IFR=0x0000;
InitPieVectTable();
InitECana();
ECanaMboxes.MBOX6.MSGID.all = 0x81231314;
ECanaShadow.CANMD.all = ECanaRegs.CANMD.all;
ECanaShadow.CANMD.bit.MD6 = 0;
ECanaRegs.CANMD.all = ECanaShadow.CANMD.all;
ECanaShadow.CANME.all = ECanaRegs.CANME.all;
ECanaShadow.CANME.bit.ME6 = 1;
ECanaRegs.CANME.all = ECanaShadow.CANME.all;
ECanaMboxes.MBOX6.MSGCTRL.bit.DLC = 2;
ECanaMboxes.MBOX6.MSGCTRL.bit.RTR = 0;
ECanaMboxes.MBOX6.MSGCTRL.bit.TPL = 0;
while(1)
{
ECanaMboxes.MBOX6.MDL.all = 0x12;
ECanaMboxes.MBOX6.MDH.all = 0x87;
ECanaShadow.CANTRS.all = ECanaRegs.CANTRS.all;
ECanaShadow.CANTRS.all = 0;
ECanaShadow.CANTRS.bit.TRS6 = 1;
ECanaRegs.CANTRS.all = ECanaShadow.CANTRS.all;
do
{
ECanaShadow.CANTA.all = ECanaRegs.CANTA.all;
} while(ECanaShadow.CANTA.bit.TA6 == 0 );
ECanaShadow.CANTA.all = 0;
ECanaShadow.CANTA.bit.TA6 = 1;
ECanaRegs.CANTA.all = ECanaShadow.CANTA.all;
can设置部分
void InitECana(void) // Initialize eCAN-A module
{
struct ECAN_REGS ECanaShadow;
EALLOW; // EALLOW enables access to protected bits
/* Configure eCAN RX and TX pins for CAN operation using eCAN regs*/
ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all;
ECanaShadow.CANTIOC.all = 8;
ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all;
ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all;
ECanaShadow.CANRIOC.all = 8;
ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all;
/* Configure eCAN for HECC mode - (reqd to access mailboxes 16 thru 31) */
// HECC mode also enables time-stamping feature
ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
ECanaShadow.CANMC.bit.ABO = 1;
ECanaShadow.CANMC.bit.SCB = 0;
ECanaShadow.CANMC.bit.STM = 0;
ECanaShadow.CANMC.bit.CDR = 1;
ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
ECanaMboxes.MBOX0.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX1.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX2.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX3.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX4.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX5.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX6.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX7.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX8.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX9.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX10.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX11.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX12.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX13.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX14.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX15.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX16.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX17.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX18.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX19.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX20.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX21.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX22.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX23.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX24.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX25.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX26.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX27.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX28.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX29.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX30.MSGCTRL.all = 0x00000000;
ECanaMboxes.MBOX31.MSGCTRL.all = 0x00000000;
// TAn, RMPn, GIFn bits are all zero upon reset and are cleared again
// as a matter of precaution.
ECanaShadow.CANTA.all = ECanaRegs.CANTA.all;
ECanaShadow.CANTA.all = 0xFFFFFFFF; /* Clear all TAn bits */
ECanaRegs.CANTA.all = ECanaShadow.CANTA.all;
ECanaShadow.CANRMP.all = ECanaRegs.CANRMP.all;
ECanaRegs.CANRMP.all = 0xFFFFFFFF; /* Clear all RMPn bits */
ECanaRegs.CANRMP.all = ECanaShadow.CANRMP.all;
ECanaRegs.CANGIF0.all = 0xFFFFFFFF; /* Clear all interrupt flag bits */
ECanaRegs.CANGIF1.all = 0xFFFFFFFF;
/* Configure bit timing parameters for eCANA*/
ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
ECanaShadow.CANMC.bit.CCR = 1 ; // Set CCR = 1
ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
// ECanaShadow.CANES.all = ECanaRegs.CANES.all;
do
{
ECanaShadow.CANES.all = ECanaRegs.CANES.all;
} while(ECanaShadow.CANES.bit.CCE != 1 ); // Wait for CCE bit to be set..
ECanaShadow.CANBTC.all = 0;
//#if (CPU_FRQ_150MHZ) // CPU_FRQ_150MHz is defined in DSP2833x_Examples.h
/* The following block for all 150 MHz SYSCLKOUT (75 MHz CAN clock) - default. Bit rate = 1 Mbps
See Note at End of File */
ECanaShadow.CANBTC.bit.BRPREG = 9;
ECanaShadow.CANBTC.bit.TSEG2REG = 2;
ECanaShadow.CANBTC.bit.TSEG1REG = 10;
// ECanaShadow.CANBTC.bit.BRPREG =14 ;
// ECanaShadow.CANBTC.bit.TSEG2REG = 5;
// ECanaShadow.CANBTC.bit.TSEG1REG = 12;
//#endif
// #if (CPU_FRQ_100MHZ) // CPU_FRQ_100MHz is defined in DSP2833x_Examples.h
/* The following block is only for 100 MHz SYSCLKOUT (50 MHz CAN clock). Bit rate = 1 Mbps
See Note at End of File */
// ECanaShadow.CANBTC.bit.BRPREG = 4;
// ECanaShadow.CANBTC.bit.TSEG2REG = 1;
// ECanaShadow.CANBTC.bit.TSEG1REG = 6;
// #endif
ECanaShadow.CANBTC.bit.SAM = 1;
ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all;
ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
ECanaShadow.CANMC.bit.CCR = 0 ; // Set CCR = 0
ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
//ECanaShadow.CANES.all = ECanaRegs.CANES.all;
do
{
ECanaShadow.CANES.all = ECanaRegs.CANES.all;
} while(ECanaShadow.CANES.bit.CCE != 0 ); // Wait for CCE bit to becleared..
/* Disable all Mailboxes*/
ECanaRegs.CANME.all = 0; // Required before writing the MSGIDs
EDIS;
} 本帖最后由 fishyy 于 2015-6-23 21:54 编辑
JY-DX-JY 发表于 2015-6-23 21:09
波特率,还有帧头,大概起始位的意思等。我也记不太清了,你最好贴出初始化代码。 ...
这是ARM接受部分
__IO uint32_t flag = 0xff;
CanTxMsg TxMessage; //发送缓冲区
CanRxMsg RxMessage; //接收缓冲区
/*
* 函数名:main
* 描述: “从机”的主函数
* 输入:无
* 输出: 无
*/
int main(void)
{
/*初始化配置CAN*/
CAN_Config();
/*等待数据,接收数据*/
while(1)
{
while( flag == 0xff );
IDEx=RxMessage.ExtId;
IDSt=RxMessage.StdId;
DATA0=RxMessage.Data;
DATA1=RxMessage.Data;
}
}
can设置部分
extern CanTxMsg TxMessage;
/*
* 函数名:CAN_GPIO_Config
* 描述:CAN的GPIO 配置,PB8上拉输入,PB9推挽输出
* 输入:无
* 输出: 无
* 调用:内部调用
*/
static void CAN_GPIO_Config(void)
{
/*定义一个GPIO_InitTypeDef类型的结构体*/
GPIO_InitTypeDef GPIO_InitStructure;//三个成员,引脚号,引脚模式,引脚速度
/*外设时钟设置*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);//打开AFIO,开启复用时钟,用于引脚重映射
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//打开CAN的时钟
/*IO设置*/
GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);//将CAN功能映射到引脚
/*接收引脚设置*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //选择8号引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入,作为接收引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//引脚最大输入速度为50M
GPIO_Init(GPIOB, &GPIO_InitStructure);//调用库函数,初始化GPIOB
/*发送引脚设置*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;// 复用推挽输出,作为发送引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/*
* 函数名:CAN_NVIC_Config
* 描述:CAN的NVIC 配置,第1优先级组,0,0优先级
* 输入:无
* 输出: 无
* 调用:内部调用
*/
static void CAN_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //选择2*8优先级模式
/*中断设置*/
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;//CAN1 RX0中断占用优先级通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级0(最高)
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//子优先级为0(最高)
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//在成员NVIC_IRQChannel中定义的IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);//初始化
}
/*
* 函数名:CAN_Mode_Config
* 描述:CAN的模式 配置
* 输入:无
* 输出: 无
* 调用:内部调用
*/
static void CAN_Mode_Config(void)
{
CAN_InitTypeDef CAN_InitStructure;
/*CAN寄存器初始化*/
CAN_DeInit(CAN1);//设置成缺省值
CAN_StructInit(&CAN_InitStructure);//初始化
/*CAN单元初始化*/
CAN_InitStructure.CAN_TTCM=DISABLE; //MCR-TTCM时间触发通信模式使能
CAN_InitStructure.CAN_ABOM=DISABLE; //MCR-ABOM自动离线管理
CAN_InitStructure.CAN_AWUM=DISABLE; //MCR-AWUM自动唤醒模式
CAN_InitStructure.CAN_NART=DISABLE; //MCR-NART禁止报文自动重传 DISABLE-自动重传
CAN_InitStructure.CAN_RFLM=DISABLE; //MCR-RFLM接收FIFO 锁定模式DISABLE-溢出时新报文会覆盖原有报文
CAN_InitStructure.CAN_TXFP=DISABLE; //MCR-TXFP发送FIFO优先级 DISABLE-优先级取决于报文标示符
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;//正常发送模式
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 2个时间单元
CAN_InitStructure.CAN_BS1=CAN_BS1_5tq; //BTR-TS1 时间段1 占用了6个时间单元
CAN_InitStructure.CAN_BS2=CAN_BS2_3tq; //BTR-TS1 时间段2 占用了3个时间单元
CAN_InitStructure.CAN_Prescaler =8; //BTR-BRP 波特率分频器定义了时间单元的时间长度 36/(1+5+3)/8=0.5Mbps
// CAN_InitStructure.CAN_BS1=CAN_BS1_7tq; //BTR-TS1 时间段1 占用了6个时间单元
// CAN_InitStructure.CAN_BS2=CAN_BS2_4tq; //BTR-TS1 时间段2 占用了3个时间单元
// CAN_InitStructure.CAN_Prescaler =12; //36/12/(7+4+1)=0.25M
CAN_Init(CAN1, &CAN_InitStructure);//初始化
}
/*
* 函数名:CAN_Filter_Config
* 描述:CAN的过滤器 配置
* 输入:无
* 输出: 无
* 调用:内部调用
*/
static void CAN_Filter_Config(void)
{
CAN_FilterInitTypeDefCAN_FilterInitStructure;
/*CAN过滤器初始化*/
CAN_FilterInitStructure.CAN_FilterNumber=0; //过滤器组0
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //工作在标识符屏蔽位模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //过滤器位宽为单个32位。
/* 使能报文标示符过滤器按照标示符的内容进行比对过滤,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO0。 */
CAN_FilterInitStructure.CAN_FilterIdHigh= 0x0000; //要过滤的ID高位
CAN_FilterInitStructure.CAN_FilterIdLow= 0x0000; //要过滤的ID低位
// CAN_FilterInitStructure.CAN_FilterIdHigh= (((u32)0x1314<<3)&0xFFFF0000)>>16; //要过滤的ID高位
//6CAN_FilterInitStructure.CAN_FilterIdLow= (((u32)0x1314<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF; //要过滤的ID低位
//CAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0xFFFF; //过滤器高16位每位必须匹配
CAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0x0000; //ID全部接受
//CAN_FilterInitStructure.CAN_FilterMaskIdLow= 0xFFFF; //过滤器低16位每位必须匹配
CAN_FilterInitStructure.CAN_FilterMaskIdLow= 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0 ; //过滤器被关联到FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //使能过滤器
CAN_FilterInit(&CAN_FilterInitStructure);//初始化
/*CAN通信中断使能*/
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
}
/*
* 函数名:CAN_Config
* 描述:完整配置CAN的功能
* 输入:无
* 输出: 无
* 调用:外部调用
*/
void CAN_Config(void)
{
CAN_GPIO_Config();
CAN_NVIC_Config();
CAN_Mode_Config();
CAN_Filter_Config();
}
ECanaMboxes.MBOX6.MSGID.all = 0x81231314;
这个大概就是帧头吧,好想和你ARM的不一样。 JY-DX-JY 发表于 2015-6-24 08:48
ECanaMboxes.MBOX6.MSGID.all = 0x81231314;
这个大概就是帧头吧,好想和你ARM的不一样。 ...
观察的很仔细。:) JY-DX-JY 发表于 2015-6-24 08:48
ECanaMboxes.MBOX6.MSGID.all = 0x81231314;
这个大概就是帧头吧,好想和你ARM的不一样。 ...
这个就是标识符,在ARM里,我设置的是无论什么ID都不过滤,所以应该没有影响吧? 应该不影响。你28335用的CAN的数据腿是哪两个?有没有设置?
页:
[1]
2