本人总是在这里劳驾大家,今天决定把我一段时间学习的成果与大家共享下!
下面的程序对初学者肯定有帮助的,因为我也是菜鸟!
STM32 CAN滤波器配置总结
经过一段时间的学习,终于把Can通信调通了。今天花费点时间总结下CAN通信各参数配置注意事项和方法,以便下回查阅。
这里采用分别介绍查询发送、中断接收和中断发送、中断接收两种方式。
第一步,初始化各端口与寄存器,这里只介绍CAN_Configuration代码如下:
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
/* CAN register init */
CAN_DeInit();
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;
CAN_InitStructure.CAN_TXFP=DISABLE;
CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;// 正常模式
CAN_InitStructure.CAN_SJW=CAN_SJW_2tq;
CAN_InitStructure.CAN_BS1=CAN_BS1_9tq;
CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;
CAN_InitStructure.CAN_Prescaler=8; //36MHz/(1+8+7)*9 =250Kb/s
CAN_Init(&CAN_InitStructure);
/* CAN filter init */初始化滤波器
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 =tempid ;//接收板的CAN地址
CAN_FilterInitStructure.CAN_FilterIdLow =0x0004;//选择扩展标识符(见手册CAN_RIxR)
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xffff;//接收板的地址要和tempid一致
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0004;//下面有介绍
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0; //选择FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;//使能过滤器
CAN_FilterInit(&CAN_FilterInitStructure); //进入初始化函数
/* CAN FIFO0 message pending interrupt enable */
CAN_ITConfig(CAN_IT_FMP0, ENABLE); //FIFO0 消息挂号中断屏蔽
CAN_ITConfig(CAN_IT_TME, ENABLE); //发送邮箱空中断屏蔽
CAN_ITConfig(CAN_IT_BOF, ENABLE); //离线中断允许
第二步,在嵌套向量中断控制中设置下,代码如下:
NVIC_InitTypeDef NVIC_InitStructure;
#ifdef VECT_TAB_RAM
/* Set the Vector Table base location at 0x20000000 */
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else /* VECT_TAB_FLASH */
/* Set the Vector Table base location at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
/* Enable CAN RX0 interrupt IRQ channel */ //接收中断
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN_RX0_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//发送中断,如果是查询方式发送的话,下面代码不要
NVIC_InitStructure.NVIC_IRQChannel=USB_HP_CAN_TX_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢先中断优先
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应中断优先
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
第三步,编写发送子函数
CanTxMsg TxMessage; //定义数据结构类型变量
u8 TransmitMailbox = 0;
u16 i = 0;
TxMessage.ExtId=(tempid << 13); //tempId 为接受板地址,应用过程中要左移13位
TxMessage.IDE=CAN_ID_EXT;//使用扩展帧
TxMessage.RTR=CAN_RTR_DATA;//发送数据帧
TxMessage.DLC= 1; //设置发送数据的长度
TxMessage.Data[0] = SendData;//赋值待发送
TransmitMailbox = CAN_Transmit(&TxMessage);//开始发送数据
i = 0;
//通过检查CANTXOK位来确认发送是否成功
while((CAN_TransmitStatus(TransmitMailbox) != CANTXOK) && (i != 0xFF))
{
i++;
}
第四步,编写中断接收函数,注:下面代码在stm32f10x_it.c中编写
Void USB_LP_CAN_RX0_IRQHandler(void)
{
CanRxMsg can_rx_one_frame; //定义接收数据变量
CAN_Receive(CAN_FIFO0,&can_rx_one_frame);//接收数据函数
Receive_data = can_rx_one_frame.Data[0];//接收到的数据转存给变量Receive_data
CAN_FIFORelease(CAN_FIFO0);// 释放一 FIFO0
}
更多资料 http://y-ec.taobao.com/ |