打印

stm32 can通信调试总结

[复制链接]
193|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
没名字的人|  楼主 | 2018-8-28 18:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本人总是在这里劳驾大家,今天决定把我一段时间学习的成果与大家共享下!

下面的程序对初学者肯定有帮助的,因为我也是菜鸟!

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/

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

420

主题

432

帖子

0

粉丝