STM32——CAN通信实验

一、硬件连接(STM32F407)

PA11接CAN_RX  PA12接CAN_TX

CANL接CANL      CANH接CANH

二、初始化函数(STM32F407)

u8 CAN1_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
{
  GPIO_InitTypeDef GPIO_InitABC;
  CAN_InitTypeDef CAN_InitABC;
  CAN_FilterInitTypeDef CAN_FilterInitABC;
#CAN1_RXO_INT_ENABLE
  NVIC_InitTypeDef NBIC_InitABC;
#endif
  //使能
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE);
  
  //初始化GPIO
  GPIO_InitABC.GPIO_Pin=GPIO_Pin_11|GPIO_Pin_12;
  GPIO_InitABC.GPIO_Mode=GPIO_Mode_AF;
  GPIO_InitABC.GPIO_OType=GPIO_OType_PP;
  GPIO_InitABC.GPIO_Speed=GPIO_Speed_100MHz;
  GPIO_InitABC.GPIO_PuPd=GPIO_PuPd_UP;
  GPIO_Init(GPIOA,&GPIO_InitABC);
  //引脚复用映射,使用CAN功能
  GPIO_PinAFConfig(GPIOA,GPIO_PinSource1,GPIO_AF_CAN1);
  GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_CAN1);
  //CAN初始化  单元设置
  CAN_InitABC.CAN_TTCM=DISABLE;
  CAN_InitABC.CAN_ABOM=DISABLE;
  CAN_InitABC.CAN_AWUM=DISABLE;
  CAN_InitABC.CAN_NART=ENABLE;
  CAN_InitABC.CAN_RFLM=DISABLE;
  CAN_InitABC.CAN_TXFP=DISABLE;
  CAN_InitABC.CAN_Mode=mode;
  CAN_InitABC.CAN_SJW=tsjw;
  CAN_InirABC.CAN_BS1=tbs1;
  CAN_InitABC.CAN_BS2=tbs2;
  CAN_InitABC.CAN_Prescaler=brp;
  CAN_Init(CAN1,&CAN_InitABC);
}

配置过滤器(接收所有ID)

{
CAN_FilterInitABC.CAN_FilterNumber=0;
CAN_FilterInitABC.CAN_FilterMode=CAN_FilterMode_IdMask;
CAN_FilterInitABC.CAN_FilterScale=CAN_FilterScale_32bit;
CAN_FilterInitABC.CAN_FilterIdHigh=0x0000;
CAN_FilterInitABC.CAN_FilterIdLow=0x0000;
CAN_FilterInitABC.CAN_FilterMaskIdHigh=0x0000;
CAN_FilterInitABC.CAN_FilterMaskIdLow=0x0000;
CAN_FilterInitABC.CAN_FilterFIFOAssignment=CAN_Filter_FIFO;
CAN_FilterInitABC.CAN_FilterActivation=ENABLE;
CAN_FilterInit(&CAN_FilterInitABC);
}

发送函数:

//CAN发送一组数据(固定格式:ID为0X12,标准帧,数据帧)
//len:数据长度(最大为8)
//msg:数据指针,最大为8个字节
//返回值:0,成功  返回其它代表失败
u8 Can_Send_Msg(u8* msg,u8 len)
{
  u8 mbox;//发送邮箱
  u16 i=0;
  CanTxMsg TxMessage;
  TxMessage.Stdld=0x12;//标准标识符
  TxMessage.Extld=0x12;//设置扩展标识符
  TxMessage.IDE=CAN_Id_Standard;//标准帧
  TxMessage.RTR=CAN_RTR_Data;//数据帧
  TxMessage.DLC=len;//要发送的数据长度
  for(i=0;i=0XFFF)  return 1;
  return 0;
}

接收函数:

//CAN口接收数据查询
//buf:数据缓存区
//返回值:0,无数据
u8 Can_Receive_Msg(u8 *buf)
{
  u32 i;
  CanRxMsg RxMessage;
  if(CAN_MessagePending(CAN1,CAN_FIFO)==0) return 0;//没有接收到数据,直接退出
  CAN_Receive(CAN1,CAN_FIFO0,&RxMessage);//读取数据
  for(i=0;i<8;i++) buf[i]=RxMessage.Data[i];
  return RxMessage.DLC;
}

你可能感兴趣的:(STM32,stm32,单片机,arm)