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

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-1794 回答时间: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收发器电路故障,请问什么问题?

也许是供电问题我猜
12下一页

所属标签

相似问题

官网相关资源

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