1,开发环境
1,固件库:STM32F10x_StdPeriph_Lib_V3.5.0
2,编译器:ARMCC V5.06
3,IDE:Keil uVision5
4,操作系统:Windows 10 专业版
2,程序源码
RingBuffer.h 文件
RingBuffer.c 文件
- <div>/**
- ******************************************************************************
- * @file RingBuffer.c
- * @author XinLi
- * @version v1.1
- * @date 15-January-2018
- * @brief Ring buffer module source file.
- ******************************************************************************
- * @attention
- *
- * <h2><center>Copyright © 2018 XinLi</center></h2>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
- *
- ******************************************************************************
- */
- /* Header includes -----------------------------------------------------------*/
- #include "RingBuffer.h"
- #include <string.h>
- /* Macro definitions ---------------------------------------------------------*/
- #define min(a, b) (((a) < (b)) ? (a) : (b))
- /* Type definitions ----------------------------------------------------------*/
- /* Variable declarations -----------------------------------------------------*/
- /* Variable definitions ------------------------------------------------------*/
- /* Function declarations -----------------------------------------------------*/
- static bool is_power_of_2(uint32_t x);
- static uint32_t roundup_pow_of_two(uint32_t x);
- /* Function definitions ------------------------------------------------------*/
- /**
- * @brief Allocates a new FIFO and its internal buffer.
- * @param [in] size: The size of the internal buffer to be allocated.
- * @note The size will be rounded-up to a power of 2.
- * @return RingBuffer pointer.
- */
- RingBuffer *RingBuffer_Malloc(uint32_t size)
- {
- RingBuffer *fifo = RING_BUFFER_MALLOC(sizeof(RingBuffer));
- if(fifo != NULL)
- {
- if(is_power_of_2(size) != true)
- {
- if(size > 0x80000000UL)
- {
- RING_BUFFER_FREE(fifo);
- return NULL;
- }
- size = roundup_pow_of_two(size);
- }
- fifo->buffer = RING_BUFFER_MALLOC(size);
- if(fifo->buffer == NULL)
- {
- RING_BUFFER_FREE(fifo);
- return NULL;
- }
- fifo->size = size;
- fifo->in = fifo->out = 0;
- }
- return fifo;
- }
- /**
- * @brief Frees the FIFO.
- * @param [in] fifo: The fifo to be freed.
- * @return None.
- */
- void RingBuffer_Free(RingBuffer *fifo)
- {
- RING_BUFFER_FREE(fifo->buffer);
- RING_BUFFER_FREE(fifo);
- }
- /**
- * @brief Puts some data into the FIFO.
- * @param [in] fifo: The fifo to be used.
- * @param [in] in: The data to be added.
- * @param [in] len: The length of the data to be added.
- * @return The number of bytes copied.
- * @note This function copies at most @len bytes from the @in into
- * the FIFO depending on the free space, and returns the number
- * of bytes copied.
- */
- uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len)
- {
- len = min(len, RingBuffer_Avail(fifo));
- /* First put the data starting from fifo->in to buffer end. */
- uint32_t l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));
- memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), in, l);
- /* Then put the rest (if any) at the beginning of the buffer. */
- memcpy(fifo->buffer, (uint8_t *)in + l, len - l);
- fifo->in += len;
- return len;
- }
- /**
- * @brief Gets some data from the FIFO.
- * @param [in] fifo: The fifo to be used.
- * @param [in] out: Where the data must be copied.
- * @param [in] len: The size of the destination buffer.
- * @return The number of copied bytes.
- * @note This function copies at most @len bytes from the FIFO into
- * the @out and returns the number of copied bytes.
- */
- uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len)
- {
- len = min(len, RingBuffer_Len(fifo));
- /* First get the data from fifo->out until the end of the buffer. */
- uint32_t l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));
- memcpy(out, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
- /* Then get the rest (if any) from the beginning of the buffer. */
- memcpy((uint8_t *)out + l, fifo->buffer, len - l);
- fifo->out += len;
- return len;
- }
- /**
- * @brief Determine whether some value is a power of two.
- * @param [in] x: The number to be confirmed.
- * @retval true: Yes.
- * @retval false: No.
- * @note Where zero is not considered a power of two.
- */
- static bool is_power_of_2(uint32_t x)
- {
- return (x != 0) && ((x & (x - 1)) == 0);
- }
- /**
- * @brief Round the given value up to nearest power of two.
- * @param [in] x: The number to be converted.
- * @return The power of two.
- */
- static uint32_t roundup_pow_of_two(uint32_t x)
- {
- uint32_t b = 0;
- for(int i = 0; i < 32; i++)
- {
- b = 1UL << i;
- if(x <= b)
- {
- break;
- }
- }
- return b;
- }</div><div></div>
复制代码
CAN.h 文件
- /**
- ******************************************************************************
- * @file CAN.h
- * @author XinLi
- * @version v1.0
- * @date 24-June-2018
- * @brief Header file for CAN.c module.
- ******************************************************************************
- * @attention
- *
- * <h2><center>Copyright © 2018 XinLi</center></h2>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
- *
- ******************************************************************************
- */
- #ifndef __CAN_H
- #define __CAN_H
- #ifdef __cplusplus
- extern "C" {
- #endif
- /* Header includes -----------------------------------------------------------*/
- #include "stm32f10x.h"
- #include <stdbool.h>
- /* Macro definitions ---------------------------------------------------------*/
- /******************************* CAN1 Configure *******************************/
- #define CAN1_TX_BUFFER_SIZE (16)
- #define CAN1_RX_BUFFER_SIZE (16)
- #define CAN1_TX_GPIO_CLOCK RCC_APB2Periph_GPIOB
- #define CAN1_RX_GPIO_CLOCK RCC_APB2Periph_GPIOB
- #define CAN1_TX_GPIO_PORT GPIOB
- #define CAN1_RX_GPIO_PORT GPIOB
- #define CAN1_TX_GPIO_PIN GPIO_Pin_9
- #define CAN1_RX_GPIO_PIN GPIO_Pin_8
- #define CAN1_IRQ_PREEMPT_PRIORITY (0)
- #define CAN1_IRQ_SUB_PRIORITY (0)
- #define CAN1_PORT_REMAP() GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE)
- /******************************************************************************/
- #ifdef STM32F10X_CL
- /******************************* CAN2 Configure *******************************/
- #define CAN2_TX_BUFFER_SIZE (16)
- #define CAN2_RX_BUFFER_SIZE (16)
- #define CAN2_TX_GPIO_CLOCK RCC_APB2Periph_GPIOB
- #define CAN2_RX_GPIO_CLOCK RCC_APB2Periph_GPIOB
- #define CAN2_TX_GPIO_PORT GPIOB
- #define CAN2_RX_GPIO_PORT GPIOB
- #define CAN2_TX_GPIO_PIN GPIO_Pin_13
- #define CAN2_RX_GPIO_PIN GPIO_Pin_12
- #define CAN2_IRQ_PREEMPT_PRIORITY (0)
- #define CAN2_IRQ_SUB_PRIORITY (0)
- #define CAN2_PORT_REMAP() GPIO_PinRemapConfig(GPIO_Remap_CAN2 , DISABLE)
- /******************************************************************************/
- #endif /* STM32F10X_CL */
- /* Type definitions ----------------------------------------------------------*/
- typedef enum
- {
- CAN_WorkModeNormal = CAN_Mode_Normal,
- CAN_WorkModeLoopBack = CAN_Mode_LoopBack
- }CAN_WorkMode;
- typedef enum
- {
- CAN_BaudRate1000K = 6,
- CAN_BaudRate500K = 12,
- CAN_BaudRate250K = 24,
- CAN_BaudRate125K = 48,
- CAN_BaudRate100K = 60,
- CAN_BaudRate50K = 120,
- CAN_BaudRate20K = 300,
- CAN_BaudRate10K = 600
- }CAN_BaudRate;
- /* Variable declarations -----------------------------------------------------*/
- /* Variable definitions ------------------------------------------------------*/
- /* Function declarations -----------------------------------------------------*/
- void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId);
- void CAN_Unconfigure(CAN_TypeDef *CANx);
- void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));
- void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));
- uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number);
- uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number);
- uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx);
- uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx);
- uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx);
- uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx);
- bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx);
- bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx);
- bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx);
- bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx);
- void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx);
- void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx);
- bool CAN_IsTransmitMessage(CAN_TypeDef *CANx);
- /* Function definitions ------------------------------------------------------*/
- #ifdef __cplusplus
- }
- #endif
- #endif /* __CAN_H */
复制代码
CAN.c 文件
- /**
- ******************************************************************************
- * @file CAN.c
- * @author XinLi
- * @version v1.0
- * @date 24-June-2018
- * @brief CAN module driver.
- ******************************************************************************
- * @attention
- *
- * <h2><center>Copyright © 2018 XinLi</center></h2>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
- *
- ******************************************************************************
- */
- /* Header includes -----------------------------------------------------------*/
- #include "CAN.h"
- #include "RingBuffer.h"
- /* Macro definitions ---------------------------------------------------------*/
- /* Type definitions ----------------------------------------------------------*/
- /* Variable declarations -----------------------------------------------------*/
- static volatile bool can1InitFlag = false;
- static volatile bool can1TransmitFlag = false;
- static volatile void (*can1TransmitFinishCallback)(void) = 0;
- static volatile void (*can1ReceiveFinishCallback)(void) = 0;
- static RingBuffer *can1TxBuffer = 0;
- static RingBuffer *can1RxBuffer = 0;
- #ifdef STM32F10X_CL
- static volatile bool can2InitFlag = false;
- static volatile bool can2TransmitFlag = false;
- static volatile void (*can2TransmitFinishCallback)(void) = 0;
- static volatile void (*can2ReceiveFinishCallback)(void) = 0;
- static RingBuffer *can2TxBuffer = 0;
- static RingBuffer *can2RxBuffer = 0;
- #endif /* STM32F10X_CL */
- /* Variable definitions ------------------------------------------------------*/
- /* Function declarations -----------------------------------------------------*/
- /* Function definitions ------------------------------------------------------*/
- /**
- * @brief CAN configure.
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
- * @param [in] WorkMode: Work mode.
- * @param [in] BaudRate: Communication baud rate.
- * @param [in] StdId: Filter standard frame ID.
- * @param [in] ExtId: Filter extended frame ID.
- * @return None.
- */
- void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId)
- {
- GPIO_InitTypeDef GPIO_InitStructure = {0};
- CAN_InitTypeDef CAN_InitStructure = {0};
- CAN_FilterInitTypeDef CAN_FilterInitStructure = {0};
- NVIC_InitTypeDef NVIC_InitStructure = {0};
- if(CANx == CAN1)
- {
- if(can1InitFlag == false)
- {
- can1InitFlag = true;
- can1TransmitFlag = false;
- can1TransmitFinishCallback = 0;
- can1ReceiveFinishCallback = 0;
- can1TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN1_TX_BUFFER_SIZE);
- can1RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN1_RX_BUFFER_SIZE);
- #ifdef STM32F10X_CL
- if(can2InitFlag == false)
- #endif /* STM32F10X_CL */
- {
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
- }
- RCC_APB2PeriphClockCmd(CAN1_TX_GPIO_CLOCK | CAN1_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);
- GPIO_InitStructure.GPIO_Pin = CAN1_TX_GPIO_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(CAN1_TX_GPIO_PORT, &GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = CAN1_RX_GPIO_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_Init(CAN1_RX_GPIO_PORT, &GPIO_InitStructure);
- CAN1_PORT_REMAP();
- CAN_InitStructure.CAN_Prescaler = BaudRate;
- CAN_InitStructure.CAN_Mode = WorkMode;
- CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
- CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
- CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;
- CAN_InitStructure.CAN_TTCM = DISABLE;
- CAN_InitStructure.CAN_ABOM = ENABLE;
- CAN_InitStructure.CAN_AWUM = DISABLE;
- CAN_InitStructure.CAN_NART = ENABLE;
- CAN_InitStructure.CAN_RFLM = DISABLE;
- CAN_InitStructure.CAN_TXFP = ENABLE;
- CAN_DeInit(CAN1);
- CAN_Init(CAN1, &CAN_InitStructure);
- CAN_FilterInitStructure.CAN_FilterIdHigh = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);
- CAN_FilterInitStructure.CAN_FilterIdLow = (uint16_t)(((StdId<<18)|ExtId)<<3);
- CAN_FilterInitStructure.CAN_FilterMaskIdHigh = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;
- CAN_FilterInitStructure.CAN_FilterMaskIdLow = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;
- CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
- CAN_FilterInitStructure.CAN_FilterNumber = 0;
- CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
- CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
- CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
- CAN_FilterInit(&CAN_FilterInitStructure);
- CAN_ITConfig(CAN1, 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);
- CAN_ITConfig(CAN1, CAN_IT_TME | CAN_IT_FMP0, ENABLE);
- #ifdef STM32F10X_CL
- NVIC_InitStructure.NVIC_IRQChannel = CAN1_TX_IRQn;
- #else
- NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn;
- #endif /* STM32F10X_CL */
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = CAN1_IRQ_SUB_PRIORITY;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- #ifdef STM32F10X_CL
- NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
- #else
- NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
- #endif /* STM32F10X_CL */
- NVIC_Init(&NVIC_InitStructure);
- }
- }
- #ifdef STM32F10X_CL
- if(CANx == CAN2)
- {
- if(can2InitFlag == false)
- {
- can2InitFlag = true;
- can2TransmitFlag = false;
- can2TransmitFinishCallback = 0;
- can2ReceiveFinishCallback = 0;
- can2TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN2_TX_BUFFER_SIZE);
- can2RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN2_RX_BUFFER_SIZE);
- if(can1InitFlag == false)
- {
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
- }
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);
- RCC_APB2PeriphClockCmd(CAN2_TX_GPIO_CLOCK | CAN2_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);
- GPIO_InitStructure.GPIO_Pin = CAN2_TX_GPIO_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(CAN2_TX_GPIO_PORT, &GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = CAN2_RX_GPIO_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_Init(CAN2_RX_GPIO_PORT, &GPIO_InitStructure);
- CAN2_PORT_REMAP();
- CAN_InitStructure.CAN_Prescaler = BaudRate;
- CAN_InitStructure.CAN_Mode = WorkMode;
- CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
- CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
- CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;
- CAN_InitStructure.CAN_TTCM = DISABLE;
- CAN_InitStructure.CAN_ABOM = ENABLE;
- CAN_InitStructure.CAN_AWUM = DISABLE;
- CAN_InitStructure.CAN_NART = ENABLE;
- CAN_InitStructure.CAN_RFLM = DISABLE;
- CAN_InitStructure.CAN_TXFP = ENABLE;
- CAN_DeInit(CAN2);
- CAN_Init(CAN2, &CAN_InitStructure);
- CAN_FilterInitStructure.CAN_FilterIdHigh = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);
- CAN_FilterInitStructure.CAN_FilterIdLow = (uint16_t)(((StdId<<18)|ExtId)<<3);
- CAN_FilterInitStructure.CAN_FilterMaskIdHigh = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;
- CAN_FilterInitStructure.CAN_FilterMaskIdLow = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;
- CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
- CAN_FilterInitStructure.CAN_FilterNumber = 14;
- CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
- CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
- CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
- CAN_FilterInit(&CAN_FilterInitStructure);
- CAN_ITConfig(CAN2, 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);
- CAN_ITConfig(CAN2, CAN_IT_TME | CAN_IT_FMP0, ENABLE);
- NVIC_InitStructure.NVIC_IRQChannel = CAN2_TX_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = CAN2_IRQ_SUB_PRIORITY;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;
- NVIC_Init(&NVIC_InitStructure);
- }
- }
- #endif /* STM32F10X_CL */
- }
- /**
- * @brief CAN unconfigure.
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
- * @return None.
- */
- void CAN_Unconfigure(CAN_TypeDef *CANx)
- {
- NVIC_InitTypeDef NVIC_InitStructure = {0};
- if(CANx == CAN1)
- {
- if(can1InitFlag == true)
- {
- can1InitFlag = false;
- #ifdef STM32F10X_CL
- NVIC_InitStructure.NVIC_IRQChannel = CAN1_TX_IRQn;
- #else
- NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn;
- #endif /* STM32F10X_CL */
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = CAN1_IRQ_SUB_PRIORITY;
- NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
- NVIC_Init(&NVIC_InitStructure);
- #ifdef STM32F10X_CL
- NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
- #else
- NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
- #endif /* STM32F10X_CL */
- NVIC_Init(&NVIC_InitStructure);
- CAN_DeInit(CAN1);
- #ifdef STM32F10X_CL
- if(can2InitFlag == false)
- #endif /* STM32F10X_CL */
- {
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);
- }
- can1TransmitFlag = false;
- can1TransmitFinishCallback = 0;
- can1ReceiveFinishCallback = 0;
- RingBuffer_Free(can1TxBuffer);
- RingBuffer_Free(can1RxBuffer);
- }
- }
- #ifdef STM32F10X_CL
- if(CANx == CAN2)
- {
- if(can2InitFlag == true)
- {
- can2InitFlag = false;
- NVIC_InitStructure.NVIC_IRQChannel = CAN2_TX_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = CAN2_IRQ_SUB_PRIORITY;
- NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
- NVIC_Init(&NVIC_InitStructure);
- NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;
- NVIC_Init(&NVIC_InitStructure);
- CAN_DeInit(CAN2);
- if(can1InitFlag == false)
- {
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);
- }
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, DISABLE);
- can2TransmitFlag = false;
- can2TransmitFinishCallback = 0;
- can2ReceiveFinishCallback = 0;
- RingBuffer_Free(can2TxBuffer);
- RingBuffer_Free(can2RxBuffer);
- }
- }
- #endif /* STM32F10X_CL */
- }
- /**
- * @brief CAN set transmit finish callback.
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
- * @param [in] Callback: Callback.
- * @return None.
- */
- void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))
- {
- if(CANx == CAN1)
- {
- if(can1InitFlag == true)
- {
- can1TransmitFinishCallback = (volatile void (*)(void))Callback;
- }
- }
- #ifdef STM32F10X_CL
- if(CANx == CAN2)
- {
- if(can2InitFlag == true)
- {
- can2TransmitFinishCallback = (volatile void (*)(void))Callback;
- }
- }
- #endif /* STM32F10X_CL */
- }
- /**
- * @brief CAN set receive finish callback.
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
- * @param [in] Callback: Callback.
- * @return None.
- */
- void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))
- {
- if(CANx == CAN1)
- {
- if(can1InitFlag == true)
- {
- can1ReceiveFinishCallback = (volatile void (*)(void))Callback;
- }
- }
- #ifdef STM32F10X_CL
- if(CANx == CAN2)
- {
- if(can2InitFlag == true)
- {
- can2ReceiveFinishCallback = (volatile void (*)(void))Callback;
- }
- }
- #endif /* STM32F10X_CL */
- }
- /**
- * @brief CAN set transmit message.
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
- * @param [in] Message: The address of the message to be transmit.
- * @param [in] Number: The number of the message to be transmit.
- * @return The number of message transmit.
- */
- uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number)
- {
- if(CANx == CAN1)
- {
- if(can1InitFlag == true)
- {
- uint32_t available = RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);
- if(available > Number)
- {
- Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);
- }
- else
- {
- Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);
- }
- if(Number > 0)
- {
- if(can1TransmitFlag == false)
- {
- can1TransmitFlag = true;
- CanTxMsg canTxMsg = {0};
- RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg));
- CAN_Transmit(CAN1, &canTxMsg);
- }
- }
- return Number;
- }
- }
- #ifdef STM32F10X_CL
- if(CANx == CAN2)
- {
- if(can2InitFlag == true)
- {
- uint32_t available = RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);
- if(available > Number)
- {
- Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);
- }
- else
- {
- Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);
- }
- if(Number > 0)
- {
- if(can2TransmitFlag == false)
- {
- can2TransmitFlag = true;
- CanTxMsg canTxMsg = {0};
- RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg));
- CAN_Transmit(CAN2, &canTxMsg);
- }
- }
- return Number;
- }
- }
- #endif /* STM32F10X_CL */
- return 0;
- }
- /**
- * @brief CAN get receive message.
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
- * @param [in] Message: To store the address of the receive message.
- * @param [in] Number: To read the number of the received message.
- * @return The number of message obtained.
- */
- uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number)
- {
- if(CANx == CAN1)
- {
- if(can1InitFlag == true)
- {
- return RingBuffer_Out(can1RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);
- }
- }
- #ifdef STM32F10X_CL
- if(CANx == CAN2)
- {
- if(can2InitFlag == true)
- {
- return RingBuffer_Out(can2RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);
- }
- }
- #endif /* STM32F10X_CL */
- return 0;
- }
- /**
- * @brief Get the size of the CAN transmit buffer used.
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
- * @return Used the size of the transmit buffer.
- */
- uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx)
- {
- if(CANx == CAN1)
- {
- if(can1InitFlag == true)
- {
- return RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg);
- }
- }
- #ifdef STM32F10X_CL
- if(CANx == CAN2)
- {
- if(can2InitFlag == true)
- {
- return RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg);
- }
- }
- #endif /* STM32F10X_CL */
- return 0;
- }
- /**
- * @brief Get the size of the CAN receive buffer used.
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
- * @return Used the size of the receive buffer.
- */
- uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx)
- {
- if(CANx == CAN1)
- {
- if(can1InitFlag == true)
- {
- return RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg);
- }
- }
- #ifdef STM32F10X_CL
- if(CANx == CAN2)
- {
- if(can2InitFlag == true)
- {
- return RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg);
- }
- }
- #endif /* STM32F10X_CL */
- return 0;
- }
- /**
- * @brief Get the size of the CAN transmit buffer unused.
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
- * @return Unused the size of the transmit buffer.
- */
- uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx)
- {
- if(CANx == CAN1)
- {
- if(can1InitFlag == true)
- {
- return RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);
- }
- }
- #ifdef STM32F10X_CL
- if(CANx == CAN2)
- {
- if(can2InitFlag == true)
- {
- return RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);
- }
- }
- #endif /* STM32F10X_CL */
- return 0;
- }
- /**
- * @brief Get the size of the CAN receive buffer unused.
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
- * @return Unused the size of the receive buffer.
- */
- uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx)
- {
- if(CANx == CAN1)
- {
- if(can1InitFlag == true)
- {
- return RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg);
- }
- }
- #ifdef STM32F10X_CL
- if(CANx == CAN2)
- {
- if(can2InitFlag == true)
- {
- return RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg);
- }
- }
- #endif /* STM32F10X_CL */
- return 0;
- }
- /**
- * @brief Is the CAN transmit buffer empty?
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
- * @retval true: The transmit buffer is empty.
- * @retval false: The transmit buffer is not empty.
- */
- bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx)
- {
- if(CANx == CAN1)
- {
- if(can1InitFlag == true)
- {
- return !(RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg));
- }
- }
- #ifdef STM32F10X_CL
- if(CANx == CAN2)
- {
- if(can2InitFlag == true)
- {
- return !(RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg));
- }
- }
- #endif /* STM32F10X_CL */
- return false;
- }
- /**
- * @brief Is the CAN receive buffer empty?
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
- * @retval true: The receive buffer is empty.
- * @retval false: The receive buffer is not empty.
- */
- bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx)
- {
- if(CANx == CAN1)
- {
- if(can1InitFlag == true)
- {
- return !(RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg));
- }
- }
- #ifdef STM32F10X_CL
- if(CANx == CAN2)
- {
- if(can2InitFlag == true)
- {
- return !(RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg));
- }
- }
- #endif /* STM32F10X_CL */
- return false;
- }
- /**
- * @brief Is the CAN transmit buffer full?
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
- * @retval true: The transmit buffer is full.
- * @retval false: The transmit buffer is not full.
- */
- bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx)
- {
- if(CANx == CAN1)
- {
- if(can1InitFlag == true)
- {
- return !(RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg));
- }
- }
- #ifdef STM32F10X_CL
- if(CANx == CAN2)
- {
- if(can2InitFlag == true)
- {
- return !(RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg));
- }
- }
- #endif /* STM32F10X_CL */
- return false;
- }
- /**
- * @brief Is the CAN receive buffer full?
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
- * @retval true: The receive buffer is full.
- * @retval false: The receive buffer is not full.
- */
- bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx)
- {
- if(CANx == CAN1)
- {
- if(can1InitFlag == true)
- {
- return !(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg));
- }
- }
- #ifdef STM32F10X_CL
- if(CANx == CAN2)
- {
- if(can2InitFlag == true)
- {
- return !(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg));
- }
- }
- #endif /* STM32F10X_CL */
- return false;
- }
- /**
- * @brief Clear the CAN transmit buffer.
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
- * @return None.
- */
- void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx)
- {
- if(CANx == CAN1)
- {
- if(can1InitFlag == true)
- {
- RingBuffer_Reset(can1TxBuffer);
- }
- }
- #ifdef STM32F10X_CL
- if(CANx == CAN2)
- {
- if(can2InitFlag == true)
- {
- RingBuffer_Reset(can2TxBuffer);
- }
- }
- #endif /* STM32F10X_CL */
- }
- /**
- * @brief Clear the CAN receive buffer.
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
- * @return None.
- */
- void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx)
- {
- if(CANx == CAN1)
- {
- if(can1InitFlag == true)
- {
- RingBuffer_Reset(can1RxBuffer);
- }
- }
- #ifdef STM32F10X_CL
- if(CANx == CAN2)
- {
- if(can2InitFlag == true)
- {
- RingBuffer_Reset(can2RxBuffer);
- }
- }
- #endif /* STM32F10X_CL */
- }
- /**
- * @brief Is the CAN transmit a message?
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
- * @retval true: Is transmit a message.
- * @retval false: Not transmit a message.
- */
- bool CAN_IsTransmitMessage(CAN_TypeDef *CANx)
- {
- if(CANx == CAN1)
- {
- if(can1InitFlag == true)
- {
- return can1TransmitFlag;
- }
- }
- #ifdef STM32F10X_CL
- if(CANx == CAN2)
- {
- if(can2InitFlag == true)
- {
- return can2TransmitFlag;
- }
- }
- #endif /* STM32F10X_CL */
- return false;
- }
- /**
- * @brief This function handles CAN1 TX Handler.
- * @param None.
- * @return None.
- */
- #ifdef STM32F10X_CL
- void CAN1_TX_IRQHandler(void)
- #else
- void USB_HP_CAN1_TX_IRQHandler(void)
- #endif /* STM32F10X_CL */
- {
- if(CAN_GetITStatus(CAN1, CAN_IT_TME) != RESET)
- {
- CAN_ClearITPendingBit(CAN1, CAN_IT_TME);
- CanTxMsg canTxMsg = {0};
- uint8_t number = RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);
- if(number > 0)
- {
- CAN_Transmit(CAN1, &canTxMsg);
- }
- else
- {
- can1TransmitFlag = false;
- if(can1TransmitFinishCallback != 0)
- {
- can1TransmitFinishCallback();
- }
- }
- }
- }
- /**
- * @brief This function handles CAN1 RX0 Handler.
- * @param None.
- * @return None.
- */
- #ifdef STM32F10X_CL
- void CAN1_RX0_IRQHandler(void)
- #else
- void USB_LP_CAN1_RX0_IRQHandler(void)
- #endif /* STM32F10X_CL */
- {
- if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)
- {
- CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);
- CanRxMsg canRxMsg = {0};
- CAN_Receive(CAN1, CAN_FIFO0, &canRxMsg);
- if(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg) > 0)
- {
- RingBuffer_In(can1RxBuffer, &canRxMsg, sizeof(canRxMsg));
- }
- if(can1ReceiveFinishCallback != 0)
- {
- can1ReceiveFinishCallback();
- }
- }
- }
- #ifdef STM32F10X_CL
- /**
- * @brief This function handles CAN2 TX Handler.
- * @param None.
- * @return None.
- */
- void CAN2_TX_IRQHandler(void)
- {
- if(CAN_GetITStatus(CAN2, CAN_IT_TME) != RESET)
- {
- CAN_ClearITPendingBit(CAN2, CAN_IT_TME);
- CanTxMsg canTxMsg = {0};
- uint8_t number = RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);
- if(number > 0)
- {
- CAN_Transmit(CAN2, &canTxMsg);
- }
- else
- {
- can2TransmitFlag = false;
- if(can2TransmitFinishCallback != 0)
- {
- can2TransmitFinishCallback();
- }
- }
- }
- }
- /**
- * @brief This function handles CAN2 RX0 Handler.
- * @param None.
- * @return None.
- */
- void CAN2_RX0_IRQHandler(void)
- {
- if(CAN_GetITStatus(CAN2, CAN_IT_FMP0) != RESET)
- {
- CAN_ClearITPendingBit(CAN2, CAN_IT_FMP0);
- CanRxMsg canRxMsg = {0};
- CAN_Receive(CAN2, CAN_FIFO0, &canRxMsg);
- if(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg) > 0)
- {
- RingBuffer_In(can2RxBuffer, &canRxMsg, sizeof(canRxMsg));
- }
- if(can2ReceiveFinishCallback != 0)
- {
- can2ReceiveFinishCallback();
- }
- }
- }
- #endif /* STM32F10X_CL */
复制代码
main.h 文件
- /**
- ******************************************************************************
- * @file main.h
- * @author XinLi
- * @version v1.0
- * @date 24-June-2018
- * @brief Header file for main.c module.
- ******************************************************************************
- * @attention
- *
- * <h2><center>Copyright © 2018 XinLi</center></h2>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
- *
- ******************************************************************************
- */
- #ifndef __MAIN_H
- #define __MAIN_H
- #ifdef __cplusplus
- extern "C" {
- #endif
- /* Header includes -----------------------------------------------------------*/
- #include "stm32f10x.h"
- /* Macro definitions ---------------------------------------------------------*/
- /* Type definitions ----------------------------------------------------------*/
- /* Variable declarations -----------------------------------------------------*/
- /* Variable definitions ------------------------------------------------------*/
- /* Function declarations -----------------------------------------------------*/
- /* Function definitions ------------------------------------------------------*/
- #ifdef __cplusplus
- }
- #endif
- #endif /* __MAIN_H */
复制代码
main.c 文件
- /**
- ******************************************************************************
- * @file main.c
- * @author XinLi
- * @version v1.0
- * @date 24-June-2018
- * @brief Main program body.
- ******************************************************************************
- * @attention
- *
- * <h2><center>Copyright © 2018 XinLi</center></h2>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
- *
- ******************************************************************************
- */
- /* Header includes -----------------------------------------------------------*/
- #include "main.h"
- #include "CAN.h"
- #ifdef _RTE_
- #include "RTE_Components.h"
- #endif
- #ifdef RTE_CMSIS_RTOS2
- #include "cmsis_os2.h"
- #endif
- /* Macro definitions ---------------------------------------------------------*/
- /* Type definitions ----------------------------------------------------------*/
- /* Variable declarations -----------------------------------------------------*/
- /* Variable definitions ------------------------------------------------------*/
- static CanTxMsg canTxMsg = {0};
- static CanRxMsg canRxMsg = {0};
- /* Function declarations -----------------------------------------------------*/
- static void SystemClock_Config(void);
- /* Function definitions ------------------------------------------------------*/
- /**
- * @brief Main program.
- * @param None.
- * @return None.
- */
- int main(void)
- {
- /* Configure the system clock to 72 MHz */
- SystemClock_Config();
- SystemCoreClockUpdate();
- /* Add your application code here */
- CAN_Configure(CAN1, CAN_WorkModeLoopBack, CAN_BaudRate250K, 0xAA55, 0x55AA);
- #ifdef RTE_CMSIS_RTOS2
- /* Initialize CMSIS-RTOS2 */
- osKernelInitialize();
- /* Create thread functions that start executing,
- Example: osThreadNew(app_main, NULL, NULL); */
- /* Start thread execution */
- osKernelStart();
- #endif
- /* Infinite loop */
- while(1)
- {
- canTxMsg.StdId = 0xAA55;
- canTxMsg.ExtId = 0x55AA;
- canTxMsg.IDE = CAN_ID_STD;
- canTxMsg.RTR = CAN_RTR_DATA;
- canTxMsg.DLC = 8;
- canTxMsg.Data[0]++;
- canTxMsg.Data[1]++;
- canTxMsg.Data[2]++;
- canTxMsg.Data[3]++;
- canTxMsg.Data[4]++;
- canTxMsg.Data[5]++;
- canTxMsg.Data[6]++;
- canTxMsg.Data[7]++;
- CAN_SetTransmitMessage(CAN1, &canTxMsg, 1);
- while(CAN_IsReceiveBufferEmpty(CAN1) == true);
- CAN_GetReceiveMessage(CAN1, &canRxMsg, 1);
- }
- }
- /**
- * @brief System Clock Configuration.
- * The system Clock is configured as follow :
- * System Clock source = PLL (HSE)
- * SYSCLK(Hz) = 72000000
- * HCLK(Hz) = 72000000
- * AHB Prescaler = 1
- * APB1 Prescaler = 2
- * APB2 Prescaler = 1
- * HSE Frequency(Hz) = 8000000
- * HSE PREDIV1 = 1
- * PLLMUL = 9
- * Flash Latency(WS) = 2
- * @param None.
- * @return None.
- */
- static void SystemClock_Config(void)
- {
- /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration */
- /* RCC system reset */
- RCC_DeInit();
- /* Enable HSE */
- RCC_HSEConfig(RCC_HSE_ON);
- /* Wait till HSE is ready */
- ErrorStatus HSEStartUpStatus = RCC_WaitForHSEStartUp();
- if(HSEStartUpStatus == SUCCESS)
- {
- /* Enable Prefetch Buffer */
- FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
- /* Flash 2 wait state */
- FLASH_SetLatency(FLASH_Latency_2);
- /* HCLK = SYSCLK */
- RCC_HCLKConfig(RCC_SYSCLK_Div1);
- /* PCLK2 = HCLK */
- RCC_PCLK2Config(RCC_HCLK_Div1);
- /* PCLK1 = HCLK / 2 */
- RCC_PCLK1Config(RCC_HCLK_Div2);
- /* Configure PLLs */
- #ifdef STM32F10X_CL
- /* PLL2 configuration: PLL2CLK = (HSE(8MHz) / 2) * 10 = 40MHz */
- RCC_PREDIV2Config(RCC_PREDIV2_Div2);
- RCC_PLL2Config(RCC_PLL2Mul_10);
- /* Enable PLL2 */
- RCC_PLL2Cmd(ENABLE);
- /* Wait till PLL2 is ready */
- while(RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET);
- /* PLL configuration: PLLCLK = (PLL2(40MHz) / 5) * 9 = 72MHz */
- RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);
- RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);
- #else
- /* PLLCLK = HSE(8MHz) * 9 = 72MHz */
- RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
- #endif
- /* Enable PLL */
- RCC_PLLCmd(ENABLE);
- /* Wait till PLL is ready */
- while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
- /* Select PLL as system clock source */
- RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
- /* Wait till PLL is used as system clock source */
- while(RCC_GetSYSCLKSource() != 0x08);
- }
- else
- {
- /* Disable HSE */
- RCC_HSEConfig(RCC_HSE_OFF);
- /* Enable HSI */
- RCC_HSICmd(ENABLE);
- /* Enable Prefetch Buffer */
- FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
- /* Flash 1 wait state */
- FLASH_SetLatency(FLASH_Latency_1);
- /* HCLK = SYSCLK */
- RCC_HCLKConfig(RCC_SYSCLK_Div1);
- /* PCLK2 = HCLK */
- RCC_PCLK2Config(RCC_HCLK_Div1);
- /* PCLK1 = HCLK */
- RCC_PCLK1Config(RCC_HCLK_Div1);
- /* Configure PLLs */
- /* PLLCLK = HSI(8MHz) / 2 * 9 = 36MHz */
- RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9);
- /* Enable PLL */
- RCC_PLLCmd(ENABLE);
- /* Wait till PLL is ready */
- while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
- /* Select PLL as system clock source */
- RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
- /* Wait till PLL is used as system clock source */
- while(RCC_GetSYSCLKSource() != 0x08);
- }
- }
- #ifdef USE_FULL_ASSERT
- /**
- * @brief Reports the name of the source file and the source line number
- * where the assert_param error has occurred.
- * @param file: pointer to the source file name.
- * @param line: assert_param error line source number.
- * @return None.
- */
- void assert_failed(uint8_t *file, uint32_t line)
- {
- /* User can add his own implementation to report the file name and line number,
- ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
- /* Infinite loop */
- while(1)
- {
- }
- }
- #endif
复制代码
3,注意
CAN 消息发送缓冲区和接收缓冲区的大小,可以根据应用的需求进行修改,缓冲区使用的是堆内存,需要根据缓冲区大小和应用程序中堆内存使用情况进行配置。
|