基于stm32的can总线彻底研究

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过滤

stm32的can总线的配置如下:

“人无完人金无足赤”,只要是人就不会是完美的,

基于stm32的can总线彻底研究

相关文章:

你感兴趣的文章:

标签云: