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)
Previous article:STM32F4 (SRAM debugging)
Next article:STM32F4 (USART+DMA+static memory)
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Download from the Internet--ARM Getting Started Notes
- Learn ARM development(22)
- Learn ARM development(21)
- Learn ARM development(20)
- Learn ARM development(19)
- Learn ARM development(14)
- Learn ARM development(15)
- The live broadcast with prizes will start at 10:00 this morning: "The use of SOI level conversion driver IC in LLC topology"
- [Blood Oximeter] Disassembly Part 3 Background Knowledge
- [Silicon Labs BG22-EK4108A Bluetooth Development Evaluation] Burn Bootloader + Debug Bluetooth Lighting
- Altium Designer 19.0.10 The shortcut key for aligning left is not available?
- The price of domestic chip substitutes is only 1/5 of imported ones. Will domestic companies have a great opportunity?
- TI reference circuit solution for electric vehicle power management
- S digital receiving channel architecture
- The role of adding a reverse diode to the be pole of the transistor
- Sub-library: Motion Algorithm Library
- TI radar technology is changing three trends in the in-cockpit sensing market