0%

报错

在Vscode中编辑EIDE项目clangd有时不能找到头文件, 如下图

问题

解决

在.vscode/settings.json中写入

1
2
3
4
5
6
7
{
"clangd.fallbackflags": [
"-I${workspacefolder}/libraries/stm32f10x_stdperiph_driver/inc",
"-I${workspacefolder}/libraries/cmsis",
"-I${workspacefolder}/user"
]
}

有时好用, 有时不好用, 玄学

参考链接

EIDE配置视频

安装实用工具

安装实用工具

Cppcheck

OpenOCD Programmer

GUN Arm Embedded Toolchain

配置EIDE

在设置中勾选

elf

EIDE插件选择拓展设置

拓展设置

输入MDK的安装路径

MDK路径

EIDE选项设置

基于STM32F1芯片, 标准库开发

项目资源

项目资源

芯片支持包

芯片支持包

构建配置

构建配置

烧录配置

烧录配置

项目属性

项目属性

项目设置

项目设置

代码规范

注意一下提到的代码规范符合Doxygen要求

参考链接CSDN关于Doxygen语法

变量批注

1
2
int a = 1; //!< 测试变量a的单行批注
int b = 1; /*!< 测试变量b的块批注 */

在每个文件的头部添加如下注释

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
******************************************************************************
* @file 文件名
* @author 作者名
* @version 版本号V0.0.1
* @date 日期31-January-2024
* @brief 文件作用简介
******************************************************************************
* @attention
*
* THE PRESENT FUCTIONS WHICH IS FOR GUIDANCE ONLY
******************************************************************************
*/

在函数前添加如下注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* @brief 函数简介
* @param 形参1: 形参1说明
* @param 形参2: 形参2说明
* @retval 返回值说明
*/

/// 例如

/**
* @brief Initializes the GPIOx peripheral according to the specified
* parameters in the GPIO_InitStruct.
* @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
* @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that
* contains the configuration information for the specified GPIO peripheral.
* @retval None
*/
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
{

}

在结构体或枚举变量前添加如下注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
* @brief 结构体或枚举说明
*/

typedef struct
{
int a; //!< 成员单行注释
int b; /*!< 成员
换行注释块 */
}A;

// 例如

/**
* @brief GPIO Init structure definition
*/

typedef struct
{
uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
This parameter can be any value of @ref GPIO_pins_define */

GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
This parameter can be a value of @ref GPIOSpeed_TypeDef */

GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins.
This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;

/**
* @brief Bit_SET and Bit_RESET enumeration
*/

typedef enum
{ Bit_RESET = 0,
Bit_SET
}BitAction;

Doxygen GUI frontend 软件使用

1

点击File->Save; 保存一个模板文件

2

  1. 输入项目名称(Project Name)
  2. 选择源码文件夹位置(Source code directory)
  3. 勾选递归扫描(Scan recursively)
  4. 选择生成的目标文件夹位置(Destination directory)

3

在output中取消勾选Latex选项(如果只需要html格式文档的话)

4

点击 Run doxygen 后可点击 Show HTML output 来查看

需求说明

为了确保列数在80个字符以内,我们需要在编辑器中显示列标尺。

操作方法

在Vscode设置中输入editor.rulers, 然后点击"在settings.json中编辑",找到"editor.rulers",
输入80即可。

Vscode设置

Vscode设置

1
2
3
"editor.rulers": [
80
]

问题说明

在嵌入式开发中需要经常用到库函数(SPL), Vscode需要配置引用路径才能对函数名或变量进行跳转

解决思路1

与Keil5 MDK类似, 在配置C/C++的json文件中添加所使用的头文件路径

在Vscode中进行配置

在vscode中按Ctrl+Shift+P 输入configuration, 如图选择C/C++编程配置(json)

Vscode配置

在"includePath"后面增加所要使用的头文件的路径, 如下图所示

Vscode配置

缺点

配置起来较为繁琐, 且部分函数依然无法跳转

解决思路2

在思路1的基础上, 向编写的文件中包含"stm32f10x_conf.h文件"

1
#include "stm32f10x_conf.h"

在stm32f10x_conf文件中有对于所有外设头文件的包含

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/* Includes ------------------------------------------------------------------*/
/* Uncomment/Comment the line below to enable/disable peripheral header file inclusion */
#include "stm32f10x_adc.h"
#include "stm32f10x_bkp.h"
#include "stm32f10x_can.h"
#include "stm32f10x_cec.h"
#include "stm32f10x_crc.h"
#include "stm32f10x_dac.h"
#include "stm32f10x_dbgmcu.h"
#include "stm32f10x_dma.h"
#include "stm32f10x_exti.h"
#include "stm32f10x_flash.h"
#include "stm32f10x_fsmc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_i2c.h"
#include "stm32f10x_iwdg.h"
#include "stm32f10x_pwr.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_rtc.h"
#include "stm32f10x_sdio.h"
#include "stm32f10x_spi.h"
#include "stm32f10x_tim.h"
#include "stm32f10x_usart.h"
#include "stm32f10x_wwdg.h"
#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */

所以在思路1的基础上加上思路2可以较好的解决该问题

说明

仅供读者本人备忘使用, 不具备参考价值

面板操作

  • 收起/打开左侧边栏: Ctrl+B
  • 切换标签页: Ctrl+Tab
  • 选择标签页: Alt+NUMBER (NUMBER为当前为第几个标签页)
  • 显示下方集成终端面板: Ctrl+`
  • 聚焦到资源管理器: Ctrl+Shift+E
  • 最大化终端面板: Ctrl+J

编辑操作

  • 代码注释: Ctrl+/
  • 生成文档(基于Copilot): Ctrl+Shift+D
  • 智能修复(fix)报错(基于Copilot): Ctrl+Shift+F

问题演示

问题演示

在此状态下输入/会直接自动补全, 如下图

问题演示

笔者想要达到的效果为可以正常输入/而不进行补全, 如下图

问题演示

解决方法

在设置->文本编辑器->建议, 取消勾选Accept Suggestion On Commit Character, 如下图所示

解决方法

说明

注释规范化参考文件为STM32F103的库文件, 即ST公司写的库函数底层代码

文件头声明格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
******************************************************************************
* @file stm32f10x_dma.h
* @author MCD Application Team
* @version V3.5.0
* @date 11-March-2011
* @brief This file contains all the functions prototypes for the DMA firmware
* library.
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/

通常包含以下部分

  • @file: 文件名
  • @author: 作者名
  • @version: 版本号
  • @date: 日期
  • @brief 文档简介
  • @attention: 注意信息

函数注释格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* @brief Enables or disables the specified DMAy Channelx interrupts.
* @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and
* x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel.
* @param DMA_IT: specifies the DMA interrupts sources to be enabled
* or disabled.
* This parameter can be any combination of the following values:
* @arg DMA_IT_TC: Transfer complete interrupt mask
* @arg DMA_IT_HT: Half transfer interrupt mask
* @arg DMA_IT_TE: Transfer error interrupt mask
* @param NewState: new state of the specified DMA interrupts.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx));
assert_param(IS_DMA_CONFIG_IT(DMA_IT));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the selected DMA interrupts */
DMAy_Channelx->CCR |= DMA_IT;
}
else
{
/* Disable the selected DMA interrupts */
DMAy_Channelx->CCR &= ~DMA_IT;
}
}

通常包含以下部分:

  • @brief: 函数简介
  • @param: 参数说明
  • @arg: 可选的参数
  • @retval: 返回值说明

结构体格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/** 
* @brief DMA Init structure definition
*/

typedef struct
{
uint32_t DMA_PeripheralBaseAddr; /*!< Specifies the peripheral base address for DMAy Channelx. */

uint32_t DMA_MemoryBaseAddr; /*!< Specifies the memory base address for DMAy Channelx. */

uint32_t DMA_DIR; /*!< Specifies if the peripheral is the source or destination.
This parameter can be a value of @ref DMA_data_transfer_direction */

uint32_t DMA_BufferSize; /*!< Specifies the buffer size, in data unit, of the specified Channel.
The data unit is equal to the configuration set in DMA_PeripheralDataSize
or DMA_MemoryDataSize members depending in the transfer direction. */

uint32_t DMA_PeripheralInc; /*!< Specifies whether the Peripheral address register is incremented or not.
This parameter can be a value of @ref DMA_peripheral_incremented_mode */

uint32_t DMA_MemoryInc; /*!< Specifies whether the memory address register is incremented or not.
This parameter can be a value of @ref DMA_memory_incremented_mode */

uint32_t DMA_PeripheralDataSize; /*!< Specifies the Peripheral data width.
This parameter can be a value of @ref DMA_peripheral_data_size */

uint32_t DMA_MemoryDataSize; /*!< Specifies the Memory data width.
This parameter can be a value of @ref DMA_memory_data_size */

uint32_t DMA_Mode; /*!< Specifies the operation mode of the DMAy Channelx.
This parameter can be a value of @ref DMA_circular_normal_mode.
@note: The circular buffer mode cannot be used if the memory-to-memory
data transfer is configured on the selected Channel */

uint32_t DMA_Priority; /*!< Specifies the software priority for the DMAy Channelx.
This parameter can be a value of @ref DMA_priority_level */

uint32_t DMA_M2M; /*!< Specifies if the DMAy Channelx will be used in memory-to-memory transfer.
This parameter can be a value of @ref DMA_memory_to_memory */
}DMA_InitTypeDef;

通常包含以下部分

  • @brief: 结构体说明
  • @note 参数说明
  • @ref: 结构体成员取值选项

结构体成员取值的注释格式

以该结构体成员其后的注释为例, 可取值 @ref DMA_data_transfer_direction

1
2
uint32_t DMA_DIR;                /*!< Specifies if the peripheral is the source or destination.
This parameter can be a value of @ref DMA_data_transfer_direction */

则下文中需出现注释

1
2
3
4
5
6
7
8
9
10
11
/** @defgroup DMA_data_transfer_direction 
* @{
*/

#define DMA_DIR_PeripheralDST ((uint32_t)0x00000010)
#define DMA_DIR_PeripheralSRC ((uint32_t)0x00000000)
#define IS_DMA_DIR(DIR) (((DIR) == DMA_DIR_PeripheralDST) || \
((DIR) == DMA_DIR_PeripheralSRC))
/**
* @}
*/

通常包含以下部分

  • @defgroup : 为可取值组的名字需与@ref后的名字对应
  • @{ @}: 取值组前后需要用@大括号括起来, 中间为结构体成员可以取的变量
  • @ref : 写在结构体成员之后, 需要与后文@defgroup的名字对应

波特率和比特率介绍

波特率(Baud Rate)和比特率(Bit Rate)是数字通信中两个相关但不同的概念。它们经常被混淆,但它们表示的是不同的量。

1
2
3
4
5
6
7
8
1. 波特率(Baud Rate):
- 定义: 波特率是指每秒传输的波特(符号、信号)的数量。一个波特可以表示一个电平变化,一个符号,或者一个脉冲。
- 单位: 波特率的单位是波特(bps),表示每秒传输的符号或波特的数量。
- 示例: 如果波特率为9600 bps,表示每秒传输9600个符号。
2. 比特率(Bit Rate):
- 定义: 比特率是指每秒传输的比特(二进制位)的数量。每个符号可能携带多个比特,具体取决于使用的调制方式。
- 单位: 比特率的单位是比特每秒(bps),表示每秒传输的二进制位的数量。
- 示例: 如果比特率为9600 bps,表示每秒传输9600个二进制位。

区别总结

1
2
3
4
5
6
7
8
- 波特率:
- 衡量的是每秒传输的波特(符号)的数量。
- 波特率单位为波特每秒(bps)。
- 通常用于描述调制解调器、串口通信等模拟信号的传输速率。
- 比特率:
- 衡量的是每秒传输的比特(二进制位)的数量。
- 比特率单位为比特每秒(bps)。
- 通常用于描述数字信号、数字通信中的传输速率。

换算关系

波特率和比特率的换算关系取决于每个符号(波特)携带的比特数。在一些通信系统中,一个波特可能携带一个比特,但在其他情况下,一个波特可以携带多个比特。以下是一些常见情况的换算关系:

1
2
3
4
1. 每波特携带一个比特的情况:
- 波特率(Baud Rate)= 比特率(Bit Rate)
2. 每波特携带多个比特的情况:
- **波特率(Baud Rate)= 比特率(Bit Rate) / 每波特携带的比特数**