你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32F1(CAN)

[复制链接]
STMCU小助手 发布时间:2021-11-26 17:00
1,开发环境

1,固件库:STM32F10x_StdPeriph_Lib_V3.5.0

2,编译器:ARMCC V5.06

3,IDE:Keil uVision5

4,操作系统:Windows 10 专业版


2,程序源码

RingBuffer.h 文件
  1. /**
  2.   ******************************************************************************
  3.   * @file    RingBuffer.h
  4.   * @author  XinLi
  5.   * @version v1.1
  6.   * @date    15-January-2018
  7.   * @brief   Header file for RingBuffer.c module.
  8.   ******************************************************************************
  9.   * @attention
  10.   *
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
  12.   *
  13.   * This program is free software: you can redistribute it and/or modify
  14.   * it under the terms of the GNU General Public License as published by
  15.   * the Free Software Foundation, either version 3 of the License, or
  16.   * (at your option) any later version.
  17.   *
  18.   * This program is distributed in the hope that it will be useful,
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.   * GNU General Public License for more details.
  22.   *
  23.   * You should have received a copy of the GNU General Public License
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
  25.   *
  26.   ******************************************************************************
  27.   */

  28. #ifndef __RINGBUFFER_H
  29. #define __RINGBUFFER_H

  30. #ifdef __cplusplus
  31. extern "C" {
  32. #endif

  33. /* Header includes -----------------------------------------------------------*/
  34. #include <stdint.h>
  35. #include <stdbool.h>
  36. #include <stdlib.h>

  37. /* Macro definitions ---------------------------------------------------------*/
  38. #define RING_BUFFER_MALLOC(size)  malloc(size)
  39. #define RING_BUFFER_FREE(block)   free(block)

  40. /* Type definitions ----------------------------------------------------------*/
  41. typedef struct
  42. {
  43.   uint8_t *buffer;
  44.   uint32_t size;
  45.   uint32_t in;
  46.   uint32_t out;
  47. }RingBuffer;

  48. /* Variable declarations -----------------------------------------------------*/
  49. /* Variable definitions ------------------------------------------------------*/
  50. /* Function declarations -----------------------------------------------------*/
  51. RingBuffer *RingBuffer_Malloc(uint32_t size);
  52. void RingBuffer_Free(RingBuffer *fifo);

  53. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len);
  54. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len);

  55. /* Function definitions ------------------------------------------------------*/

  56. /**
  57.   * @brief  Removes the entire FIFO contents.
  58.   * @param  [in] fifo: The fifo to be emptied.
  59.   * @return None.
  60.   */
  61. static inline void RingBuffer_Reset(RingBuffer *fifo)
  62. {
  63.   fifo->in = fifo->out = 0;
  64. }

  65. /**
  66.   * @brief  Returns the size of the FIFO in bytes.
  67.   * @param  [in] fifo: The fifo to be used.
  68.   * @return The size of the FIFO.
  69.   */
  70. static inline uint32_t RingBuffer_Size(RingBuffer *fifo)
  71. {
  72.   return fifo->size;
  73. }

  74. /**
  75.   * @brief  Returns the number of used bytes in the FIFO.
  76.   * @param  [in] fifo: The fifo to be used.
  77.   * @return The number of used bytes.
  78.   */
  79. static inline uint32_t RingBuffer_Len(RingBuffer *fifo)
  80. {
  81.   return fifo->in - fifo->out;
  82. }

  83. /**
  84.   * @brief  Returns the number of bytes available in the FIFO.
  85.   * @param  [in] fifo: The fifo to be used.
  86.   * @return The number of bytes available.
  87.   */
  88. static inline uint32_t RingBuffer_Avail(RingBuffer *fifo)
  89. {
  90.   return RingBuffer_Size(fifo) - RingBuffer_Len(fifo);
  91. }

  92. /**
  93.   * @brief  Is the FIFO empty?
  94.   * @param  [in] fifo: The fifo to be used.
  95.   * @retval true:      Yes.
  96.   * @retval false:     No.
  97.   */
  98. static inline bool RingBuffer_IsEmpty(RingBuffer *fifo)
  99. {
  100.   return RingBuffer_Len(fifo) == 0;
  101. }

  102. /**
  103.   * @brief  Is the FIFO full?
  104.   * @param  [in] fifo: The fifo to be used.
  105.   * @retval true:      Yes.
  106.   * @retval false:     No.
  107.   */
  108. static inline bool RingBuffer_IsFull(RingBuffer *fifo)
  109. {
  110.   return RingBuffer_Avail(fifo) == 0;
  111. }

  112. #ifdef __cplusplus
  113. }
  114. #endif

  115. #endif /* __RINGBUFFER_H */
复制代码


RingBuffer.c 文件
  1. <div>/**
  2.   ******************************************************************************
  3.   * @file    RingBuffer.c
  4.   * @author  XinLi
  5.   * @version v1.1
  6.   * @date    15-January-2018
  7.   * @brief   Ring buffer module source file.
  8.   ******************************************************************************
  9.   * @attention
  10.   *
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
  12.   *
  13.   * This program is free software: you can redistribute it and/or modify
  14.   * it under the terms of the GNU General Public License as published by
  15.   * the Free Software Foundation, either version 3 of the License, or
  16.   * (at your option) any later version.
  17.   *
  18.   * This program is distributed in the hope that it will be useful,
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.   * GNU General Public License for more details.
  22.   *
  23.   * You should have received a copy of the GNU General Public License
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
  25.   *
  26.   ******************************************************************************
  27.   */

  28. /* Header includes -----------------------------------------------------------*/
  29. #include "RingBuffer.h"
  30. #include <string.h>

  31. /* Macro definitions ---------------------------------------------------------*/
  32. #define min(a, b)  (((a) < (b)) ? (a) : (b))

  33. /* Type definitions ----------------------------------------------------------*/
  34. /* Variable declarations -----------------------------------------------------*/
  35. /* Variable definitions ------------------------------------------------------*/
  36. /* Function declarations -----------------------------------------------------*/
  37. static bool is_power_of_2(uint32_t x);
  38. static uint32_t roundup_pow_of_two(uint32_t x);

  39. /* Function definitions ------------------------------------------------------*/

  40. /**
  41.   * @brief  Allocates a new FIFO and its internal buffer.
  42.   * @param  [in] size: The size of the internal buffer to be allocated.
  43.   * @note   The size will be rounded-up to a power of 2.
  44.   * @return RingBuffer pointer.
  45.   */
  46. RingBuffer *RingBuffer_Malloc(uint32_t size)
  47. {
  48.   RingBuffer *fifo = RING_BUFFER_MALLOC(sizeof(RingBuffer));

  49.   if(fifo != NULL)
  50.   {
  51.     if(is_power_of_2(size) != true)
  52.     {
  53.       if(size > 0x80000000UL)
  54.       {
  55.         RING_BUFFER_FREE(fifo);
  56.         return NULL;
  57.       }

  58.       size = roundup_pow_of_two(size);
  59.     }

  60.     fifo->buffer = RING_BUFFER_MALLOC(size);

  61.     if(fifo->buffer == NULL)
  62.     {
  63.       RING_BUFFER_FREE(fifo);
  64.       return NULL;
  65.     }

  66.     fifo->size = size;
  67.     fifo->in = fifo->out = 0;
  68.   }

  69.   return fifo;
  70. }

  71. /**
  72.   * @brief  Frees the FIFO.
  73.   * @param  [in] fifo: The fifo to be freed.
  74.   * @return None.
  75.   */
  76. void RingBuffer_Free(RingBuffer *fifo)
  77. {
  78.   RING_BUFFER_FREE(fifo->buffer);
  79.   RING_BUFFER_FREE(fifo);
  80. }

  81. /**
  82.   * @brief  Puts some data into the FIFO.
  83.   * @param  [in] fifo: The fifo to be used.
  84.   * @param  [in] in:   The data to be added.
  85.   * @param  [in] len:  The length of the data to be added.
  86.   * @return The number of bytes copied.
  87.   * @note   This function copies at most @len bytes from the @in into
  88.   *         the FIFO depending on the free space, and returns the number
  89.   *         of bytes copied.
  90.   */
  91. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len)
  92. {
  93.   len = min(len, RingBuffer_Avail(fifo));

  94.   /* First put the data starting from fifo->in to buffer end. */
  95.   uint32_t l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));
  96.   memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), in, l);

  97.   /* Then put the rest (if any) at the beginning of the buffer. */
  98.   memcpy(fifo->buffer, (uint8_t *)in + l, len - l);

  99.   fifo->in += len;

  100.   return len;
  101. }

  102. /**
  103.   * @brief  Gets some data from the FIFO.
  104.   * @param  [in] fifo: The fifo to be used.
  105.   * @param  [in] out:  Where the data must be copied.
  106.   * @param  [in] len:  The size of the destination buffer.
  107.   * @return The number of copied bytes.
  108.   * @note   This function copies at most @len bytes from the FIFO into
  109.   *         the @out and returns the number of copied bytes.
  110.   */
  111. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len)
  112. {
  113.   len = min(len, RingBuffer_Len(fifo));

  114.   /* First get the data from fifo->out until the end of the buffer. */
  115.   uint32_t l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));
  116.   memcpy(out, fifo->buffer + (fifo->out & (fifo->size - 1)), l);

  117.   /* Then get the rest (if any) from the beginning of the buffer. */
  118.   memcpy((uint8_t *)out + l, fifo->buffer, len - l);

  119.   fifo->out += len;

  120.   return len;
  121. }

  122. /**
  123.   * @brief  Determine whether some value is a power of two.
  124.   * @param  [in] x: The number to be confirmed.
  125.   * @retval true:   Yes.
  126.   * @retval false:  No.
  127.   * @note   Where zero is not considered a power of two.
  128.   */
  129. static bool is_power_of_2(uint32_t x)
  130. {
  131.   return (x != 0) && ((x & (x - 1)) == 0);
  132. }

  133. /**
  134.   * @brief  Round the given value up to nearest power of two.
  135.   * @param  [in] x: The number to be converted.
  136.   * @return The power of two.
  137.   */
  138. static uint32_t roundup_pow_of_two(uint32_t x)
  139. {
  140.   uint32_t b = 0;

  141.   for(int i = 0; i < 32; i++)
  142.   {
  143.     b = 1UL << i;

  144.     if(x <= b)
  145.     {
  146.       break;
  147.     }
  148.   }

  149.   return b;
  150. }</div><div></div>
复制代码


CAN.h 文件
  1. /**
  2.   ******************************************************************************
  3.   * @file    CAN.h
  4.   * @author  XinLi
  5.   * @version v1.0
  6.   * @date    24-June-2018
  7.   * @brief   Header file for CAN.c module.
  8.   ******************************************************************************
  9.   * @attention
  10.   *
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
  12.   *
  13.   * This program is free software: you can redistribute it and/or modify
  14.   * it under the terms of the GNU General Public License as published by
  15.   * the Free Software Foundation, either version 3 of the License, or
  16.   * (at your option) any later version.
  17.   *
  18.   * This program is distributed in the hope that it will be useful,
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.   * GNU General Public License for more details.
  22.   *
  23.   * You should have received a copy of the GNU General Public License
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
  25.   *
  26.   ******************************************************************************
  27.   */

  28. #ifndef __CAN_H
  29. #define __CAN_H

  30. #ifdef __cplusplus
  31. extern "C" {
  32. #endif

  33. /* Header includes -----------------------------------------------------------*/
  34. #include "stm32f10x.h"
  35. #include <stdbool.h>

  36. /* Macro definitions ---------------------------------------------------------*/

  37. /******************************* CAN1 Configure *******************************/
  38. #define CAN1_TX_BUFFER_SIZE        (16)
  39. #define CAN1_RX_BUFFER_SIZE        (16)

  40. #define CAN1_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
  41. #define CAN1_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB

  42. #define CAN1_TX_GPIO_PORT          GPIOB
  43. #define CAN1_RX_GPIO_PORT          GPIOB

  44. #define CAN1_TX_GPIO_PIN           GPIO_Pin_9
  45. #define CAN1_RX_GPIO_PIN           GPIO_Pin_8

  46. #define CAN1_IRQ_PREEMPT_PRIORITY  (0)
  47. #define CAN1_IRQ_SUB_PRIORITY      (0)

  48. #define CAN1_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE)
  49. /******************************************************************************/

  50. #ifdef STM32F10X_CL
  51. /******************************* CAN2 Configure *******************************/
  52. #define CAN2_TX_BUFFER_SIZE        (16)
  53. #define CAN2_RX_BUFFER_SIZE        (16)

  54. #define CAN2_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
  55. #define CAN2_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB

  56. #define CAN2_TX_GPIO_PORT          GPIOB
  57. #define CAN2_RX_GPIO_PORT          GPIOB

  58. #define CAN2_TX_GPIO_PIN           GPIO_Pin_13
  59. #define CAN2_RX_GPIO_PIN           GPIO_Pin_12

  60. #define CAN2_IRQ_PREEMPT_PRIORITY  (0)
  61. #define CAN2_IRQ_SUB_PRIORITY      (0)

  62. #define CAN2_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap_CAN2 , DISABLE)
  63. /******************************************************************************/
  64. #endif /* STM32F10X_CL */

  65. /* Type definitions ----------------------------------------------------------*/
  66. typedef enum
  67. {
  68.   CAN_WorkModeNormal   = CAN_Mode_Normal,
  69.   CAN_WorkModeLoopBack = CAN_Mode_LoopBack
  70. }CAN_WorkMode;

  71. typedef enum
  72. {
  73.   CAN_BaudRate1000K = 6,
  74.   CAN_BaudRate500K  = 12,
  75.   CAN_BaudRate250K  = 24,
  76.   CAN_BaudRate125K  = 48,
  77.   CAN_BaudRate100K  = 60,
  78.   CAN_BaudRate50K   = 120,
  79.   CAN_BaudRate20K   = 300,
  80.   CAN_BaudRate10K   = 600
  81. }CAN_BaudRate;

  82. /* Variable declarations -----------------------------------------------------*/
  83. /* Variable definitions ------------------------------------------------------*/
  84. /* Function declarations -----------------------------------------------------*/
  85. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId);
  86. void CAN_Unconfigure(CAN_TypeDef *CANx);

  87. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));
  88. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));

  89. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number);
  90. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number);

  91. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx);
  92. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx);
  93. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx);
  94. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx);

  95. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx);
  96. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx);
  97. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx);
  98. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx);

  99. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx);
  100. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx);

  101. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx);

  102. /* Function definitions ------------------------------------------------------*/

  103. #ifdef __cplusplus
  104. }
  105. #endif

  106. #endif /* __CAN_H */
复制代码



CAN.c 文件

  1. /**
  2.   ******************************************************************************
  3.   * @file    CAN.c
  4.   * @author  XinLi
  5.   * @version v1.0
  6.   * @date    24-June-2018
  7.   * @brief   CAN module driver.
  8.   ******************************************************************************
  9.   * @attention
  10.   *
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
  12.   *
  13.   * This program is free software: you can redistribute it and/or modify
  14.   * it under the terms of the GNU General Public License as published by
  15.   * the Free Software Foundation, either version 3 of the License, or
  16.   * (at your option) any later version.
  17.   *
  18.   * This program is distributed in the hope that it will be useful,
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.   * GNU General Public License for more details.
  22.   *
  23.   * You should have received a copy of the GNU General Public License
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
  25.   *
  26.   ******************************************************************************
  27.   */

  28. /* Header includes -----------------------------------------------------------*/
  29. #include "CAN.h"
  30. #include "RingBuffer.h"

  31. /* Macro definitions ---------------------------------------------------------*/
  32. /* Type definitions ----------------------------------------------------------*/
  33. /* Variable declarations -----------------------------------------------------*/
  34. static volatile bool can1InitFlag     = false;
  35. static volatile bool can1TransmitFlag = false;

  36. static volatile void (*can1TransmitFinishCallback)(void) = 0;
  37. static volatile void (*can1ReceiveFinishCallback)(void)  = 0;

  38. static RingBuffer *can1TxBuffer = 0;
  39. static RingBuffer *can1RxBuffer = 0;

  40. #ifdef STM32F10X_CL
  41. static volatile bool can2InitFlag     = false;
  42. static volatile bool can2TransmitFlag = false;

  43. static volatile void (*can2TransmitFinishCallback)(void) = 0;
  44. static volatile void (*can2ReceiveFinishCallback)(void)  = 0;

  45. static RingBuffer *can2TxBuffer = 0;
  46. static RingBuffer *can2RxBuffer = 0;
  47. #endif /* STM32F10X_CL */

  48. /* Variable definitions ------------------------------------------------------*/
  49. /* Function declarations -----------------------------------------------------*/
  50. /* Function definitions ------------------------------------------------------*/

  51. /**
  52.   * @brief  CAN configure.
  53.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.
  54.   * @param  [in] WorkMode: Work mode.
  55.   * @param  [in] BaudRate: Communication baud rate.
  56.   * @param  [in] StdId:    Filter standard frame ID.
  57.   * @param  [in] ExtId:    Filter extended frame ID.
  58.   * @return None.
  59.   */
  60. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId)
  61. {
  62.   GPIO_InitTypeDef      GPIO_InitStructure      = {0};
  63.   CAN_InitTypeDef       CAN_InitStructure       = {0};
  64.   CAN_FilterInitTypeDef CAN_FilterInitStructure = {0};
  65.   NVIC_InitTypeDef      NVIC_InitStructure      = {0};

  66.   if(CANx == CAN1)
  67.   {
  68.     if(can1InitFlag == false)
  69.     {
  70.       can1InitFlag = true;

  71.       can1TransmitFlag = false;

  72.       can1TransmitFinishCallback = 0;
  73.       can1ReceiveFinishCallback  = 0;

  74.       can1TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN1_TX_BUFFER_SIZE);
  75.       can1RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN1_RX_BUFFER_SIZE);

  76. #ifdef STM32F10X_CL
  77.       if(can2InitFlag == false)
  78. #endif /* STM32F10X_CL */
  79.       {
  80.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
  81.       }

  82.       RCC_APB2PeriphClockCmd(CAN1_TX_GPIO_CLOCK | CAN1_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);

  83.       GPIO_InitStructure.GPIO_Pin   = CAN1_TX_GPIO_PIN;
  84.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
  85.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  86.       GPIO_Init(CAN1_TX_GPIO_PORT, &GPIO_InitStructure);

  87.       GPIO_InitStructure.GPIO_Pin   = CAN1_RX_GPIO_PIN;
  88.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
  89.       GPIO_Init(CAN1_RX_GPIO_PORT, &GPIO_InitStructure);

  90.       CAN1_PORT_REMAP();

  91.       CAN_InitStructure.CAN_Prescaler = BaudRate;
  92.       CAN_InitStructure.CAN_Mode      = WorkMode;
  93.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;
  94.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;
  95.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;
  96.       CAN_InitStructure.CAN_TTCM      = DISABLE;
  97.       CAN_InitStructure.CAN_ABOM      = ENABLE;
  98.       CAN_InitStructure.CAN_AWUM      = DISABLE;
  99.       CAN_InitStructure.CAN_NART      = ENABLE;
  100.       CAN_InitStructure.CAN_RFLM      = DISABLE;
  101.       CAN_InitStructure.CAN_TXFP      = ENABLE;

  102.       CAN_DeInit(CAN1);
  103.       CAN_Init(CAN1, &CAN_InitStructure);

  104.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);
  105.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);
  106.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;
  107.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;
  108.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
  109.       CAN_FilterInitStructure.CAN_FilterNumber         = 0;
  110.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;
  111.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;
  112.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;
  113.       CAN_FilterInit(&CAN_FilterInitStructure);

  114.       CAN_ITConfig(CAN1, CAN_IT_TME | CAN_IT_FMP0 |CAN_IT_FF0 | CAN_IT_FOV0 | CAN_IT_FMP1 | CAN_IT_FF1 | CAN_IT_FOV1 |
  115.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);
  116.       CAN_ITConfig(CAN1, CAN_IT_TME | CAN_IT_FMP0, ENABLE);

  117. #ifdef STM32F10X_CL
  118.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;
  119. #else
  120.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;
  121. #endif /* STM32F10X_CL */

  122.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;
  123.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;
  124.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
  125.       NVIC_Init(&NVIC_InitStructure);

  126. #ifdef STM32F10X_CL
  127.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;
  128. #else
  129.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;
  130. #endif /* STM32F10X_CL */

  131.       NVIC_Init(&NVIC_InitStructure);
  132.     }
  133.   }

  134. #ifdef STM32F10X_CL
  135.   if(CANx == CAN2)
  136.   {
  137.     if(can2InitFlag == false)
  138.     {
  139.       can2InitFlag = true;

  140.       can2TransmitFlag = false;

  141.       can2TransmitFinishCallback = 0;
  142.       can2ReceiveFinishCallback  = 0;

  143.       can2TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN2_TX_BUFFER_SIZE);
  144.       can2RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN2_RX_BUFFER_SIZE);

  145.       if(can1InitFlag == false)
  146.       {
  147.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
  148.       }

  149.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);
  150.       RCC_APB2PeriphClockCmd(CAN2_TX_GPIO_CLOCK | CAN2_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);

  151.       GPIO_InitStructure.GPIO_Pin   = CAN2_TX_GPIO_PIN;
  152.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
  153.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  154.       GPIO_Init(CAN2_TX_GPIO_PORT, &GPIO_InitStructure);

  155.       GPIO_InitStructure.GPIO_Pin   = CAN2_RX_GPIO_PIN;
  156.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
  157.       GPIO_Init(CAN2_RX_GPIO_PORT, &GPIO_InitStructure);

  158.       CAN2_PORT_REMAP();

  159.       CAN_InitStructure.CAN_Prescaler = BaudRate;
  160.       CAN_InitStructure.CAN_Mode      = WorkMode;
  161.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;
  162.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;
  163.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;
  164.       CAN_InitStructure.CAN_TTCM      = DISABLE;
  165.       CAN_InitStructure.CAN_ABOM      = ENABLE;
  166.       CAN_InitStructure.CAN_AWUM      = DISABLE;
  167.       CAN_InitStructure.CAN_NART      = ENABLE;
  168.       CAN_InitStructure.CAN_RFLM      = DISABLE;
  169.       CAN_InitStructure.CAN_TXFP      = ENABLE;

  170.       CAN_DeInit(CAN2);
  171.       CAN_Init(CAN2, &CAN_InitStructure);

  172.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);
  173.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);
  174.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;
  175.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;
  176.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
  177.       CAN_FilterInitStructure.CAN_FilterNumber         = 14;
  178.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;
  179.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;
  180.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;
  181.       CAN_FilterInit(&CAN_FilterInitStructure);

  182.       CAN_ITConfig(CAN2, CAN_IT_TME | CAN_IT_FMP0 |CAN_IT_FF0 | CAN_IT_FOV0 | CAN_IT_FMP1 | CAN_IT_FF1 | CAN_IT_FOV1 |
  183.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);
  184.       CAN_ITConfig(CAN2, CAN_IT_TME | CAN_IT_FMP0, ENABLE);

  185.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;
  186.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;
  187.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;
  188.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
  189.       NVIC_Init(&NVIC_InitStructure);

  190.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;
  191.       NVIC_Init(&NVIC_InitStructure);
  192.     }
  193.   }
  194. #endif /* STM32F10X_CL */
  195. }

  196. /**
  197.   * @brief  CAN unconfigure.
  198.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
  199.   * @return None.
  200.   */
  201. void CAN_Unconfigure(CAN_TypeDef *CANx)
  202. {
  203.   NVIC_InitTypeDef NVIC_InitStructure = {0};

  204.   if(CANx == CAN1)
  205.   {
  206.     if(can1InitFlag == true)
  207.     {
  208.       can1InitFlag = false;

  209. #ifdef STM32F10X_CL
  210.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;
  211. #else
  212.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;
  213. #endif /* STM32F10X_CL */

  214.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;
  215.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;
  216.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;
  217.       NVIC_Init(&NVIC_InitStructure);

  218. #ifdef STM32F10X_CL
  219.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;
  220. #else
  221.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;
  222. #endif /* STM32F10X_CL */

  223.       NVIC_Init(&NVIC_InitStructure);

  224.       CAN_DeInit(CAN1);

  225. #ifdef STM32F10X_CL
  226.       if(can2InitFlag == false)
  227. #endif /* STM32F10X_CL */
  228.       {
  229.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);
  230.       }

  231.       can1TransmitFlag = false;

  232.       can1TransmitFinishCallback = 0;
  233.       can1ReceiveFinishCallback  = 0;

  234.       RingBuffer_Free(can1TxBuffer);
  235.       RingBuffer_Free(can1RxBuffer);
  236.     }
  237.   }

  238. #ifdef STM32F10X_CL
  239.   if(CANx == CAN2)
  240.   {
  241.     if(can2InitFlag == true)
  242.     {
  243.       can2InitFlag = false;

  244.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;
  245.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;
  246.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;
  247.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;
  248.       NVIC_Init(&NVIC_InitStructure);

  249.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;
  250.       NVIC_Init(&NVIC_InitStructure);

  251.       CAN_DeInit(CAN2);

  252.       if(can1InitFlag == false)
  253.       {
  254.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);
  255.       }

  256.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, DISABLE);

  257.       can2TransmitFlag = false;

  258.       can2TransmitFinishCallback = 0;
  259.       can2ReceiveFinishCallback  = 0;

  260.       RingBuffer_Free(can2TxBuffer);
  261.       RingBuffer_Free(can2RxBuffer);
  262.     }
  263.   }
  264. #endif /* STM32F10X_CL */
  265. }

  266. /**
  267.   * @brief  CAN set transmit finish callback.
  268.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.
  269.   * @param  [in] Callback: Callback.
  270.   * @return None.
  271.   */
  272. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))
  273. {
  274.   if(CANx == CAN1)
  275.   {
  276.     if(can1InitFlag == true)
  277.     {
  278.       can1TransmitFinishCallback = (volatile void (*)(void))Callback;
  279.     }
  280.   }

  281. #ifdef STM32F10X_CL
  282.   if(CANx == CAN2)
  283.   {
  284.     if(can2InitFlag == true)
  285.     {
  286.       can2TransmitFinishCallback = (volatile void (*)(void))Callback;
  287.     }
  288.   }
  289. #endif /* STM32F10X_CL */
  290. }

  291. /**
  292.   * @brief  CAN set receive finish callback.
  293.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.
  294.   * @param  [in] Callback: Callback.
  295.   * @return None.
  296.   */
  297. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))
  298. {
  299.   if(CANx == CAN1)
  300.   {
  301.     if(can1InitFlag == true)
  302.     {
  303.       can1ReceiveFinishCallback = (volatile void (*)(void))Callback;
  304.     }
  305.   }

  306. #ifdef STM32F10X_CL
  307.   if(CANx == CAN2)
  308.   {
  309.     if(can2InitFlag == true)
  310.     {
  311.       can2ReceiveFinishCallback = (volatile void (*)(void))Callback;
  312.     }
  313.   }
  314. #endif /* STM32F10X_CL */
  315. }

  316. /**
  317.   * @brief  CAN set transmit message.
  318.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.
  319.   * @param  [in] Message: The address of the message to be transmit.
  320.   * @param  [in] Number:  The number of the message to be transmit.
  321.   * @return The number of message transmit.
  322.   */
  323. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number)
  324. {
  325.   if(CANx == CAN1)
  326.   {
  327.     if(can1InitFlag == true)
  328.     {
  329.       uint32_t available = RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);

  330.       if(available > Number)
  331.       {
  332.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);
  333.       }
  334.       else
  335.       {
  336.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);
  337.       }

  338.       if(Number > 0)
  339.       {
  340.         if(can1TransmitFlag == false)
  341.         {
  342.           can1TransmitFlag = true;

  343.           CanTxMsg canTxMsg = {0};
  344.           RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg));
  345.           CAN_Transmit(CAN1, &canTxMsg);
  346.         }
  347.       }

  348.       return Number;
  349.     }
  350.   }

  351. #ifdef STM32F10X_CL
  352.   if(CANx == CAN2)
  353.   {
  354.     if(can2InitFlag == true)
  355.     {
  356.       uint32_t available = RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);

  357.       if(available > Number)
  358.       {
  359.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);
  360.       }
  361.       else
  362.       {
  363.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);
  364.       }

  365.       if(Number > 0)
  366.       {
  367.         if(can2TransmitFlag == false)
  368.         {
  369.           can2TransmitFlag = true;

  370.           CanTxMsg canTxMsg = {0};
  371.           RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg));
  372.           CAN_Transmit(CAN2, &canTxMsg);
  373.         }
  374.       }

  375.       return Number;
  376.     }
  377.   }
  378. #endif /* STM32F10X_CL */

  379.   return 0;
  380. }

  381. /**
  382.   * @brief  CAN get receive message.
  383.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.
  384.   * @param  [in] Message: To store the address of the receive message.
  385.   * @param  [in] Number:  To read the number of the received message.
  386.   * @return The number of message obtained.
  387.   */
  388. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number)
  389. {
  390.   if(CANx == CAN1)
  391.   {
  392.     if(can1InitFlag == true)
  393.     {
  394.       return RingBuffer_Out(can1RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);
  395.     }
  396.   }

  397. #ifdef STM32F10X_CL
  398.   if(CANx == CAN2)
  399.   {
  400.     if(can2InitFlag == true)
  401.     {
  402.       return RingBuffer_Out(can2RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);
  403.     }
  404.   }
  405. #endif /* STM32F10X_CL */

  406.   return 0;
  407. }

  408. /**
  409.   * @brief  Get the size of the CAN transmit buffer used.
  410.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
  411.   * @return Used the size of the transmit buffer.
  412.   */
  413. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx)
  414. {
  415.   if(CANx == CAN1)
  416.   {
  417.     if(can1InitFlag == true)
  418.     {
  419.       return RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg);
  420.     }
  421.   }

  422. #ifdef STM32F10X_CL
  423.   if(CANx == CAN2)
  424.   {
  425.     if(can2InitFlag == true)
  426.     {
  427.       return RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg);
  428.     }
  429.   }
  430. #endif /* STM32F10X_CL */

  431.   return 0;
  432. }

  433. /**
  434.   * @brief  Get the size of the CAN receive buffer used.
  435.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
  436.   * @return Used the size of the receive buffer.
  437.   */
  438. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx)
  439. {
  440.   if(CANx == CAN1)
  441.   {
  442.     if(can1InitFlag == true)
  443.     {
  444.       return RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg);
  445.     }
  446.   }

  447. #ifdef STM32F10X_CL
  448.   if(CANx == CAN2)
  449.   {
  450.     if(can2InitFlag == true)
  451.     {
  452.       return RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg);
  453.     }
  454.   }
  455. #endif /* STM32F10X_CL */

  456.   return 0;
  457. }

  458. /**
  459.   * @brief  Get the size of the CAN transmit buffer unused.
  460.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
  461.   * @return Unused the size of the transmit buffer.
  462.   */
  463. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx)
  464. {
  465.   if(CANx == CAN1)
  466.   {
  467.     if(can1InitFlag == true)
  468.     {
  469.       return RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);
  470.     }
  471.   }

  472. #ifdef STM32F10X_CL
  473.   if(CANx == CAN2)
  474.   {
  475.     if(can2InitFlag == true)
  476.     {
  477.       return RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);
  478.     }
  479.   }
  480. #endif /* STM32F10X_CL */

  481.   return 0;
  482. }

  483. /**
  484.   * @brief  Get the size of the CAN receive buffer unused.
  485.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
  486.   * @return Unused the size of the receive buffer.
  487.   */
  488. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx)
  489. {
  490.   if(CANx == CAN1)
  491.   {
  492.     if(can1InitFlag == true)
  493.     {
  494.       return RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg);
  495.     }
  496.   }

  497. #ifdef STM32F10X_CL
  498.   if(CANx == CAN2)
  499.   {
  500.     if(can2InitFlag == true)
  501.     {
  502.       return RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg);
  503.     }
  504.   }
  505. #endif /* STM32F10X_CL */

  506.   return 0;
  507. }

  508. /**
  509.   * @brief  Is the CAN transmit buffer empty?
  510.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
  511.   * @retval true:      The transmit buffer is empty.
  512.   * @retval false:     The transmit buffer is not empty.
  513.   */
  514. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx)
  515. {
  516.   if(CANx == CAN1)
  517.   {
  518.     if(can1InitFlag == true)
  519.     {
  520.       return !(RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg));
  521.     }
  522.   }

  523. #ifdef STM32F10X_CL
  524.   if(CANx == CAN2)
  525.   {
  526.     if(can2InitFlag == true)
  527.     {
  528.       return !(RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg));
  529.     }
  530.   }
  531. #endif /* STM32F10X_CL */

  532.   return false;
  533. }

  534. /**
  535.   * @brief  Is the CAN receive buffer empty?
  536.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
  537.   * @retval true:      The receive buffer is empty.
  538.   * @retval false:     The receive buffer is not empty.
  539.   */
  540. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx)
  541. {
  542.   if(CANx == CAN1)
  543.   {
  544.     if(can1InitFlag == true)
  545.     {
  546.       return !(RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg));
  547.     }
  548.   }

  549. #ifdef STM32F10X_CL
  550.   if(CANx == CAN2)
  551.   {
  552.     if(can2InitFlag == true)
  553.     {
  554.       return !(RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg));
  555.     }
  556.   }
  557. #endif /* STM32F10X_CL */

  558.   return false;
  559. }

  560. /**
  561.   * @brief  Is the CAN transmit buffer full?
  562.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
  563.   * @retval true:      The transmit buffer is full.
  564.   * @retval false:     The transmit buffer is not full.
  565.   */
  566. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx)
  567. {
  568.   if(CANx == CAN1)
  569.   {
  570.     if(can1InitFlag == true)
  571.     {
  572.       return !(RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg));
  573.     }
  574.   }

  575. #ifdef STM32F10X_CL
  576.   if(CANx == CAN2)
  577.   {
  578.     if(can2InitFlag == true)
  579.     {
  580.       return !(RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg));
  581.     }
  582.   }
  583. #endif /* STM32F10X_CL */

  584.   return false;
  585. }

  586. /**
  587.   * @brief  Is the CAN receive buffer full?
  588.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
  589.   * @retval true:      The receive buffer is full.
  590.   * @retval false:     The receive buffer is not full.
  591.   */
  592. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx)
  593. {
  594.   if(CANx == CAN1)
  595.   {
  596.     if(can1InitFlag == true)
  597.     {
  598.       return !(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg));
  599.     }
  600.   }

  601. #ifdef STM32F10X_CL
  602.   if(CANx == CAN2)
  603.   {
  604.     if(can2InitFlag == true)
  605.     {
  606.       return !(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg));
  607.     }
  608.   }
  609. #endif /* STM32F10X_CL */

  610.   return false;
  611. }

  612. /**
  613.   * @brief  Clear the CAN transmit buffer.
  614.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
  615.   * @return None.
  616.   */
  617. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx)
  618. {
  619.   if(CANx == CAN1)
  620.   {
  621.     if(can1InitFlag == true)
  622.     {
  623.       RingBuffer_Reset(can1TxBuffer);
  624.     }
  625.   }

  626. #ifdef STM32F10X_CL
  627.   if(CANx == CAN2)
  628.   {
  629.     if(can2InitFlag == true)
  630.     {
  631.       RingBuffer_Reset(can2TxBuffer);
  632.     }
  633.   }
  634. #endif /* STM32F10X_CL */
  635. }

  636. /**
  637.   * @brief  Clear the CAN receive buffer.
  638.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
  639.   * @return None.
  640.   */
  641. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx)
  642. {
  643.   if(CANx == CAN1)
  644.   {
  645.     if(can1InitFlag == true)
  646.     {
  647.       RingBuffer_Reset(can1RxBuffer);
  648.     }
  649.   }

  650. #ifdef STM32F10X_CL
  651.   if(CANx == CAN2)
  652.   {
  653.     if(can2InitFlag == true)
  654.     {
  655.       RingBuffer_Reset(can2RxBuffer);
  656.     }
  657.   }
  658. #endif /* STM32F10X_CL */
  659. }

  660. /**
  661.   * @brief  Is the CAN transmit a message?
  662.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
  663.   * @retval true:      Is transmit a message.
  664.   * @retval false:     Not transmit a message.
  665.   */
  666. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx)
  667. {
  668.   if(CANx == CAN1)
  669.   {
  670.     if(can1InitFlag == true)
  671.     {
  672.       return can1TransmitFlag;
  673.     }
  674.   }

  675. #ifdef STM32F10X_CL
  676.   if(CANx == CAN2)
  677.   {
  678.     if(can2InitFlag == true)
  679.     {
  680.       return can2TransmitFlag;
  681.     }
  682.   }
  683. #endif /* STM32F10X_CL */

  684.   return false;
  685. }

  686. /**
  687.   * @brief  This function handles CAN1 TX Handler.
  688.   * @param  None.
  689.   * @return None.
  690.   */
  691. #ifdef STM32F10X_CL
  692. void CAN1_TX_IRQHandler(void)
  693. #else
  694. void USB_HP_CAN1_TX_IRQHandler(void)
  695. #endif /* STM32F10X_CL */
  696. {
  697.   if(CAN_GetITStatus(CAN1, CAN_IT_TME) != RESET)
  698.   {
  699.     CAN_ClearITPendingBit(CAN1, CAN_IT_TME);

  700.     CanTxMsg canTxMsg = {0};
  701.     uint8_t  number   = RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);

  702.     if(number > 0)
  703.     {
  704.       CAN_Transmit(CAN1, &canTxMsg);
  705.     }
  706.     else
  707.     {
  708.       can1TransmitFlag = false;

  709.       if(can1TransmitFinishCallback != 0)
  710.       {
  711.         can1TransmitFinishCallback();
  712.       }
  713.     }
  714.   }
  715. }

  716. /**
  717.   * @brief  This function handles CAN1 RX0 Handler.
  718.   * @param  None.
  719.   * @return None.
  720.   */
  721. #ifdef STM32F10X_CL
  722. void CAN1_RX0_IRQHandler(void)
  723. #else
  724. void USB_LP_CAN1_RX0_IRQHandler(void)
  725. #endif /* STM32F10X_CL */
  726. {
  727.   if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)
  728.   {
  729.     CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);

  730.     CanRxMsg canRxMsg = {0};
  731.     CAN_Receive(CAN1, CAN_FIFO0, &canRxMsg);

  732.     if(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg) > 0)
  733.     {
  734.       RingBuffer_In(can1RxBuffer, &canRxMsg, sizeof(canRxMsg));
  735.     }

  736.     if(can1ReceiveFinishCallback != 0)
  737.     {
  738.       can1ReceiveFinishCallback();
  739.     }
  740.   }
  741. }

  742. #ifdef STM32F10X_CL
  743. /**
  744.   * @brief  This function handles CAN2 TX Handler.
  745.   * @param  None.
  746.   * @return None.
  747.   */
  748. void CAN2_TX_IRQHandler(void)
  749. {
  750.   if(CAN_GetITStatus(CAN2, CAN_IT_TME) != RESET)
  751.   {
  752.     CAN_ClearITPendingBit(CAN2, CAN_IT_TME);

  753.     CanTxMsg canTxMsg = {0};
  754.     uint8_t  number   = RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);

  755.     if(number > 0)
  756.     {
  757.       CAN_Transmit(CAN2, &canTxMsg);
  758.     }
  759.     else
  760.     {
  761.       can2TransmitFlag = false;

  762.       if(can2TransmitFinishCallback != 0)
  763.       {
  764.         can2TransmitFinishCallback();
  765.       }
  766.     }
  767.   }
  768. }

  769. /**
  770.   * @brief  This function handles CAN2 RX0 Handler.
  771.   * @param  None.
  772.   * @return None.
  773.   */
  774. void CAN2_RX0_IRQHandler(void)
  775. {
  776.   if(CAN_GetITStatus(CAN2, CAN_IT_FMP0) != RESET)
  777.   {
  778.     CAN_ClearITPendingBit(CAN2, CAN_IT_FMP0);

  779.     CanRxMsg canRxMsg = {0};
  780.     CAN_Receive(CAN2, CAN_FIFO0, &canRxMsg);

  781.     if(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg) > 0)
  782.     {
  783.       RingBuffer_In(can2RxBuffer, &canRxMsg, sizeof(canRxMsg));
  784.     }

  785.     if(can2ReceiveFinishCallback != 0)
  786.     {
  787.       can2ReceiveFinishCallback();
  788.     }
  789.   }
  790. }
  791. #endif /* STM32F10X_CL */
复制代码


main.h 文件
  1. /**
  2.   ******************************************************************************
  3.   * @file    main.h
  4.   * @author  XinLi
  5.   * @version v1.0
  6.   * @date    24-June-2018
  7.   * @brief   Header file for main.c module.
  8.   ******************************************************************************
  9.   * @attention
  10.   *
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
  12.   *
  13.   * This program is free software: you can redistribute it and/or modify
  14.   * it under the terms of the GNU General Public License as published by
  15.   * the Free Software Foundation, either version 3 of the License, or
  16.   * (at your option) any later version.
  17.   *
  18.   * This program is distributed in the hope that it will be useful,
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.   * GNU General Public License for more details.
  22.   *
  23.   * You should have received a copy of the GNU General Public License
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
  25.   *
  26.   ******************************************************************************
  27.   */

  28. #ifndef __MAIN_H
  29. #define __MAIN_H

  30. #ifdef __cplusplus
  31. extern "C" {
  32. #endif

  33. /* Header includes -----------------------------------------------------------*/
  34. #include "stm32f10x.h"

  35. /* Macro definitions ---------------------------------------------------------*/
  36. /* Type definitions ----------------------------------------------------------*/
  37. /* Variable declarations -----------------------------------------------------*/
  38. /* Variable definitions ------------------------------------------------------*/
  39. /* Function declarations -----------------------------------------------------*/
  40. /* Function definitions ------------------------------------------------------*/

  41. #ifdef __cplusplus
  42. }
  43. #endif

  44. #endif /* __MAIN_H */
复制代码


main.c 文件
  1. /**
  2.   ******************************************************************************
  3.   * @file    main.c
  4.   * @author  XinLi
  5.   * @version v1.0
  6.   * @date    24-June-2018
  7.   * @brief   Main program body.
  8.   ******************************************************************************
  9.   * @attention
  10.   *
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
  12.   *
  13.   * This program is free software: you can redistribute it and/or modify
  14.   * it under the terms of the GNU General Public License as published by
  15.   * the Free Software Foundation, either version 3 of the License, or
  16.   * (at your option) any later version.
  17.   *
  18.   * This program is distributed in the hope that it will be useful,
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.   * GNU General Public License for more details.
  22.   *
  23.   * You should have received a copy of the GNU General Public License
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
  25.   *
  26.   ******************************************************************************
  27.   */

  28. /* Header includes -----------------------------------------------------------*/
  29. #include "main.h"
  30. #include "CAN.h"

  31. #ifdef _RTE_
  32. #include "RTE_Components.h"
  33. #endif

  34. #ifdef RTE_CMSIS_RTOS2
  35. #include "cmsis_os2.h"
  36. #endif

  37. /* Macro definitions ---------------------------------------------------------*/
  38. /* Type definitions ----------------------------------------------------------*/
  39. /* Variable declarations -----------------------------------------------------*/
  40. /* Variable definitions ------------------------------------------------------*/
  41. static CanTxMsg canTxMsg = {0};
  42. static CanRxMsg canRxMsg = {0};

  43. /* Function declarations -----------------------------------------------------*/
  44. static void SystemClock_Config(void);

  45. /* Function definitions ------------------------------------------------------*/

  46. /**
  47.   * @brief  Main program.
  48.   * @param  None.
  49.   * @return None.
  50.   */
  51. int main(void)
  52. {
  53.   /* Configure the system clock to 72 MHz */
  54.   SystemClock_Config();
  55.   SystemCoreClockUpdate();

  56.   /* Add your application code here */
  57.   CAN_Configure(CAN1, CAN_WorkModeLoopBack, CAN_BaudRate250K, 0xAA55, 0x55AA);

  58. #ifdef RTE_CMSIS_RTOS2
  59.   /* Initialize CMSIS-RTOS2 */
  60.   osKernelInitialize();

  61.   /* Create thread functions that start executing,
  62.   Example: osThreadNew(app_main, NULL, NULL); */

  63.   /* Start thread execution */
  64.   osKernelStart();
  65. #endif

  66.   /* Infinite loop */
  67.   while(1)
  68.   {
  69.     canTxMsg.StdId = 0xAA55;
  70.     canTxMsg.ExtId = 0x55AA;
  71.     canTxMsg.IDE   = CAN_ID_STD;
  72.     canTxMsg.RTR   = CAN_RTR_DATA;
  73.     canTxMsg.DLC   = 8;

  74.     canTxMsg.Data[0]++;
  75.     canTxMsg.Data[1]++;
  76.     canTxMsg.Data[2]++;
  77.     canTxMsg.Data[3]++;
  78.     canTxMsg.Data[4]++;
  79.     canTxMsg.Data[5]++;
  80.     canTxMsg.Data[6]++;
  81.     canTxMsg.Data[7]++;

  82.     CAN_SetTransmitMessage(CAN1, &canTxMsg, 1);

  83.     while(CAN_IsReceiveBufferEmpty(CAN1) == true);

  84.     CAN_GetReceiveMessage(CAN1, &canRxMsg, 1);
  85.   }
  86. }

  87. /**
  88.   * @brief  System Clock Configuration.
  89.   *         The system Clock is configured as follow :
  90.   *            System Clock source            = PLL (HSE)
  91.   *            SYSCLK(Hz)                     = 72000000
  92.   *            HCLK(Hz)                       = 72000000
  93.   *            AHB Prescaler                  = 1
  94.   *            APB1 Prescaler                 = 2
  95.   *            APB2 Prescaler                 = 1
  96.   *            HSE Frequency(Hz)              = 8000000
  97.   *            HSE PREDIV1                    = 1
  98.   *            PLLMUL                         = 9
  99.   *            Flash Latency(WS)              = 2
  100.   * @param  None.
  101.   * @return None.
  102.   */
  103. static void SystemClock_Config(void)
  104. {
  105.   /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration */
  106.   /* RCC system reset */
  107.   RCC_DeInit();

  108.   /* Enable HSE */
  109.   RCC_HSEConfig(RCC_HSE_ON);

  110.   /* Wait till HSE is ready */
  111.   ErrorStatus HSEStartUpStatus = RCC_WaitForHSEStartUp();

  112.   if(HSEStartUpStatus == SUCCESS)
  113.   {
  114.     /* Enable Prefetch Buffer */
  115.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

  116.     /* Flash 2 wait state */
  117.     FLASH_SetLatency(FLASH_Latency_2);

  118.     /* HCLK = SYSCLK */
  119.     RCC_HCLKConfig(RCC_SYSCLK_Div1);

  120.     /* PCLK2 = HCLK */
  121.     RCC_PCLK2Config(RCC_HCLK_Div1);

  122.     /* PCLK1 = HCLK / 2 */
  123.     RCC_PCLK1Config(RCC_HCLK_Div2);

  124.     /* Configure PLLs */
  125. #ifdef STM32F10X_CL
  126.     /* PLL2 configuration: PLL2CLK = (HSE(8MHz) / 2) * 10 = 40MHz */
  127.     RCC_PREDIV2Config(RCC_PREDIV2_Div2);
  128.     RCC_PLL2Config(RCC_PLL2Mul_10);

  129.     /* Enable PLL2 */
  130.     RCC_PLL2Cmd(ENABLE);

  131.     /* Wait till PLL2 is ready */
  132.     while(RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET);

  133.     /* PLL configuration: PLLCLK = (PLL2(40MHz) / 5) * 9 = 72MHz */
  134.     RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);
  135.     RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);
  136. #else
  137.     /* PLLCLK = HSE(8MHz) * 9 = 72MHz */
  138.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
  139. #endif

  140.     /* Enable PLL */
  141.     RCC_PLLCmd(ENABLE);

  142.     /* Wait till PLL is ready */
  143.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

  144.     /* Select PLL as system clock source */
  145.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

  146.     /* Wait till PLL is used as system clock source */
  147.     while(RCC_GetSYSCLKSource() != 0x08);
  148.   }
  149.   else
  150.   {
  151.     /* Disable HSE */
  152.     RCC_HSEConfig(RCC_HSE_OFF);

  153.     /* Enable HSI */
  154.     RCC_HSICmd(ENABLE);

  155.     /* Enable Prefetch Buffer */
  156.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

  157.     /* Flash 1 wait state */
  158.     FLASH_SetLatency(FLASH_Latency_1);

  159.     /* HCLK = SYSCLK */
  160.     RCC_HCLKConfig(RCC_SYSCLK_Div1);

  161.     /* PCLK2 = HCLK */
  162.     RCC_PCLK2Config(RCC_HCLK_Div1);

  163.     /* PCLK1 = HCLK */
  164.     RCC_PCLK1Config(RCC_HCLK_Div1);

  165.     /* Configure PLLs */
  166.     /* PLLCLK = HSI(8MHz) / 2 * 9 = 36MHz */
  167.     RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9);

  168.     /* Enable PLL */
  169.     RCC_PLLCmd(ENABLE);

  170.     /* Wait till PLL is ready */
  171.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

  172.     /* Select PLL as system clock source */
  173.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

  174.     /* Wait till PLL is used as system clock source */
  175.     while(RCC_GetSYSCLKSource() != 0x08);
  176.   }
  177. }

  178. #ifdef USE_FULL_ASSERT
  179. /**
  180.   * @brief  Reports the name of the source file and the source line number
  181.   *         where the assert_param error has occurred.
  182.   * @param  file: pointer to the source file name.
  183.   * @param  line: assert_param error line source number.
  184.   * @return None.
  185.   */
  186. void assert_failed(uint8_t *file, uint32_t line)
  187. {
  188.   /* User can add his own implementation to report the file name and line number,
  189.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  190.   /* Infinite loop */
  191.   while(1)
  192.   {
  193.   }
  194. }
  195. #endif
复制代码

3,注意

CAN 消息发送缓冲区和接收缓冲区的大小,可以根据应用的需求进行修改,缓冲区使用的是堆内存,需要根据缓冲区大小和应用程序中堆内存使用情况进行配置。



收藏 评论0 发布时间:2021-11-26 17:00

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版