STM32F4 CAN2配置

STM32F4 CAN2配置


  • 代码说明
  • 基本知识
  • 代码块

代码说明


通信协议

ID号(StdId) 1
扩展格式(IDE) 标准格式(CAN_ID_STD
消息类型(RTR) 数据帧(CAN_RTR_DATA)
数据长度(DLC) 8个字节
波特率 1Mbps
数据类型 自定义
数据单位 自定义
数据上报频率 自定义(定时器)
data[0] 数据
data[1] 数据
data[2] 数据
data[3] 数据
data[4] 数据
data[5] 数据
data[6] 数据
data[7] 数据

基本知识

  • 特别注意 CAN2配置时,滤波器要从[14]开始配置。

代码块

#define CAN2_PORT        CAN2
#define CAN2_GPIO_PORT   GPIOB
#define CAN2_RX_PIN      GPIO_Pin_12
#define CAN2_TX_PIN      GPIO_Pin_13

#define CAN_ID_Chassis   130

struct CAN_Socket
{
  unsigned int    u32_StdId;
  unsigned int    u32_ExtId;
  unsigned char   u8_IDE;
  unsigned char   u8_RTR;
  unsigned char   u8_DLC;
  unsigned char   u8_FMI;
  unsigned char   u8_data[8];
};
typedef struct CAN_Socket CAN;

CAN Send_Socket;

CanRxMsg  RxMessage2;
CanTxMsg  TxMessage2;

void CAN_Data_Init(void)
{
  int i;
  Send_Socket.u32_StdId = CAN_ID_Chassis;
  Send_Socket.u8_IDE = CAN_ID_STD;
  Send_Socket.u8_RTR = CAN_RTR_DATA;
  Send_Socket.u8_DLC = DLC_MAX;

  for(i = 0; i<8; i++)
  {
    Send_Socket.u8_data[i] = 0;
  }
}

void CAN2_Setup()
{
  GPIO_InitTypeDef GPIO_InitStructure;
  CAN_InitTypeDef CAN_InitStructure;
  CAN_FilterInitTypeDef CAN_FilterInitStructure;
  NVIC_InitTypeDef  NVIC_InitStructure;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);

  GPIO_InitStructure.GPIO_Pin = CAN2_RX_PIN|CAN2_TX_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  //GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  //GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(CAN2_GPIO_PORT, &GPIO_InitStructure);

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_CAN2); //CAN_RX = PB12
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_CAN2); //CAN_TX = PB13

  CAN_DeInit(CAN2);
  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 = ENABLE;
  CAN_InitStructure.CAN_RFLM = DISABLE;
  CAN_InitStructure.CAN_TXFP = DISABLE;
  CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;//同步跳转时间段
  CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;//时间段1
  CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;//时间段2
  CAN_InitStructure.CAN_Prescaler = 6;//波特率分频器
  /* CAN 波特率配置 = 42MHz/[(1+3+3)*6] = 1MHz (APB1的时钟频率一般为42MHz)*/

  if(CAN_Init(CAN2, &CAN_InitStructure) == CANINITFAILED)
  {
    do {}
    while(1);
  }
  /* CAN filter init */
  CAN_FilterInitStructure.CAN_FilterNumber = 14;//CAN2的滤波器从14开始
  CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
  CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
  CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
  CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
  //  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0;
  CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
  CAN_FilterInit(&CAN_FilterInitStructure);

  CAN_ITConfig(CAN2, CAN_IT_FMP0, ENABLE);

  NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);  
}

void CAN2_RX0_IRQHandler(void)
{
  int i;
  RxMessage2.StdId = 0x00;
  RxMessage2.ExtId = 0x00;

  for(i =0; i<8; i++)
  {
    RxMessage2.Data[i] = 0;
  }
  CAN_Receive(CAN2, CAN_FIFO0, &RxMessage2);

  switch(RxMessage2.StdId)
  {
  case 1:
    break;

  case 2:
    break;

  default:
    break;
  }
}

void CAN_TxSocket_CAN2(CAN *can_Socket)
{
  char i = 0;
  TxMessage2.StdId=can_Socket->u32_StdId;
  TxMessage2.ExtId=can_Socket->u32_ExtId;
  TxMessage2.IDE=can_Socket->u8_IDE;
  TxMessage2.RTR= can_Socket->u8_RTR;
  TxMessage2.DLC=can_Socket->u8_DLC;

  for(i =0; i.DLC; i++)
  {
    TxMessage2.Data[i] = can_Socket->u8_data[i];
  }
  i = CAN_Transmit(CAN2, &TxMessage2);
}

int main(void)
{
  CAN2_Setup();
  CAN_Data_Init();

  while(1)
  {
    if(Send_Flag == 1)//这个flag可用一个定时器来计时,这里不做特别说明
    {
      Send_Flag = 0;
      CAN_TxSocket_CAN2(&Send_Socket);//Send_Socket中可以存入要发送的数据
    }
  }
}

你可能感兴趣的:(stm32)