小弟刚接触CAN总线,用的STM32F207ZGT6,目前CAN的发送和过滤基本上算搞懂点了,但是在调试过程中遇到个问题,读取FIFO输出邮箱时,不能读取最新送入FIFO的数据,只能读取进入FIFO最早的一帧数据,我是的ST的固件库的接收程序,接收程序里加入了RFOM置位(清邮箱)。调试的时候感觉RFOM置位和CAN_FIFORelease(CAN1, CAN_FIFO0);没用。下面是CAN部分代码。
void CAN_Config(void)//CAN口设置
{
GPIO_InitTypeDef GPIO_InitStructure; //初始化结构体 GPIO_InitStructure
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource11,GPIO_AF_CAN1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource12,GPIO_AF_CAN1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
CAN_DeInit(CAN1);
CAN_StructInit(&CAN_InitStructure);
/* CAN cell init */
CAN_InitStructure.CAN_TTCM = DISABLE; //禁止时间触发通信模式
CAN_InitStructure.CAN_ABOM = DISABLE; //离线模式管理
CAN_InitStructure.CAN_AWUM = DISABLE; //软件唤醒模式
CAN_InitStructure.CAN_NART = DISABLE; //发送失败自动重传直到发送成功
CAN_InitStructure.CAN_RFLM = DISABLE; //溢出时FIFO不锁定,自动覆盖
CAN_InitStructure.CAN_TXFP = DISABLE; //报文优先级由报文的标识符决定
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; //CAN工作在正常模式下
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; //重新同步跳跃时宽、tsjw=tcan*(sjw+1),此处为1个报文位的时间
CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq; //CAN_BS1 = 6
CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq; //CAN_BS2 = 8
CAN_InitStructure.CAN_Prescaler = 16; //Prescaler =16 ,so CAN_Baudarate = 30M/16/(1+6+8)=125kbps
CAN_Init(CAN1, &CAN_InitStructure);
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdList;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh =((unsigned short int) CAN_RX_ID)<<5;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000|CAN_ID_STD|CAN_RTR_DATA; //要过滤的ID低位
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFE0; //过滤器高16位每位必须匹配
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000; //过滤器低16位每位必须匹配
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0 ; //关联到FIFO0
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; //使能过滤器
CAN_FilterInit(&CAN_FilterInitStructure);
/* Enable FIFO 0 message pending Interrupt */
CAN_ITConfig(CAN1, CAN_IT_FMP0|CAN_IT_FF0|CAN_IT_FOV0 , ENABLE);
}
void NVIC_Config(void)//开CAN接收中断
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn; //CAN1接收中断向量
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void CAN_ReceivedData(void)
{
unsigned char i;
if(1 == CAN_GetITStatus(CAN1,CAN_IT_FF0)) //接收邮箱满
{
CAN_ClearITPendingBit(CAN1,CAN_IT_FF0);
}
else if(1 == CAN_GetITStatus(CAN1,CAN_IT_FOV0))
{
CAN_ClearITPendingBit(CAN1,CAN_IT_FOV0);
}
else
{
CAN_Receive(CAN1, CAN_Filter_FIFO0, &RxMessage);
ID_STD_Receive = RxMessage.StdId;
ID_ExtId_Receive = RxMessage.ExtId;
IDE_Recevie = RxMessage.IDE;
RTR_Recevie = RxMessage.RTR;
DLC_Recevie = RxMessage.DLC;
for(i=0;i<DLC_Recevie;i++)
{
CAN_RX_DATA = RxMessage.Data;
}
FMI_Recevie = RxMessage.FMI;
}
}
下面是调试截图:
左边是电脑发送的数据场最后一位从1开始每发送一次加一,共发送三次,右边是仿真的数据,MCU接收到的数据都存在CAN_RX_DATA里
公司没人搞过CAN,完全靠自学的小弟实在是没辙了:'(,请大神指点下。
|