打印
[应用相关]

Clion开发STM32之串口封装(HAL库)

[复制链接]
1786|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
前提
在开发STM32过程中,芯片提供的串口引脚一般是不会发生变化的,所以为了方便移植,借助HAL提供的注册回调函数自定义,这边重新进行简要的封装
此工程开发是以Clion为开发的IDE,用keil只需将对应的文件进行移植即可.
文章末尾附带gitee工程地址
工程创建(以STM32F103C8T6为例)
1.参考Stm32开发环境从0搭建(Clion作为开发软件)
2.开启自定义注册串口硬件注册回调(方便后面工程移植,也可以使用HAL默认的硬件回调)



3. 打开工程并测试

添加自定义的项目路径(方便后期移植)
1.创建目录框架


2. 编写CMakeLists文件t和CMakeLists模板文件(此步骤是将自定义目录框架包含到项目中)



3. 创建同一的头文件去管理


统一串口宏定义
头文件 (bsp_serial_define.h)

#ifndef STM32_VET6_BSP_SERIAL_DEFINE_H
#define STM32_VET6_BSP_SERIAL_DEFINE_H

#include "sys_driver_include.h"
// 串口只支持异步
/***********************************************************串口1相关宏定义*******************************************************/
#define USE_COM1_ENABLE (1)
#define USE_COM1_IRQ_ENABLE (0) // 串口1中断使能
#define USE_COM1_DMA_RX_ENABLE (0) // 串口1 DMA RX 使能
#define COM1_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define COM1_TX_PORT GPIOA
#define COM1_TX_PIN GPIO_PIN_9
#define COM1_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define COM1_RX_PORT GPIOA
#define COM1_RX_PIN GPIO_PIN_10
#define COM1_IRQ_Priority 5 // 抢占优先级
#define COM1_IRQ_SubPriority 0 // 响应优先级
#define COM1_DMA_RX_CHANNEL DMA1_Channel5
#define COM1_DMA_CLK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE()
#define COM1_DMA_IRQ DMA1_Channel5_IRQn
#define COM1_IRQ_HANDLE DMA1_Channel5_IRQHandler
extern UART_HandleTypeDef com1_handle;
/***********************************************************串口2相关宏定义*******************************************************/
#define USE_COM2_ENABLE (0)
#define USE_COM2_IRQ_ENABLE (0) // 串口2中断使能
#define USE_COM2_DMA_RX_ENABLE (0) // 串口1 DMA RX 使能

/**@Details 引脚定义*/
#define COM2_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define COM2_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define COM2_TX_PIN GPIO_PIN_2
#define COM2_RX_PIN GPIO_PIN_3
#define COM2_TX_PORT GPIOA
#define COM2_RX_PORT GPIOA

#define COM2_IRQ_Priority 5 // 抢占优先级
#define COM2_IRQ_SubPriority 0 // 响应优先级
#define COM2_DMA_RX_CHANNEL DMA1_Channel6
#define COM2_DMA_CLK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE()
#define COM2_DMA_IRQ DMA1_Channel6_IRQn
#define COM2_IRQ_HANDLE DMA1_Channel6_IRQHandler
extern UART_HandleTypeDef com2_handle;
/***********************************************************串口3相关宏定义*******************************************************/
#define USE_COM3_ENABLE (0)
#define USE_COM3_IRQ_ENABLE (1) // 串口3中断使能
#define USE_COM3_DMA_RX_ENABLE (1) // 串口3 DMA RX 使能
#define COM3_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
#define COM3_TX_PORT GPIOD
#define COM3_TX_PIN GPIO_PIN_8
#define COM3_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
#define COM3_RX_PORT GPIOD
#define COM3_RX_PIN GPIO_PIN_9
#define COM3_IRQ_Priority 5 // 抢占优先级
#define COM3_IRQ_SubPriority 0 // 响应优先级
#define COM3_DMA_CLK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE()
#define COM3_DMA_RX_CHANNEL DMA1_Channel3
#define COM3_DMA_IRQ DMA1_Channel3_IRQn
#define COM3_IRQ_HANDLE DMA1_Channel3_IRQHandler
extern UART_HandleTypeDef com3_handle;
/***********************************************************串口4相关宏定义*******************************************************/
#define USE_COM4_ENABLE (0)
#define USE_COM4_IRQ_ENABLE (1) // 串口4中断使能
#define USE_COM4_DMA_RX_ENABLE (1) // 串口4 DMA RX 使能
#define COM4_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
#define COM4_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
#define COM4_TX_PORT GPIOC
#define COM4_RX_PORT GPIOC
#define COM4_TX_PIN GPIO_PIN_10
#define COM4_RX_PIN GPIO_PIN_11
#define COM4_IRQ_Priority 5 // 抢占优先级
#define COM4_IRQ_SubPriority 0 // 响应优先级
#define COM4_DMA_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
#define COM4_DMA_RX_CHANNEL DMA2_Channel3
#define COM4_DMA_IRQ DMA2_Channel3_IRQn
#define COM4_DMA_IRQ_HANDLE DMA2_Channel3_IRQHandler
extern UART_HandleTypeDef com4_handle;
#endif //STM32_VET6_BSP_SERIAL_DEFINE_H



串口核心文件
头文件(bsp_serial.h)

#ifndef STM32_VET6_BSP_SERIAL_H
#define STM32_VET6_BSP_SERIAL_H

#include "bsp_serial_define.h"
#include "bsp_serial_com1.h"


void Com_Init_01(USART_TypeDef *uart, uint32_t baud);

void Com_Init(UART_HandleTypeDef *comHandle, UART_InitTypeDef *config);

void Com_RegisterCallback(UART_HandleTypeDef *comHandle);

void Com_Dma_Init(DMA_HandleTypeDef *dmaHandle, DMA_InitTypeDef *config);

void UART_MspInit(UART_HandleTypeDef *comHandle);

void UART_MspDeInit(UART_HandleTypeDef *comHandle);

void UART_RxEventCallback(UART_HandleTypeDef *com_handle, uint16_t Pos);

#endif //STM32_VET6_BSP_SERIAL_H



源文件(bsp_serial.c)

#include "bsp_serial.h"

static UART_InitTypeDef init_cnf = {
        .OverSampling = UART_OVERSAMPLING_16,
        .Mode = UART_MODE_TX_RX,
        .HwFlowCtl = UART_HWCONTROL_NONE,
        .Parity = UART_PARITY_NONE,
        .StopBits = UART_STOPBITS_1,
        .WordLength = UART_WORDLENGTH_8B,
        .BaudRate = 9600
};
static DMA_InitTypeDef default_dma_config = {
        .Direction = DMA_PERIPH_TO_MEMORY,
        .PeriphInc = DMA_PINC_DISABLE,
        .MemInc = DMA_MINC_ENABLE,
        .PeriphDataAlignment = DMA_PDATAALIGN_BYTE,
        .MemDataAlignment =DMA_MDATAALIGN_BYTE,
        .Mode = DMA_NORMAL,
        .Priority = DMA_PRIORITY_LOW
};

/**
* 通用串口初始化
* @param uart  串口
* @param baud
*/
void Com_Init_01(USART_TypeDef *uart, uint32_t baud) {
    init_cnf.BaudRate = baud;
    if (uart == NULL) {

    }
#if USE_COM1_ENABLE
    else if (uart == USART1) {
        Com_Init(&com1_handle, &init_cnf);
    }
#endif
#if USE_COM2_ENABLE
    else if (uart == USART2) {
        Sw_Com_Init(&com2_handle, &init_cnf);

    }
#endif
#if USE_COM3_ENABLE
    else if (uart == USART3) {
            Sw_Com_Init(&com3_handle, &init_cnf);
        }
#endif
#if USE_COM4_ENABLE
    else if (uart == UART4) {
        Sw_Com_Init(&com4_handle, &init_cnf);
    }
#endif
}

/**
* @brief 通用串口初始化
* @param comHandle
* @param config
*/
void Com_Init(UART_HandleTypeDef *comHandle, UART_InitTypeDef *config) {
#if USE_HAL_UART_REGISTER_CALLBACKS
    comHandle->MspDeInitCallback = UART_MspDeInit;
    comHandle->MspInitCallback = UART_MspInit;
#endif
    UART_InitTypeDef *ptr = NULL;
    if (config != NULL) {
        ptr = config;
    } else {
        ptr = &init_cnf;
    }
    memcpy(&comHandle->Init, ptr, sizeof(UART_InitTypeDef));
    if (HAL_UART_Init(comHandle) != HAL_OK) {
        common_error_handle(__FILE__, __LINE__);
    }
}

/**
* @brief 注册接收事件回调
* @param comHandle
*/
void Com_RegisterCallback(UART_HandleTypeDef *comHandle) {
#if USE_HAL_UART_REGISTER_CALLBACKS
    HAL_UART_RegisterRxEventCallback(comHandle, UART_RxEventCallback);
#endif
}

void UART_MspInit(UART_HandleTypeDef *comHandle) {
#if USE_COM1_ENABLE
    if (comHandle->Instance == USART1) {
        Com1_MspInit();
    }
#endif
#if USE_COM2_ENABLE
    if (comHandle->Instance == USART2) {
        Com2_MspInit();
    }
#endif
#if USE_COM3_ENABLE
    if (comHandle->Instance == USART3) {
        Com3_MspInit();
    }
#endif
#if USE_COM4_ENABLE
    if (comHandle->Instance == UART4) {
        Com4_MspInit();
    }
#endif
}

void UART_MspDeInit(UART_HandleTypeDef *comHandle) {
#if USE_COM1_ENABLE
    if (comHandle->Instance == USART1) {
        Com1_MspDeInit();
    }
#endif
#if USE_COM2_ENABLE
    if (comHandle->Instance == USART2) {
        Com2_MspDeInit();
    }
#endif
#if USE_COM3_ENABLE
    if (comHandle->Instance == USART3) {
        Com3_MspDeInit();
    }
#endif
#if USE_COM4_ENABLE
    if (comHandle->Instance == UART4) {
        Com4_MspDeInit();
    }
#endif
}

/**
* @brief 串口接收事件
* @param com_handle
* @param Pos
*/
void UART_RxEventCallback(UART_HandleTypeDef *com_handle, uint16_t Pos) {
    if (com_handle == NULL) {
        common_error_handle(__FILE__, __LINE__);
    }
#if (USE_COM1_ENABLE == 1)
    else if (com_handle->Instance == USART1) {
        Com1_RxEvent(Pos);
    }
#endif
#if (USE_COM2_ENABLE == 1)
    else if (comHandle->Instance == USART2) {
        Com2_RxEvent(Pos);
    }
#endif
#if (USE_COM3_ENABLE == 1)
    else if (comHandle->Instance == USART3) {
        Com3_RxEvent(Pos);
    }
#endif
#if (USE_COM4_ENABLE == 1)
    else if (comHandle->Instance == UART4) {
        Com4_RxEvent(Pos);
    }
#endif
}

/**
* 错误回调
* @param comHandle 串口句柄
*/
void HAL_UART_ErrorCallback(UART_HandleTypeDef *comHandle) {
    switch (comHandle->ErrorCode) {
        case HAL_UART_ERROR_PE:
            __HAL_UART_CLEAR_FLAG(comHandle, UART_FLAG_PE);
            break;
        case HAL_UART_ERROR_NE:
            __HAL_UART_CLEAR_FLAG(comHandle, UART_FLAG_NE);
            break;
        case HAL_UART_ERROR_FE:
            __HAL_UART_CLEAR_FLAG(comHandle, UART_FLAG_FE);
            break;
        case HAL_UART_ERROR_ORE:
            __HAL_UART_CLEAR_FLAG(comHandle, UART_FLAG_ORE);
            break;
    }
    if (comHandle == NULL) {
        common_error_handle(__FILE__, __LINE__);
    }
#if (USE_COM1_ENABLE == 1)
    else if (comHandle->Instance == USART1) {
        Com1_ErrEvent();
    }
#endif
#if (USE_COM2_ENABLE == 1)
    else if (comHandle->Instance == USART2) {
        Com2_ErrEvent();
    }
#endif
#if (USE_COM3_ENABLE == 1)
    else if (comHandle->Instance == USART3) {
        Com3_ErrEvent();
    }
#endif
#if (USE_COM4_ENABLE == 1)
    else if (comHandle->Instance == UART4) {
        Com4_ErrEvent();
    }
#endif
}


/**
* @brief 统一DMA接口初始化
* @param dmaHandle
* @param config
*/
void Com_Dma_Init(DMA_HandleTypeDef *dmaHandle, DMA_InitTypeDef *config) {
    DMA_InitTypeDef *ptr;

    if (config != NULL) {
        ptr = config;
    } else {
        ptr = &default_dma_config;
    }
    memcpy(&dmaHandle->Init, ptr, sizeof(DMA_InitTypeDef));
}


串口1
头文件(bsp_serial_com1.h)

#ifndef STM32_VET6_BSP_SERIAL_COM1_H
#define STM32_VET6_BSP_SERIAL_COM1_H

#include "bsp_serial_define.h"

#if USE_COM1_ENABLE

void Com1_DMA_Init(uint32_t PreemptPriority, uint32_t SubPriority, DMA_InitTypeDef *config);

void Com1_Init(UART_InitTypeDef *config);

void Com1_MspInit(void);

void Com1_MspDeInit(void);

void Com1_DMA_Rx_MspInit(void);

void Com1_DMA_Rx_MspDeInit(void);

void Com1_RxEvent(uint16_t pos);

void Com1_ErrEvent(void);

#endif

#endif //STM32_VET6_BSP_SERIAL_COM1_H



基础源文件(bsp_serial_com1.c)

#include "bsp_serial.h"

UART_HandleTypeDef com1_handle = {.Instance=USART1};


/**
* @brief Com1初始化
* @param config
*/
void Com1_Init(UART_InitTypeDef *config) {
    Com_Init(&com1_handle, config);
    // 使用自定义的中断回调
    Com_RegisterCallback(&com1_handle);
}

void Com1_MspInit(void) {
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    /* USART1 clock enable */
    __HAL_RCC_USART1_CLK_ENABLE();
    COM1_TX_GPIO_CLK_ENABLE();
    COM1_RX_GPIO_CLK_ENABLE();
    /**USART1 GPIO Configuration
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX
    */
    GPIO_InitStruct.Pin = COM1_TX_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(COM1_TX_PORT, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = COM1_RX_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(COM1_RX_PORT, &GPIO_InitStruct);
#if USE_COM1_DMA_RX_ENABLE
    Com1_DMA_Rx_MspInit();
#endif
}

void Com1_MspDeInit(void) {
    /* Peripheral clock disable */
    __HAL_RCC_USART1_CLK_DISABLE();
    HAL_GPIO_DeInit(COM1_TX_PORT, COM1_TX_PIN);
    HAL_GPIO_DeInit(COM1_RX_PORT, COM1_RX_PIN);
#if USE_COM1_DMA_RX_ENABLE
    Com1_DMA_Rx_MspDeInit();
#endif
}

void USART1_IRQHandler(void) {
    HAL_UART_IRQHandler(&com1_handle);
}


扩展串口接收dma(bsp_serial_dma_com1.c)

#include "bsp_serial.h"

DMA_HandleTypeDef com1_dma_rx_handle={
                .Instance=COM1_DMA_RX_CHANNEL,
};

void Com1_DMA_Init(uint32_t PreemptPriority, uint32_t SubPriority, DMA_InitTypeDef *config) {
/* DMA controller clock enable */
        COM1_DMA_CLK_ENABLE();
        /* DMA interrupt init */
        HAL_NVIC_SetPriority(COM1_DMA_IRQ, PreemptPriority, SubPriority);
        HAL_NVIC_EnableIRQ(COM1_DMA_IRQ);
        // com1初始化
    Com_Dma_Init(&com1_dma_rx_handle, config);
}

void Com1_DMA_Rx_MspInit(void) {
        if (HAL_DMA_Init(&com1_dma_rx_handle) != HAL_OK) {
        common_error_handle(__FILE__, __LINE__);
        }
        __HAL_LINKDMA(&com1_handle, hdmarx, com1_dma_rx_handle);
#if USE_COM1_IRQ_ENABLE
        HAL_NVIC_SetPriority(USART1_IRQn, COM1_IRQ_Priority, COM1_IRQ_SubPriority);
        HAL_NVIC_EnableIRQ(USART1_IRQn);
#endif
}

void Com1_DMA_Rx_MspDeInit(void) {
        /*  DMA DeInit */
        HAL_DMA_DeInit(&com1_dma_rx_handle);
        /*  interrupt Deinit */
        HAL_NVIC_DisableIRQ(COM1_DMA_IRQ);
}


void COM1_IRQ_HANDLE(void) {
        /* USER CODE BEGIN DMA1_Channel5_IRQn 0 */
        HAL_DMA_IRQHandler(&com1_dma_rx_handle);
}


/**
* @brief 参考 @ref HAL_UARTEx_RxEventCallback
* @param pos
*/
__weak void Com1_RxEvent(uint16_t pos) {
        UNUSED(pos);
}
/**
* @brief 错误事件
*/
__weak void Com1_ErrEvent(void) {

}




示例
开启串口中断和DMA接收中断



/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include <stdbool.h>
#include "main.h"
#include "dma.h"
#include "usart.h"
#include "gpio.h"
#include "bsp_serial.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
static uint8_t buffer[256];
// 接收数据标志位
static volatile bool rec_data_flag = false;
// 接收数据长度
static volatile uint16_t rec_len = 0;

/**
* @brief 错误事件
*/
void Com1_ErrEvent(void) {
    rec_len = 0;
    rec_data_flag = false;
    // 重新开启DMA接收
    HAL_UARTEx_ReceiveToIdle_DMA(&com1_handle, buffer, 256);
}

void Com1_RxEvent(uint16_t pos) {
    rec_len = pos;
    rec_data_flag = true;

}

static uint16_t com_rec(void *retBuf) {
    if (rec_data_flag) {
        rec_data_flag = false;
        memcpy(retBuf, buffer, rec_len);
        HAL_UARTEx_ReceiveToIdle_DMA(&com1_handle, buffer, 256);
        return rec_len;
    }
    return 0;
}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void) {
    /* USER CODE BEGIN 1 */

    /* USER CODE END 1 */

    /* MCU Configuration--------------------------------------------------------*/

    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    HAL_Init();

    /* USER CODE BEGIN Init */

    /* USER CODE END Init */

    /* Configure the system clock */
    SystemClock_Config();

    /* USER CODE BEGIN SysInit */
#if 0
    /* USER CODE END SysInit */

    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    MX_DMA_Init();
    MX_USART1_UART_Init();
    /* USER CODE BEGIN 2 */
#endif

    Com1_DMA_Init(5, 0, NULL);
    Com_Init_01(USART1, 9600);
    // 开启串口屏接收数据
    HAL_UARTEx_ReceiveToIdle_DMA(&com1_handle, buffer, 256);
    /* USER CODE END 2 */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    uint8_t read_buf[256];
    while (1) {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
        uint16_t data_len = com_rec(read_buf);
        if (data_len > 0) {
            // todo 解析数据 read_buf
        }
    }
    /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void) {
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    /** Initializes the RCC Oscillators according to the specified parameters
    * in the RCC_OscInitTypeDef structure.
    */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
        Error_Handler();
    }

    /** Initializes the CPU, AHB and APB buses clocks
    */
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
                                  | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
        Error_Handler();
    }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void) {
    /* USER CODE BEGIN Error_Handler_Debug */
    /* User can add his own implementation to report the HAL error return state */
    __disable_irq();
    while (1) {
    }
    /* USER CODE END Error_Handler_Debug */
}

#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
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* 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) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */





项目gitee
https://gitee.com/scl_arm/serial_proj.git
————————————————
版权声明:本文为CSDN博主「詩不诉卿」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44742767/article/details/130444774

使用特权

评论回复
沙发
51xlf| | 2023-6-8 07:21 | 只看该作者
在CLion中编写STM32的C代码,并使用CMSIS库函数和HAL库函数等来控制芯片的外设。可以使用CLion的代码补全、语法高亮等功能来辅助编码。

使用特权

评论回复
板凳
mattlincoln| | 2023-6-8 15:20 | 只看该作者
clion是什么               

使用特权

评论回复
地板
Pretext| | 2023-6-8 15:23 | 只看该作者
CLion调试的话好像就不如Keil了。

使用特权

评论回复
5
朝生| | 2023-6-8 15:24 | 只看该作者
用CLion写代码还是很舒服的。

使用特权

评论回复
6
软核硬核| | 2023-6-8 15:24 | 只看该作者
是Keil不好用吗?为啥要换使用环境呢。

使用特权

评论回复
7
qiufengsd| | 2023-6-8 16:27 | 只看该作者
如何安装配置clion开发环境              

使用特权

评论回复
8
pixhw| | 2023-6-8 22:31 | 只看该作者
在使用CLion开发STM32时,需要对CMake、CMSIS库和HAL库等进行深入了解

使用特权

评论回复
9
wilhelmina2| | 2023-6-13 21:00 | 只看该作者
将STM32单片机连接到电脑,并通过OpenOCD进行调试。

使用特权

评论回复
10
febgxu| | 2023-6-13 22:05 | 只看该作者
CLion 怎么链接库?              

使用特权

评论回复
11
Stahan| | 2023-6-13 22:55 | 只看该作者
CLion调试不太好用

使用特权

评论回复
12
ingramward| | 2023-6-14 10:05 | 只看该作者
CLion 和 VS 哪个是更智能

使用特权

评论回复
13
yeates333| | 2023-6-14 16:55 | 只看该作者
在开发STM32时,需要安装GNU ARM工具链和OpenOCD等工具来进行编译、调试和下载程序。可以从官方网站上下载对应版本的工具链和OpenOCD,并将其配置到系统环境变量中。

使用特权

评论回复
14
uiint| | 2023-6-21 13:47 | 只看该作者
CLion是JetBrains公司开发的一款基于CMake构建的跨平台集成开发环境(IDE),支持多种编程语言,包括C/C++。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

74

主题

3882

帖子

4

粉丝