STM32F4(CAN)

Publisher:RadiantSoulLatest update time:2018-04-23 Source: eefocusKeywords:STM32F4  CAN Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. Development Environment

      1. Applicable chips: some STM32F4 chips

      2. Firmware library: STM32F4xx_DSP_StdPeriph_Lib_V1.8.0

      3,IDE:MDK517


2. Driver source code

      CAN.h File

/**************************************************************** 

 * Copyright (C) 2016, XinLi, all right reserved. 

 * File name:    CAN.h 

 * Date:         2016.11.30 

 * Description:  CAN Driver 

*****************************************************************/  

  

#ifndef __CAN_H  

#define __CAN_H  

  

/**************************************************************** 

 *                        Header include 

*****************************************************************/  

#include "stm32f4xx.h"  

  

/**************************************************************** 

 *                       Macro definition 

*****************************************************************/  

#define CAN1_FILTER_FIFO    CAN_Filter_FIFO0  

#define CAN2_FILTER_FIFO    CAN_Filter_FIFO0  

#if defined(STM32F413_423xx)  

#define CAN3_FILTER_FIFO    CAN_Filter_FIFO1  

#endif /* STM32F413_423xx */  

  

#define CAN1_FIFO   CAN_FIFO0  

#define CAN2_FIFO   CAN_FIFO0  

#if defined(STM32F413_423xx)  

#define CAN3_FIFO   CAN_FIFO1  

#endif /* STM32F413_423xx */  

  

/********************** CAN1 Configuration **********************/  

  

#define RCC_AHB1Periph_CAN1_Tx    RCC_AHB1Periph_GPIOA  

#define RCC_AHB1Periph_CAN1_Rx    RCC_AHB1Periph_GPIOA  

  

#define GPIO_CAN1_Tx              GPIOA  

#define GPIO_CAN1_Rx              GPIOA  

  

#define GPIO_Pin_CAN1_Tx          GPIO_Pin_12  

#define GPIO_Pin_CAN1_Rx          GPIO_Pin_11  

  

#define GPIO_PinSource_CAN1_Tx    GPIO_PinSource12  

#define GPIO_PinSource_CAN1_Rx    GPIO_PinSource11  

  

/****************************************************************/  

  

/********************** CAN2 Configuration **********************/  

  

#define RCC_AHB1Periph_CAN2_Tx    RCC_AHB1Periph_GPIOB  

#define RCC_AHB1Periph_CAN2_Rx    RCC_AHB1Periph_GPIOB  

  

#define GPIO_CAN2_Tx              GPIOB  

#define GPIO_CAN2_Rx              GPIOB  

  

#define GPIO_Pin_CAN2_Tx          GPIO_Pin_13  

#define GPIO_Pin_CAN2_Rx          GPIO_Pin_12  

  

#define GPIO_PinSource_CAN2_Tx    GPIO_PinSource13  

#define GPIO_PinSource_CAN2_Rx    GPIO_PinSource12  

  

/****************************************************************/  

  

/********************** CAN3 Configuration **********************/  

  

#if defined(STM32F413_423xx)  

#define RCC_AHB1Periph_CAN3_Tx    RCC_AHB1Periph_GPIOB  

#define RCC_AHB1Periph_CAN3_Rx    RCC_AHB1Periph_GPIOB  

  

#define GPIO_CAN3_Tx              GPIOB  

#define GPIO_CAN3_Rx              GPIOB  

  

#define GPIO_Pin_CAN3_Tx          GPIO_Pin_4  

#define GPIO_Pin_CAN3_Rx          GPIO_Pin_3  

  

#define GPIO_PinSource_CAN3_Tx    GPIO_PinSource4  

#define GPIO_PinSource_CAN3_Rx    GPIO_PinSource3  

#endif /* STM32F413_423xx */  

  

/****************************************************************/  

  

#if defined(STM32F40_41xxx)  

#define BAUD_RATE_1000K    ((uint16_t)2)  

#define BAUD_RATE_500K     ((uint16_t)4)  

#define BAUD_RATE_250K     ((uint16_t)8)  

#define BAUD_RATE_125K     ((uint16_t)16)  

#define BAUD_RATE_100K     ((uint16_t)20)  

#define BAUD_RATE_50K      ((uint16_t)40)  

#define BAUD_RATE_20K      ((uint16_t)100)  

#define BAUD_RATE_10K      ((uint16_t)200)  

#endif /* STM32F40_41xxx */  

  

#if defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx) || defined(STM32F469_479xx)  

#define BAUD_RATE_1000K    ((uint16_t)3)  

#define BAUD_RATE_500K     ((uint16_t)6)  

#define BAUD_RATE_250K     ((uint16_t)12)  

#define BAUD_RATE_125K     ((uint16_t)24)  

#define BAUD_RATE_100K     ((uint16_t)30)  

#define BAUD_RATE_50K      ((uint16_t)60)  

#define BAUD_RATE_20K      ((uint16_t)150)  

#define BAUD_RATE_10K      ((uint16_t)300)  

#endif /* STM32F427_437x || STM32F429_439xx || STM32F446xx || STM32F469_479xx */  

  

#if defined(STM32F413_423xx)  

#define BAUD_RATE_1000K    ((uint16_t)10)  

#define BAUD_RATE_500K     ((uint16_t)20)  

#define BAUD_RATE_250K     ((uint16_t)40)  

#define BAUD_RATE_125K     ((uint16_t)80)  

#define BAUD_RATE_100K     ((uint16_t)100)  

#define BAUD_RATE_50K      ((uint16_t)200)  

#define BAUD_RATE_20K      ((uint16_t)500)  

#define BAUD_RATE_10K      ((uint16_t)1000)  

#endif /* STM32F413_423xx */  

  

#if defined(STM32F412xG)  

#define BAUD_RATE_1000K    ((uint16_t)5)  

#define BAUD_RATE_500K     ((uint16_t)10)  

#define BAUD_RATE_250K     ((uint16_t)20)  

#define BAUD_RATE_125K     ((uint16_t)40)  

#define BAUD_RATE_100K     ((uint16_t)50)  

#define BAUD_RATE_50K      ((uint16_t)100)  

#define BAUD_RATE_20K      ((uint16_t)250)  

#define BAUD_RATE_10K      ((uint16_t)500)  

#endif /* STM32F412xG */  

  

/**************************************************************** 

 *                       Type definition 

*****************************************************************/  

  

  

/**************************************************************** 

 *                     Structure definition 

*****************************************************************/  

  

  

  

#ifdef __cplusplus  

 extern "C" {  

#endif  /* __cplusplus */  

  

/**************************************************************** 

 *                     Variable declaration 

*****************************************************************/  

  

  

/**************************************************************** 

 *                     Function declaration 

*****************************************************************/  

void CAN_Configuration(CAN_TypeDef* CANx, uint16_t BaudRate, uint32_t StdId, uint32_t ExtId, uint8_t CAN_Mode, uint32_t CAN_IT);  

void CAN_Unconfigure(CAN_TypeDef* CANx);  

uint8_t CAN_TxMsg(CAN_TypeDef* CANx, CanTxMsg* TxMessage);  

uint8_t CAN_RxMsg(CAN_TypeDef* CANx, CanRxMsg* RxMessage);  

  

#ifdef __cplusplus  

}  

#endif  /* __cplusplus */  

  

#endif  /* __CAN_H */  


      CAN.c file

/**************************************************************** 

 * Copyright (C) 2016, XinLi, all right reserved. 

 * File name:    CAN.c 

 * Date:         2016.11.30 

 * Description:  CAN Driver 

*****************************************************************/  

  

/**************************************************************** 

 *                        Header include 

*****************************************************************/  

#include "CAN.h"  

  

/**************************************************************** 

 *                       Global variables 

*****************************************************************/  

static uint8_t gpioFlag = 0x00; /* Used to record the GPIO initialization flag. */  

static uint8_t canFlag  = 0x00; /* Used to record the CAN initialization flag. */  

  

/**************************************************************** 

 *                     Function declaration 

*****************************************************************/  

  

  

/**************************************************************** 

 *                     Function definition 

*****************************************************************/  

  

/**************************************************************** 

 * Function:    CAN_Configuration 

 * Description: CAN Configuration. 

 * Input:       CANx 

 *              BaudRate 

 *              StdId 

 *              ExtId 

 *              CAN_Mode 

 *              CAN_IT 

 * Output: 

 * Return: 

*****************************************************************/  

void CAN_Configuration(CAN_TypeDef* CANx, uint16_t BaudRate, uint32_t StdId, uint32_t ExtId, uint8_t CAN_Mode, uint32_t CAN_IT)  

{  

  GPIO_InitTypeDef GPIO_InitStructure;  

  CAN_InitTypeDef CAN_InitStructure;  

  CAN_FilterInitTypeDef CAN_FilterInitStructure;  

    

  if(CANx == CAN1)  

  {  

    if((canFlag & 0x01) != 0x01)  

    {  

      canFlag |= 0x01;  

        

      RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);     /* Enable CAN1 clock */  

    }  

      

    if((gpioFlag & 0x01) != 0x01)  

    {  

      gpioFlag |= 0x01;  

        

      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CAN1_Tx, ENABLE);  /* Enable CAN1_Tx GPIO clock */  

      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CAN1_Rx, ENABLE);  /* Enable CAN1_Rx GPIO clock */  

  

      GPIO_PinAFConfig(GPIO_CAN1_Tx, GPIO_PinSource_CAN1_Tx, GPIO_AF_CAN1); /* Connect GPIOxn to CAN1_Tx */  

      GPIO_PinAFConfig(GPIO_CAN1_Rx, GPIO_PinSource_CAN1_Rx, GPIO_AF_CAN1); /* Connect GPIOxn to CAN1_Rx */  

  

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN1_Tx;     /* Specifies the GPIO pins to be configured. */  

      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        /* Specifies the operating mode for the selected pins. */  

      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;  /* Specifies the speed for the selected pins. */  

      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      /* Specifies the operating output type for the selected pins. */  

      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        /* Specifies the operating Pull-up/Pull down for the selected pins. */  

      GPIO_Init(GPIO_CAN1_Tx, &GPIO_InitStructure);       /* Initializes the GPIOx peripheral according to the specified parameters in the GPIO_InitStruct. */  

        

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN1_Rx;     /* Specifies the GPIO pins to be configured. */  

      GPIO_Init(GPIO_CAN1_Rx, &GPIO_InitStructure);       /* Initializes the GPIOx peripheral according to the specified parameters in the GPIO_InitStruct. */  

    }  

  }  

  else if(CANx == CAN2)  

  {  

    if((canFlag & 0x02) != 0x02)  

    {  

      canFlag |= 0x02;  

        

      RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);     /* Enable CAN1 clock */  

      RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);     /* Enable CAN2 clock */  

    }  

      

    if((gpioFlag & 0x02) != 0x02)  

    {  

      gpioFlag |= 0x02;  

        

      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CAN2_Tx, ENABLE);  /* Enable CAN2_Tx GPIO clock */  

      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CAN2_Rx, ENABLE);  /* Enable CAN2_Rx GPIO clock */  

  

      GPIO_PinAFConfig(GPIO_CAN2_Tx, GPIO_PinSource_CAN2_Tx, GPIO_AF_CAN2); /* Connect GPIOxn to CAN2_Tx */  

      GPIO_PinAFConfig(GPIO_CAN2_Rx, GPIO_PinSource_CAN2_Rx, GPIO_AF_CAN2); /* Connect GPIOxn to CAN2_Rx */  

  

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN2_Tx;     /* Specifies the GPIO pins to be configured. */  

      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        /* Specifies the operating mode for the selected pins. */  

      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;  /* Specifies the speed for the selected pins. */  

      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      /* Specifies the operating output type for the selected pins. */  

      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        /* Specifies the operating Pull-up/Pull down for the selected pins. */  

      GPIO_Init(GPIO_CAN2_Tx, &GPIO_InitStructure);       /* Initializes the GPIOx peripheral according to the specified parameters in the GPIO_InitStruct. */  

        

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN2_Rx;     /* Specifies the GPIO pins to be configured. */  

      GPIO_Init(GPIO_CAN2_Rx, &GPIO_InitStructure);       /* Initializes the GPIOx peripheral according to the specified parameters in the GPIO_InitStruct. */  

    }  

  }  

#if defined(STM32F413_423xx)  

  else if(CANx == CAN3)  

  {  

    if((canFlag & 0x04) != 0x04)  

    {  

      canFlag |= 0x04;  

        

      RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN3, ENABLE);     /* Enable CAN3 clock */  

    }  

      

    if((gpioFlag & 0x04) != 0x04)  

    {  

      gpioFlag |= 0x04;  

        

      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CAN3_Tx, ENABLE);  /* Enable CAN3_Tx GPIO clock */  

      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CAN3_Rx, ENABLE);  /* Enable CAN3_Rx GPIO clock */  

  

      GPIO_PinAFConfig(GPIO_CAN3_Tx, GPIO_PinSource_CAN3_Tx, GPIO_AF11_CAN3); /* Connect GPIOxn to CAN3_Tx */  

      GPIO_PinAFConfig(GPIO_CAN3_Rx, GPIO_PinSource_CAN3_Rx, GPIO_AF11_CAN3); /* Connect GPIOxn to CAN3_Rx */  

  

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN3_Tx;     /* Specifies the GPIO pins to be configured. */  

      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        /* Specifies the operating mode for the selected pins. */  

      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;  /* Specifies the speed for the selected pins. */  

      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      /* Specifies the operating output type for the selected pins. */  

      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        /* Specifies the operating Pull-up/Pull down for the selected pins. */  

      GPIO_Init(GPIO_CAN3_Tx, &GPIO_InitStructure);       /* Initializes the GPIOx peripheral according to the specified parameters in the GPIO_InitStruct. */  

        

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN3_Rx;     /* Specifies the GPIO pins to be configured. */  

      GPIO_Init(GPIO_CAN3_Rx, &GPIO_InitStructure);       /* Initializes the GPIOx peripheral according to the specified parameters in the GPIO_InitStruct. */  

    }  

  }  

#endif /* STM32F413_423xx */  

    

  CAN_InitStructure.CAN_Prescaler = BaudRate;     /* Specifies the length of a time quantum. It ranges from 1 to 1024. */  

  CAN_InitStructure.CAN_Mode = CAN_Mode;          /* Specifies the CAN operating mode. */  

  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;        /* Specifies the maximum number of time quanta the CAN hardware is allowed to lengthen or shorten a bit to perform resynchronization. */  

  

#if defined(STM32F40_41xxx)  

  CAN_InitStructure.CAN_BS1 = CAN_BS1_16tq;       /* Specifies the number of time quanta in Bit Segment 1. */  

  CAN_InitStructure.CAN_BS2 = CAN_BS2_4tq;        /* Specifies the number of time quanta in Bit Segment 2. */  

#endif /* STM32F40_41xxx */  

    

#if defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx) || defined(STM32F469_479xx)  

  CAN_InitStructure.CAN_BS1 = CAN_BS1_11tq;       /* Specifies the number of time quanta in Bit Segment 1. */  

  CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;        /* Specifies the number of time quanta in Bit Segment 2. */  

#endif /* STM32F427_437x || STM32F429_439xx || STM32F446xx || STM32F469_479xx */  

    

#if defined(STM32F413_423xx)  

  CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;        /* Specifies the number of time quanta in Bit Segment 1. */  

  CAN_InitStructure.CAN_BS2 = CAN_BS2_1tq;        /* Specifies the number of time quanta in Bit Segment 2. */  

#endif /* STM32F413_423xx */  

    

#if defined(STM32F412xG)  

  CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;        /* Specifies the number of time quanta in Bit Segment 1. */  

  CAN_InitStructure.CAN_BS2 = CAN_BS2_1tq;        /* Specifies the number of time quanta in Bit Segment 2. */  

#endif /* STM32F412xG */  

    

  CAN_InitStructure.CAN_TTCM = DISABLE;           /* Enable or disable the time triggered communication mode. */  

  CAN_InitStructure.CAN_ABOM = DISABLE;           /* Enable or disable the automatic bus-off management. */  

  CAN_InitStructure.CAN_AWUM = DISABLE;           /* Enable or disable the automatic wake-up mode. */  

  CAN_InitStructure.CAN_NART = DISABLE;           /* Enable or disable the non-automatic retransmission mode. */  

  CAN_InitStructure.CAN_RFLM = DISABLE;           /* Enable or disable the Receive FIFO Locked mode. */  

  CAN_InitStructure.CAN_TXFP = DISABLE;           /* Enable or disable the transmit FIFO priority. */  

    

  CAN_DeInit(CANx);                   /* Deinitializes the CAN peripheral registers to their default reset values. */  

  CAN_Init(CANx, &CAN_InitStructure); /* Initializes the CAN peripheral according to the specified parameters in the CAN_InitStruct. */  

    

  CAN_FilterInitStructure.CAN_FilterIdHigh = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);                  /* Specifies the filter identification number. */  

  CAN_FilterInitStructure.CAN_FilterIdLow = (uint16_t)(((StdId<<18)|ExtId)<<3);                         /* Specifies the filter identification number. */  

  CAN_FilterInitStructure.CAN_FilterMaskIdHigh = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;  /* Specifies the filter mask number or identification number,according to the mode. */  

  CAN_FilterInitStructure.CAN_FilterMaskIdLow = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;         /* Specifies the filter mask number or identification number,according to the mode. */  

    

  if(CANx == CAN1)  

  {  

    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN1_FILTER_FIFO;  /* Specifies the FIFO (0 or 1) which will be assigned to the filter. */  

    CAN_FilterInitStructure.CAN_FilterNumber = 0;                         /* Specifies the filter which will be initialized. */  

  }  

  else if(CANx == CAN2)  

  {  

    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN2_FILTER_FIFO;  /* Specifies the FIFO (0 or 1) which will be assigned to the filter. */  

    CAN_FilterInitStructure.CAN_FilterNumber = 14;                        /* Specifies the filter which will be initialized. */  

  }  

#if defined(STM32F413_423xx)  

  else if(CANx == CAN3)  

  {  

    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN3_FILTER_FIFO;  /* Specifies the FIFO (0 or 1) which will be assigned to the filter. */  

    CAN_FilterInitStructure.CAN_FilterNumber = 0;                         /* Specifies the filter which will be initialized. */  

  }  

#endif /* STM32F413_423xx */  

    

  CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;   /* Specifies the filter mode to be initialized. */  

  CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;  /* Specifies the filter scale. */  

  CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;            /* Enable or disable the filter. */  

    

#if defined(STM32F413_423xx)  

  CAN_FilterInit(CANx, &CAN_FilterInitStructure); /* Configures the CAN reception filter according to the specified parameters in the CAN_FilterInitStruct. */  

#else  

  CAN_FilterInit(&CAN_FilterInitStructure);       /* Configures the CAN reception filter according to the specified parameters in the CAN_FilterInitStruct. */  

#endif /* STM32F413_423xx */  

    

  CAN_ITConfig(CANx, CAN_IT_TME|CAN_IT_FMP0|CAN_IT_FF0|CAN_IT_FOV0|CAN_IT_FMP1|CAN_IT_FF1|CAN_IT_FOV1|  

                     CAN_IT_WKU|CAN_IT_SLK|CAN_IT_EWG|CAN_IT_EPV|CAN_IT_BOF|CAN_IT_LEC|CAN_IT_ERR, DISABLE);  /* Disables the specified CAN interrupts. */  

  CAN_ITConfig(CANx, CAN_IT, ENABLE);                                                                         /* Enables the specified CAN interrupts. */  

}  

  

/**************************************************************** 

 * Function:    CAN_Unconfigure 

 * Description: CAN Unconfigure. 

 * Input:       CANx 

 * Output: 

 * Return: 

*****************************************************************/  

void CAN_Unconfigure(CAN_TypeDef* CANx)  

{  

  if(CANx == CAN1)  

  {  

    if((canFlag & 0x01) == 0x01)  

    {  

      canFlag &= 0xFE;  

        

      RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);     /* Disable CAN1 clock */  

        

      CAN_DeInit(CAN1); /* Deinitializes the CAN1 peripheral registers to their default reset values. */  

    }  

  }  

  else if(CANx == CAN2)  

  {  

    if((canFlag & 0x02) == 0x02)  

    {  

      canFlag &= 0xFD;  

        

      RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, DISABLE);     /* Disable CAN2 clock */  

        

      if((canFlag & 0x01) != 0x01)  

      {  

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);   /* Disable CAN1 clock */  

      }  

        

      CAN_DeInit(CAN2); /* Deinitializes the CAN2 peripheral registers to their default reset values. */  

    }  

  }  

#if defined(STM32F413_423xx)  

  else if(CANx == CAN3)  

  {  

    if((canFlag & 0x04) == 0x04)  

    {  

      canFlag &= 0xFB;  

        

      RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN3, DISABLE);     /* Disable CAN3 clock */  

        

      CAN_DeInit(CAN3); /* Deinitializes the CAN3 peripheral registers to their default reset values. */  

    }  

  }  

#endif /* STM32F413_423xx */  

}  

  

/**************************************************************** 

 * Function:    CAN_TxMsg 

 * Description: CAN TxMsg. 

 * Input:       CAN_x 

 *              TxMessage 

 * Output: 

 * Return:      0:Failure 

 *              1:Success 

*****************************************************************/  

uint8_t CAN_TxMsg(CAN_TypeDef* CANx, CanTxMsg* TxMessage)  

{  

  uint8_t status = 0;  

    

  if(CANx == CAN1)  

  {  

    if((canFlag & 0x01) == 0x01)  

    {  

      status = 1;  

        

      while(CAN_Transmit(CAN1, TxMessage) == CAN_TxStatus_NoMailBox);  

    }  

  }  

  else if(CANx == CAN2)  

  {  

    if((canFlag & 0x02) == 0x02)  

    {  

      status = 1;  

        

      while(CAN_Transmit(CAN2, TxMessage) == CAN_TxStatus_NoMailBox);  

    }  

  }  

#if defined(STM32F413_423xx)  

  else if(CANx == CAN3)  

  {  

    if((canFlag & 0x04) == 0x04)  

    {  

      status = 1;  

        

      while(CAN_Transmit(CAN3, TxMessage) == CAN_TxStatus_NoMailBox);  

    }  

  }  

#endif /* STM32F413_423xx */  

    

  return status;  

}  

  

/**************************************************************** 

 * Function:    CAN_RxMsg 

 * Description: CAN RxMsg. 

 * Input:       CAN_x 

 *              RxMessage 

 * Output: 

 * Return:      0:Failure 

 *              1:Success 

*****************************************************************/  

uint8_t CAN_RxMsg(CAN_TypeDef* CANx, CanRxMsg* RxMessage)  

{  

  uint8_t status = 0;  

    

  if(CANx == CAN1)  

  {  

    if((canFlag & 0x01) == 0x01)  

    {  

      status = 1;  

        

      CAN_Receive(CAN1, CAN1_FIFO, RxMessage);  

    }  

  }  

  else if(CANx == CAN2)  

  {  

    if((canFlag & 0x02) == 0x02)  

    {  

      status = 1;  

        

      CAN_Receive(CAN2, CAN2_FIFO, RxMessage);  

    }  

  }  

#if defined(STM32F413_423xx)  

  else if(CANx == CAN3)  

  {  

    if((canFlag & 0x04) == 0x04)  

    {  

      status = 1;  

        

      CAN_Receive(CAN3, CAN3_FIFO, RxMessage);  

    }  

  }  

#endif /* STM32F413_423xx */  

    

  return status;  

}  


3. Routines


      main.h file


/**************************************************************** 

 * Copyright (C) 2016, XinLi, all right reserved. 

 * File name:    main.h 

 * Date:         2016.11.30 

 * Description:  CAN Example. 

*****************************************************************/  

  

#ifndef __MAIN_H  

#define __MAIN_H  

  

/**************************************************************** 

 *                        Header include 

*****************************************************************/  

#include "stm32f4xx.h"  

  

/**************************************************************** 

 *                       Macro definition 

*****************************************************************/  

  

  

/**************************************************************** 

 *                       Type definition 

*****************************************************************/  

  

  

/**************************************************************** 

 *                     Structure definition 

*****************************************************************/  

  

  

  

#ifdef __cplusplus  

 extern "C" {  

#endif  /* __cplusplus */  

  

/**************************************************************** 

 *                     Variable declaration 

*****************************************************************/  

extern CanRxMsg RxMessage;  

  

/**************************************************************** 

 *                     Function declaration 

*****************************************************************/  

  

  

#ifdef __cplusplus  

}  

#endif  /* __cplusplus */  

  

#endif  /* __MAIN_H */  


      main.c file

/**************************************************************** 

 * Copyright (C) 2016, XinLi, all right reserved. 

 * File name:    main.c 

 * Date:         2016.11.30 

 * Description:  CAN Example. 

*****************************************************************/  

  

/**************************************************************** 

 *                        Header include 

*****************************************************************/  

#include "main.h"  

#include "CAN.h"  

  

/**************************************************************** 

 *                       Global variables 

*****************************************************************/  

CanTxMsg TxMessage;  

CanRxMsg RxMessage;  

  

/**************************************************************** 

 *                     Function declaration 

*****************************************************************/  

static void System_Init(void);  

static void NVIC_Configuration(void);  

  

/**************************************************************** 

 *                     Function definition 

*****************************************************************/  

  

/**************************************************************** 

 * Function:    main 

 * Description: Program entry. 

 * Input: 

 * Output: 

 * Return: 

*****************************************************************/  

int main(void)  

{  

  System_Init();  

    

  for(;;)  

  {  

    TxMessage.StdId = 0x02;  

    TxMessage.ExtId = 0x03;  

    TxMessage.IDE = CAN_ID_EXT;  

    TxMessage.RTR = CAN_RTR_DATA;  

    TxMessage.DLC = 8;  

    TxMessage.Data[0] += 1;  

    TxMessage.Data[1] = 1;  

    TxMessage.Data[2] = 2;  

    TxMessage.Data[3] = 3;  

    TxMessage.Data[4] = 4;  

    TxMessage.Data[5] = 5;  

    TxMessage.Data[6] = 8;  

    TxMessage.Data[7] = 9;  

      

    CAN_TxMsg(CAN1, &TxMessage);  

  }  

}  

  

/**************************************************************** 

 * Function:    System_Init 

 * Description: Initialization System. 

 * Input: 

 * Output: 

 * Return: 

*****************************************************************/  

static void System_Init(void)  

{  

  CAN_Configuration(CAN1, BAUD_RATE_1000K, 0x01|0x02, 0x02|0x03, CAN_Mode_LoopBack, CAN_IT_FMP0);  

  NVIC_Configuration();  

}  

  

/**************************************************************** 

 * Function:    NVIC_Configuration 

 * Description: Interrupt Vector Table Configuration. 

 * Input: 

 * Output: 

 * Return: 

*****************************************************************/  

static void NVIC_Configuration(void)  

{  

  NVIC_InitTypeDef NVIC_InitStructure;  

  

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);  

  

  NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;  

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;  

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;  

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  

  NVIC_Init(&NVIC_InitStructure);  

}  


      Interrupt Service Routine

/** 

  * @brief  This function handles CAN1 RX0 Handler. 

  * @param  None 

  * @retval None 

  */  

void CAN1_RX0_IRQHandler(void)  

{  

  if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)  

  {  

    CAN_RxMsg(CAN1, &RxMessage);  

      

    CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);  

  }  

}  

      Modify the hardware interface (modify according to your own board)





Keywords:STM32F4  CAN Reference address:STM32F4(CAN)

Previous article:STM32F4 (SRAM debugging)
Next article:STM32F4 (USART+DMA+static memory)

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号