OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3536|回复: 7

STM32CAN通信问题

[复制链接]

12

主题

36

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2394
金钱
2394
注册时间
2016-4-14
在线时间
225 小时
发表于 2016-4-29 13:29:58 | 显示全部楼层 |阅读模式
1金钱
在进行CAN通信测试时,如果CAN接收采用中断模式,在回环模式下,CAN能够进入接收中断并将接收到的数据通过串口打印出来,是不是说明CAN的初始化还有接收发送就是没有问题的?现在在用一块F072的板子测试CAN,在回环模式下能够看到CAN打印出的接收数据,但是改成正常模式,通过CAN卡无法在上位机上显示出来,请问最可能哪里有问题呢?是不是说CAN回环无错误,就说明软件端配置无问题,波特率已经选择和CAN卡相同了。

最佳答案

查看完整内容[请看2#楼]

CAN回环模式说明软件没有问题,但是你实际连接的时候硬件可能会有问题的。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

391

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1957
金钱
1957
注册时间
2014-8-8
在线时间
307 小时
发表于 2016-4-29 13:29:59 | 显示全部楼层
hechuanxi0312 发表于 2016-4-29 17:35
改了之后,还是没什么反应。不知道是不是072这个板子的CAN硬件的问题。对于CAN来说,是不是CAN回环模式无 ...

CAN回环模式说明软件没有问题,但是你实际连接的时候硬件可能会有问题的。
回复

使用道具 举报

2

主题

391

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1957
金钱
1957
注册时间
2014-8-8
在线时间
307 小时
发表于 2016-4-29 14:48:34 | 显示全部楼层
重复提问?我记得回答过了啊?你有什么不明白的?
回复

使用道具 举报

12

主题

36

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2394
金钱
2394
注册时间
2016-4-14
在线时间
225 小时
 楼主| 发表于 2016-4-29 14:52:19 | 显示全部楼层
365mcu 发表于 2016-4-29 14:48
重复提问?我记得回答过了啊?你有什么不明白的?

之前是用两块103的板子来调试的,现在将其中一块换成了F072进行通信,103的确认能够进行正常的收发,并且用上位机CAN卡能够检测到CAN数据。F072的板子利用自身的CAN回环模式将数据发送到串口能够在串口显示数据,但是F072的板子无法与上位机CAN卡通信,所以有此一问。
回复

使用道具 举报

2

主题

391

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1957
金钱
1957
注册时间
2014-8-8
在线时间
307 小时
发表于 2016-4-29 15:04:16 | 显示全部楼层
hechuanxi0312 发表于 2016-4-29 14:52
之前是用两块103的板子来调试的,现在将其中一块换成了F072进行通信,103的确认能够进行正常的收发,并且 ...

一般跟踪CAN发送是能够查处问题来的,可能是你CAN总线离线后没有自动重连,你配置CAN的程序发来看一下
[mw_shl_code=c,true]  FunctionalState CAN_ABOM;  /*!< Enable or disable the automatic bus-off management.
                                 This parameter can be set either to ENABLE or DISABLE. */[/mw_shl_code]
回复

使用道具 举报

12

主题

36

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2394
金钱
2394
注册时间
2016-4-14
在线时间
225 小时
 楼主| 发表于 2016-4-29 16:52:11 | 显示全部楼层
本帖最后由 hechuanxi0312 于 2016-4-29 16:54 编辑
365mcu 发表于 2016-4-29 15:04
一般跟踪CAN发送是能够查处问题来的,可能是你CAN总线离线后没有自动重连,你配置CAN的程序发来看一下
[ ...

[mw_shl_code=c,true]u8 CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        CAN_InitTypeDef CAN_InitStructure;
        CAN_FilterInitTypeDef CAN_FilterInitStructure;        
        #if CAN_RX_INT_ENABLE //是否使能CAN接收中断
                NVIC_InitTypeDef NVIC_InitStructure;
        #endif
        
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);//使能CAN对应的管脚的时钟
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN,ENABLE);//使能CAN时钟
        
        GPIO_PinAFConfig(GPIOB,GPIO_PinSource8,GPIO_AF_4);//选择CAN管脚的复用功能,PB8->RX
        GPIO_PinAFConfig(GPIOB,GPIO_PinSource9,GPIO_AF_4);//选贼CAN管交的复用功能,PB9->TX
/*初始化CAN管脚*/
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        /*CAN相关设置*/
        /* CAN register init */
        CAN_DeInit(CAN);
        CAN_StructInit(&CAN_InitStructure);
        /*CAN单元设置*/
        CAN_InitStructure.CAN_TTCM = DISABLE; /* 时间触发禁止, 时间触发:CAN硬件的内部定时器被激活,并且被用于产生时间戳 */
        CAN_InitStructure.CAN_ABOM = DISABLE; /* 自动离线禁止,自动离线:一旦硬件监控到128次11个隐性位,就自动退出离线状态。在这里要软件设定后才能退出 */
        CAN_InitStructure.CAN_AWUM = DISABLE; /* 自动唤醒禁止,有报文来的时候自动退出休眠        */
        CAN_InitStructure.CAN_NART = DISABLE; /* 报文重传, 如果错误一直传到成功止,否则只传一次 */
        CAN_InitStructure.CAN_RFLM = DISABLE; /* 接收FIFO锁定, 1--锁定后接收到新的报文摘不要,0--接收到新的报文则覆盖前一报文        */
        CAN_InitStructure.CAN_TXFP = ENABLE;  /* 发送优先级  0---由标识符决定  1---由发送请求顺序决定        */
        CAN_InitStructure.CAN_Mode = mode;//模式设置: mode:0,普通模式;1,回环模式;
        CAN_InitStructure.CAN_SJW = tsjw;//重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位  CAN_SJW_1tq~CAN_SJW_4tq
        CAN_InitStructure.CAN_BS1 = tbs1;//Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq
        CAN_InitStructure.CAN_BS2 = tbs2;//Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~CAN_BS2_8tq
        CAN_InitStructure.CAN_Prescaler = brp;//分频系数(Fdiv)为brp+1        
        CAN_Init(CAN,&CAN_InitStructure);
        /*CAN滤波设置*/
        CAN_FilterInitStructure.CAN_FilterNumber=0;     /* 过滤器0 */
        CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;  /* 屏敝模式 */
        CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; /* 32位 */
        CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;  /* 以下四个都为0, 表明不过滤任何id */
        CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;//32位ID
        CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
        CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;//32位MASK
        CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;  /* 能够通过该过滤器的报文存到fifo0中 */
        CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;//激活过滤器0
        CAN_FilterInit(&CAN_FilterInitStructure);
        
        #if CAN_RX_INT_ENABLE//是否使能CAN接收中断
                NVIC_InitStructure.NVIC_IRQChannel = CEC_CAN_IRQn;//设定CAN中断的通道
                NVIC_InitStructure.NVIC_IRQChannelPriority = 0;//CAN中断优先级
                NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能中断
                NVIC_Init(&NVIC_InitStructure);//初始化
                CAN_ITConfig(CAN,CAN_IT_FMP0, ENABLE);//FIFO0消息挂号中断使能
        #endif
        return 0;
}[/mw_shl_code]
这是我初始化CAN的
[mw_shl_code=c,true]u8 Can_Send_Msg(u16 stdID,u8* msg,u8 len)
{
        u8 mbox;
        u16 i=0;
        CanTxMsg TxMessage;
        LED2_Toggle();
       
        TxMessage.StdId = stdID;//标准CANID标识符
        //TxMessage.ExtId = 0x00;//设置扩展ID
        TxMessage.IDE = CAN_Id_Standard;//标识标准帧,使用标准ID
        TxMessage.RTR = CAN_RTR_DATA;//标识是数据帧
        TxMessage.DLC = len;//要发送的数据长度
        for(i=0;i<len;i++)//要发送的数据
        {
                TxMessage.Data=msg;
        }
        mbox = CAN_Transmit(CAN,&TxMessage);//发送数据,返回这个信息请求发送的邮箱号0,1,2或没有邮箱申请发送no_box
        i=0;
        while((CAN_TransmitStatus(CAN, mbox)==CAN_TxStatus_Failed)&&(i<0XFFF))
                i++;        //等待发送结束
        if(i>=0XFFF)
                return 1;
        return 0;         
}[/mw_shl_code]
这是发送CAN的

[mw_shl_code=c,true]void CEC_CAN_IRQHandler(void)
{
        CanRxMsg RxMessage;
        //u32 CAN_StdId,Can_ExtId;//接收到的CAN的ID
        u8 CAN_DATA[8];//接收到的CAN的数据
        u16 i;
        LED1_Toggle();
        //u8 CAN_IDE,CAN_RTR,CAN_DLC;//接收到的CAN的其他数据,需要时使用       
        CAN_Receive(CAN,CAN_FIFO0,&RxMessage);//此函数包含释放提出报文了的,在非必要时,不需要自己释放
        //CAN_StdId = RxMessage.StdId;//接收到的CANID
        //Can_ExtId = RxMessage.ExtId;
        CAN_DATA[0] = RxMessage.Data[0];
        CAN_DATA[1] = RxMessage.Data[1];
        CAN_DATA[2] = RxMessage.Data[2];
        CAN_DATA[3] = RxMessage.Data[3];
        CAN_DATA[4] = RxMessage.Data[4];
        CAN_DATA[5] = RxMessage.Data[5];
        CAN_DATA[6] = RxMessage.Data[6];
        CAN_DATA[7] = RxMessage.Data[7];
        for(i=0;i<8;i++)
                printf("receive data:0X%X,\r\n",RxMessage.Data);  
        //CAN_ClearITPendingBit(CAN,CAN_IT_FMP0);  /* 清除挂起中断 */       
}[/mw_shl_code]
这是接收中断



回复

使用道具 举报

2

主题

391

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1957
金钱
1957
注册时间
2014-8-8
在线时间
307 小时
发表于 2016-4-29 16:58:53 | 显示全部楼层
hechuanxi0312 发表于 2016-4-29 16:52
[mw_shl_code=c,true]u8 CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
{
        GPIO_Ini ...

[mw_shl_code=c,true]CAN_InitStructure.CAN_ABOM = DISABLE; /* 自动离线禁止,自动离线:一旦硬件监控到128次11个隐性位,就自动退出离线状态。在这里要软件设定后才能退出 */[/mw_shl_code]
改成ENABLE
回复

使用道具 举报

12

主题

36

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2394
金钱
2394
注册时间
2016-4-14
在线时间
225 小时
 楼主| 发表于 2016-4-29 17:35:52 | 显示全部楼层
365mcu 发表于 2016-4-29 16:58
[mw_shl_code=c,true]CAN_InitStructure.CAN_ABOM = DISABLE; /* 自动离线禁止,自动离线:一旦硬件监控 ...

改了之后,还是没什么反应。不知道是不是072这个板子的CAN硬件的问题。对于CAN来说,是不是CAN回环模式无问题,表明初始化还有发送接收中断软件部分就没啥问题了呢?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-16 00:39

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表