你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F105VC的双路CAN通信问题。求大神们帮忙

[复制链接]
lwdawx 提问时间:2016-5-26 15:16 /
我用的STM32F105VC芯片LQFP100脚做的双路CAN通信,现在是CAN2功能正常,CAN1通信异常。CAN1,CAN2的代码基本一样,波特率是500kbps。软件方面:CAN1是完全映射到PD0,PD1上面,在回环模式下,CAN1通信正常,且可以在CAN1_TX上面量到波形;正常通信模式下,CAN1通信失败。调试使用的是周立功的CAN卡通信。

硬件方面:电脑用CAN卡向CAN1发送数据,可以在单片机STM32F105的CAN1_RX处用示波器量到正常脉冲,但是CAN1不进中断,不接受。CAN卡也显示通信异常。CAN收发器用的ADI的ADM3053隔离型。并且做了2块PCB都是这种情况,以下是我的CAN初始化代码,希望大家可以帮忙看看!

/*********************************************************************************
功能说明:CAN1模式初始化配置
          CAN1的过滤器为0~13,过滤器关联到FIFO 0
*********************************************************************************/
void CAN1_Mode_Init(void)
{

                GPIO_InitTypeDef       GPIO_InitStructure;
                CAN_InitTypeDef        CAN_InitStructure;
                CAN_FilterInitTypeDef  CAN_FilterInitStructure;

           NVIC_InitTypeDef  NVIC_InitStructure;


          RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);//使能PORTD时钟                         
          RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟       
               
       
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;            
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽
    GPIO_Init(GPIOD, &GPIO_InitStructure);                //初始化IO    CAN1 TX
       
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
    GPIO_Init(GPIOD, &GPIO_InitStructure);//初始化IO       CAN1 RX
               
                GPIO_PinRemapConfig(GPIO_Remap2_CAN1 , ENABLE); //CAN1完全重映射到PD0,PD1
               
       
                CAN_DeInit(CAN1); //复位CAN寄存器
          CAN_StructInit(&CAN_InitStructure);  //填充CAN参数结构体成员为缺省值
          //CAN单元设置
                CAN_InitStructure.CAN_TTCM=DISABLE;                                                 //非时间触发通信模式  //
                CAN_InitStructure.CAN_ABOM=DISABLE;                                                 //软件自动离线管理         //
          CAN_InitStructure.CAN_AWUM=DISABLE;                                                 //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)//
          CAN_InitStructure.CAN_NART=ENABLE;                                                         //禁止报文自动传送 //
          CAN_InitStructure.CAN_RFLM=DISABLE;                                                 //报文不锁定,新的覆盖旧的 //
          CAN_InitStructure.CAN_TXFP=DISABLE;                                                 //优先级由报文标识符决定 //
          CAN_InitStructure.CAN_Mode= CAN_Mode_Normal;                 //模式设置: mode:0,普通模式;1,回环模式; //
          //设置波特率
                //CAN 波特率 = RCC_APB1Periph_CAN / Prescaler /(sjw + bs1 +bs2)
                //CAN 波特率 = 36000000/8/(1+4+4)=500kbps
                CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;      //重复同步跳跃宽度为个实际单位
                CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq;      //时间段1占用4个时间单位
                CAN_InitStructure.CAN_BS2 = CAN_BS2_4tq;      //时间段2占用4个时间单位
                CAN_InitStructure.CAN_Prescaler = 8;          //分频系数为8
          CAN_Init(CAN1, &CAN_InitStructure);            // 初始化CAN1
               

                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;////32位滤波器ID
          CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
          CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK ID
          CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
          CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0
                CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0
          CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化 CAN1
               
                NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn ;
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;     // 主优先级为0
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;            // 次优先级为0
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
          NVIC_Init(&NVIC_InitStructure);
          
       
                CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许.                                                   
         

}  
/**********************************************************************************
功能说明:CAN2模式初始化配置
          CAN2的过滤器配置为14~28,过滤器关联到FIFO 1
**********************************************************************************/
void CAN2_Mode_Init(void)
{

                GPIO_InitTypeDef GPIO_InitStructure;
                CAN_InitTypeDef        CAN_InitStructure;
                CAN_FilterInitTypeDef  CAN_FilterInitStructure;

           NVIC_InitTypeDef  NVIC_InitStructure;


                RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);//使能PORTB时钟                                                                                                                            
                RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);//使能CAN2时
       
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;            
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽
    GPIO_Init(GPIOB, &GPIO_InitStructure);                //初始化IO    CAN2 TX

       
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
    GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化IO       CAN2 RX

                GPIO_PinRemapConfig(GPIO_Remap_CAN2 , ENABLE);
          CAN_DeInit(CAN2); //复位CAN寄存器
          CAN_StructInit(&CAN_InitStructure);  //填充CAN参数结构体成员为缺省值
          //CAN单元设置
                CAN_InitStructure.CAN_TTCM=DISABLE;                                                 //非时间触发通信模式  //
                CAN_InitStructure.CAN_ABOM=DISABLE;                                                 //软件自动离线管理         //
          CAN_InitStructure.CAN_AWUM=DISABLE;                                                 //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)//
          CAN_InitStructure.CAN_NART=ENABLE;                                                         //禁止报文自动传送 //
          CAN_InitStructure.CAN_RFLM=DISABLE;                                                 //报文不锁定,新的覆盖旧的 //
          CAN_InitStructure.CAN_TXFP=DISABLE;                                                 //优先级由报文标识符决定 //
          CAN_InitStructure.CAN_Mode= CAN_Mode_Normal;                 //模式设置: mode:0,普通模式;1,回环模式; //
          //设置波特率
                //CAN 波特率 = RCC_APB1Periph_CAN / Prescaler /(sjw + bs1 +bs2)
                //CAN 波特率 = 36000000/8/(1+4+4)=500kbps
                CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
                CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq;
                CAN_InitStructure.CAN_BS2 = CAN_BS2_4tq;
                CAN_InitStructure.CAN_Prescaler = 8;
                CAN_Init(CAN2, &CAN_InitStructure);            // 初始化CAN2
               

                CAN_FilterInitStructure.CAN_FilterNumber=14;          //过滤器0
                CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
          CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位
          CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;////32位ID
          CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
          CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK
          CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
          CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO1;//过滤器0关联到FIFO1
                CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0
          CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化 CAN2
                    
//                CAN_ITConfig(CAN2,CAN_IT_FMP1,ENABLE);       
               
          NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX1_IRQn;
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0;     // 主优先级为0
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;            // 次优先级为0
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
          NVIC_Init(&NVIC_InitStructure);
               
                CAN_ITConfig(CAN2,CAN_IT_FMP1,ENABLE);

}




/**********************************************************************************
功能说明:CAN1 FIFO0 接收中断
***********************************************************************************/
void CAN1_RX0_IRQHandler(void)
{   
          u32 i;
                u16 CAN1RxID=0;
                CanRxMsg RxMessage;
          CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);//
                CAN1RxID=        RxMessage.StdId;  //标准ID
                for(i=0;i<Max_Canidex;i++)
                {
                                if(CAN1_RX_BUF[i][10]==0) //最后1个字节的接收标志位 0:没有接收到数据 1:接收到数据
        {
            memcpy(&(CAN1_RX_BUF[i][0]),&CAN1RxID,2); //前两个字节是ID
            memcpy(&(CAN1_RX_BUF[i][2]),RxMessage.Data,8);//8个字节的数据
            CAN1_RX_BUF[i][10] =1;
            break;
        }
                }
                  CAN1_Receive_flag = 1;
                        LED0=~LED0;
}

/***********************************************************************************
功能说明:CAN2 FIFO1 接收中断
***********************************************************************************/
void CAN2_RX1_IRQHandler(void)
{
                u32 i;
                u16 CAN2RxID=0;
                CanRxMsg RxMessage;
          CAN_Receive(CAN2, CAN_FIFO1, &RxMessage);
                CAN2RxID=        RxMessage.StdId;
                for(i=0;i<Max_Canidex;i++)
                {
                                if(CAN2_RX_BUF[i][10]==0)
        {
            memcpy(&(CAN2_RX_BUF[i][0]),&CAN2RxID,2);
            memcpy(&(CAN2_RX_BUF[i][2]),RxMessage.Data,8);
            CAN2_RX_BUF[i][10] =1;
          break;
        }
                }
                  CAN2_Receive_flag = 1;
                        LED1=~LED1;
                 
}


/*************************************************************************************
功能说明:CAN1发送函数

//can发送1组8个字节数据
//CanStdID:发送数据的ID
//CanData:发送的数据指针
//返回值:0,成功;
//                 其他,失败;
*************************************************************************************/
u8 Can1_SendData(u16 CanStdID, u8 *CanData)
{
                CanTxMsg TxMessage;
          u8 i;
          u8 CanTx_check = 0;
                u8 Mailbox = 0;
          
                TxMessage.StdId = CanStdID;   //标准标识符
          TxMessage.ExtId = 0;
          TxMessage.IDE = CAN_ID_STD;  //使用标准标示符
          TxMessage.RTR = CAN_RTR_DATA;//数据帧
                TxMessage.DLC = 8;
          
                for(i = 0;i < 7;i++)
                CanTx_check += CanData[i];
                CanTx_check = -CanTx_check+1;   //校验和
                CanData[7] = CanTx_check;
          
    memcpy(TxMessage.Data, CanData, 8);
          
          Mailbox = CAN_Transmit(CAN1, &TxMessage);
          i = 0;
          while((CAN_TransmitStatus(CAN1,Mailbox) != CAN_TxStatus_Ok) && (i < 0xff))//等待发送结束
                i++;
                if(i >= 0xff)   return 1;
                return 0;
}


/***********************************************************************************
功能说明:CAN2发送函数
************************************************************************************/
u8 Can2_SendData(u16 CanStdID, u8 *CanData)
{
                CanTxMsg TxMessage;
          u8 i;
          u8 CanTx_check = 0;
                u8 Mailbox = 0;
          
                TxMessage.StdId = CanStdID;   
          TxMessage.ExtId = 0;
          TxMessage.IDE = CAN_ID_STD;
          TxMessage.RTR = CAN_RTR_DATA;
                TxMessage.DLC = 8;
          
                for(i = 0;i < 7;i++)
                        CanTx_check += CanData[i];
                CanTx_check = -CanTx_check+1;   //校验和
                CanData[7] = CanTx_check;
          
    memcpy(TxMessage.Data, CanData, 8); //将CanData数组中的数据拷贝到TxMessage.Data中
          
          Mailbox = CAN_Transmit(CAN2, &TxMessage); //范围值是邮箱号码,如果没有空邮箱返回CAN_NO_MB
          i = 0;
          while((CAN_TransmitStatus(CAN2,Mailbox) != CAN_TxStatus_Ok) && (i < 0xff)) //等待发送结束
                                i++;
                if(i >= 0xff)   return 1;
                return 0;
}


收藏 1 评论11 发布时间:2016-5-26 15:16

举报

11个回答
xmshao 回答时间:2016-5-27 16:49:35
按理说 你软件配置应该没啥问题了。

你的启动文件是否正确? 要选startup_stm32f10x_cl.s
lwdawx 回答时间:2016-5-28 09:22:43
xmshao 发表于 2016-5-27 16:49
按理说 你软件配置应该没啥问题了。

你的启动文件是否正确? 要选startup_stm32f10x_cl.s ...

启动文件没有问题,我已经调试好了用到的4个串口,2个SPI,ADC,I2C等其他功能了,就剩这个CAN1啦。
yklstudent 回答时间:2016-5-28 12:17:10
lwdawx 发表于 2016-5-28 09:22
启动文件没有问题,我已经调试好了用到的4个串口,2个SPI,ADC,I2C等其他功能了,就剩这个CAN1啦。 ...

你的项目够大的,需要用到这么多功能
xmshao 回答时间:2016-5-28 16:55:33
本帖最后由 xmshao 于 2016-5-28 16:57 编辑
lwdawx 发表于 2016-5-28 09:22
启动文件没有问题,我已经调试好了用到的4个串口,2个SPI,ADC,I2C等其他功能了,就剩这个CAN1啦。 ...

那再检查下硬件线路。你可以拿ST官方例程专门测试CAN1.
lwdawx 回答时间:2016-5-29 15:51:43
yklstudent-1794 发表于 2016-5-28 12:17
你的项目够大的,需要用到这么多功能

没有办法,100腿用完了,又扩了40个腿的IO用,快把105榨干了。谢谢,问题已经解决了,是我的CAN收发器硬件电路问题,程序没有问题。
lwdawx 回答时间:2016-5-29 15:52:47
xmshao 发表于 2016-5-28 16:55
那再检查下硬件线路。你可以拿ST官方例程专门测试CAN1.

谢谢回答,确实是硬件问题。CAN收发器电路故障导致的。
chushifpga 回答时间:2016-8-16 15:46:46
CAN收发器电路故障,请问什么问题?
gdgly 回答时间:2016-10-10 18:53:22
可以分享下你的代码吗? 谢谢!! 3516863899@qq.com
zhulikai 回答时间:2016-10-11 14:52:32
chushifpga 发表于 2016-8-16 15:46
CAN收发器电路故障,请问什么问题?

也许是供电问题我猜
andrewz 回答时间:2016-11-1 17:03:06
谢谢分享代码~


st.png
zbber 回答时间:2016-11-1 20:33:16
CAN收发器电路故障,请问什么问题?

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版