文章
博客 网店

 STM32F042K6T6 CAN总线简单示例


STM32F042 简单的CAN总线操作例程,测试过的;



CanRxMsg g_CanRxMsg;
CanTxMsg g_CanTxMsg;

uint8_t CANInit(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
  NVIC_InitTypeDef  NVIC_InitStructure;
  CAN_InitTypeDef        CAN_InitStructure;
  CAN_FilterInitTypeDef  CAN_FilterInitStructure;
  
  // Connect CAN pins to AF4 
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_4);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_4);   
  
  //CAN_RX引脚
  GPIO_InitStructure.GPIO_Pin    = GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode   = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed  = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd   = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  //CAN_TX引脚
  GPIO_InitStructure.GPIO_Pin    = GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode   = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType  = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed  = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_PuPd   = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  //Enable CAN clock
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);
  //SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP; //TQFP32封装不需要此行
  
  //CAN register init
  CAN_DeInit(CAN);  
  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 Baudrate = 10KBps (CAN clocked at 48 MHz)
  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
  CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
  CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;
  CAN_InitStructure.CAN_Prescaler = 800;    //baud=48m/800/(1+3+2)=10k
  
  if( CAN_Init(CAN, &CAN_InitStructure) != CANINITOK )
    return 1;

  // CAN filter init 接收所有数据包
  CAN_FilterInitStructure.CAN_FilterNumber = 0; //激活第一组过滤器
  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 = CAN_FIFO0;
  CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
  CAN_FilterInit(&CAN_FilterInitStructure);
  
  //NVIC configuration 
  NVIC_InitStructure.NVIC_IRQChannel = CEC_CAN_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
  //Enable FIFO 0 message pending Interrupt
  CAN_ITConfig(CAN, CAN_IT_FMP0, ENABLE);
  
  //发送缓冲区初始化
  g_CanTxMsg.StdId = 0;
  g_CanTxMsg.ExtId = 0;
  g_CanTxMsg.RTR = CAN_RTR_DATA;
  g_CanTxMsg.IDE = CAN_ID_STD;
  g_CanTxMsg.DLC = 8;  
  
  return 0;


//CAN中断
void CEC_CAN_IRQHandler(void)
{
  //只打开了接收中断
  CAN_Receive(CAN, CAN_FIFO0, &g_CanRxMsg);
  //...
}

//发送一个数据包
void CAN_Send(uint8_t *buf,uint8_t len)
{
  uint8_t i;
  uint8_t size;
  size=len<8?len:8;
  
  for(i=0;i<size;i++)
    g_CanTxMsg.Data[i]=buf[i];
  
  g_CanTxMsg.DLC=size;
  
  CAN_Transmit(CAN, &g_CanTxMsg);   
}

芯艺工作室    蒙ICP备06005492号
Copyright© 2004-2023 ChipArt Studio All Rights Reserved