微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 基于stm32的can总线彻底研究

基于stm32的can总线彻底研究

时间:11-18 来源:互联网 点击:
1、CAN总线的初始化

void can_init(void)
{
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报文只被发送1次,不管发送的结果如何(成功、出错或仲裁丢失)
CAN_InitStructure.CAN_RFLM=DISABLE;
CAN_InitStructure.CAN_TXFP=DISABLE;
CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;
//CAN_Mode_LoopBack
//CAN_Mode_Normal
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1=CAN_BS1_5tq;//1--16
CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;//1--8
CAN_InitStructure.CAN_Prescaler=2;
CAN_Init(&CAN_InitStructure);
#ifdef can_id_filter
/* 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=slave_id<5;//过滤器标识符
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;//
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xffff;//过滤器屏蔽标识符
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xfffc;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;//选择FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;//使能过滤器
CAN_FilterInit(&CAN_FilterInitStructure);//进入初始化函数
#else
/* 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=0x0000;//过滤器标识符
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;//
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//过滤器屏蔽标识符
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
CAN_ITConfig(CAN_IT_FMP0, ENABLE);//使能指定的can中断
}

void CAN_DeInit(void)
{
/* Enable CAN reset state */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN, ENABLE);
/* Release CAN from reset state */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN, DISABLE);
}

2、发送程序

unsignedcharCAN_PushMessage(CAN_MSG *pTransmitBuf )
{
u8 TransmitMailbox=0;
CanTxMsg TxMessage;
if(pTransmitBuf -> LEN > 8)
{
return 1;
}
/* transmit */
TxMessage.StdId=pTransmitBuf ->StdId;//用来设定标准标识符(0-0x7ff,11位)
TxMessage.ExtId=pTransmitBuf ->ExtId;
TxMessage.RTR= pTransmitBuf ->RTR;//设置RTR位为数据帧
TxMessage.IDE= pTransmitBuf ->IDE;//标识符扩展位,为标准帧
TxMessage.DLC= pTransmitBuf ->LEN;//设置数据长度
//根据DLC字段的值,将有效数据拷贝到发送数据寄存器
memcpy(TxMessage.Data, pTransmitBuf ->BUF,pTransmitBuf ->LEN);
TransmitMailbox = CAN_Transmit(&TxMessage);
// TxMessage.Data[1]=(data & 0xff00)>>8;
return 1;
}

3、中断接收程序

void USB_LP_CAN_RX0_IRQHandler(void)
{
//清空can接收缓存
CanRxMsg RxMessage;
RxMessage.StdId=0x00;
RxMessage.ExtId=0x00;
RxMessage.IDE=0;
RxMessage.DLC=0;
RxMessage.FMI=0;//CAN过滤主控制寄存器
memset( &RxMessage.Data[0],0,8);
//can总线接收数据函数
CAN_Receive(CAN_FIFO0, &RxMessage);
//将接收到的数据写于modbus的寄存器1
//modbus_regester[1]=(RxMessage.Data[0]<8)|(RxMessage.Data[1]);
// if((RxMessage.StdId==slave_id) && (RxMessage.ExtId==0x00) && (RxMessage.IDE==CAN_ID_STD))
{
//将can接收标志位置1,表示从卡应经接收到一个can报文
flag_can_recv=0;
memcpy(can_rx_data,&RxMessage.Data,RxMessage.DLC);
flag_can_recv=1;
}

}

4、can总线的id过滤

对扩展数据帧过滤:

CAN_FilterInitStructure.CAN_FilterNumber=0;
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh=(((u32)CAN_ID<3)&0xFFFF0000)>>16;
CAN_FilterInitStructure.CAN_FilterIdLow=(((u32)CAN_ID<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xFFFF;

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top