完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我用的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 if(CAN1_RX_BUF[10]==0) //最后1个字节的接收标志位 0:没有接收到数据 1:接收到数据 { memcpy(&(CAN1_RX_BUF[0]),&CAN1RxID,2); //前两个字节是ID memcpy(&(CAN1_RX_BUF[2]),RxMessage.Data,8);//8个字节的数据 CAN1_RX_BUF[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 if(CAN2_RX_BUF[10]==0) { memcpy(&(CAN2_RX_BUF[0]),&CAN2RxID,2); memcpy(&(CAN2_RX_BUF[2]),RxMessage.Data,8); CAN2_RX_BUF[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; 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; 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; } |
|
相关推荐
12个回答
|
|
|
|
|
|
启动文件没有问题,我已经调试好了用到的4个串口,2个SPI,ADC,I2C等其他功能了,就剩这个CAN1啦。 |
|
|
|
你的项目够大的,需要用到这么多功能 |
|
|
|
本帖最后由 xmshao 于 2016-5-28 16:57 编辑 那再检查下硬件线路。你可以拿ST官方例程专门测试CAN1. |
|
|
|
没有办法,100腿用完了,又扩了40个腿的IO用,快把105榨干了。谢谢,问题已经解决了,是我的CAN收发器硬件电路问题,程序没有问题。 |
|
|
|
谢谢回答,确实是硬件问题。CAN收发器电路故障导致的。 |
|
|
|
CAN收发器电路故障,请问什么问题?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CAN收发器电路故障,请问什么问题?
|
|
|
|
请问电路是什么故障啊?我也遇到了,rxd脚有数据,但不进中断,能正常发数据
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
2093 浏览 1 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
1931 浏览 3 评论
4526 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
2076 浏览 1 评论
hal库中i2c卡死在HAL_I2C_Master_Transmit
2587 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 11:55 , Processed in 1.113034 second(s), Total 95, Slave 79 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号