STM32(hal库)中,__HAL_LINKDMA 函数使用时候,串口的handler DMA_HandleTypedef 为什么前面要加extern

news/2024/11/20 8:26:59/

        在STM32 HAL库中,__HAL_LINKDMA是一个宏,用于将特定的外设(如UART、SPI等)的句柄(Handle)与其对应的DMA(直接内存访问)句柄链接起来。这样做的目的是让HAL库内部能够自动管理DMA传输,从而简化代码并减少出错的可能性。

        当你在使用__HAL_LINKDMA链接串口的handler (UART_HandleTypeDef) 和DMA的handler (DMA_HandleTypeDef) 时,如果看到示例代码中DMA_HandleTypeDef前面加了extern关键字,这通常意味着DMA_HandleTypeDef的定义是在另一个源文件中完成的,而不是在当前文件中。

使用extern的原因

  1. 跨文件引用extern关键字用于声明一个变量或对象是在其他地方定义的。当你需要在多个文件中访问同一个变量或对象时,你通常在一个文件中定义它(不提供extern),而在其他需要访问该变量的文件中声明它(使用extern)。

  2. 模块化设计:在嵌入式系统开发中,模块化设计是非常重要的。通过将不同的硬件外设的初始化和管理代码放在不同的源文件中,可以提高代码的可读性和可维护性。对于DMA和串口这样的外设,可能会在不同的源文件中使用它们,因此需要使用extern来跨文件引用它们的句柄。

示例

假设你有两个源文件:main.cuart_dma.c

  • uart_dma.c中,你定义了DMA的句柄并初始化了它:

    DMA_HandleTypeDef hdma_usartx_tx;void MX_DMA_Init(void) {// 初始化DMA句柄hdma_usartx_tx.Instance = DMAx_Channely; // 替换为实际的DMA实例和通道// 其他初始化代码...
    }

  • main.c中,你需要链接串口的handler到DMA的handler,但因为你是在main.c中引用hdma_usartx_tx,而它是在uart_dma.c中定义的,所以你需要在main.c的顶部声明它:

    extern DMA_HandleTypeDef hdma_usartx_tx;void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_USARTx_UART_Init(void);int main(void) {HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_DMA_Init(); // 确保DMA初始化在链接之前完成MX_USARTx_UART_Init();// 链接DMA句柄到UART句柄__HAL_LINKDMA(&huartx, hdmatx, hdma_usartx_tx);// 其他代码...
    }static void MX_USARTx_UART_Init(void) {huartx.Instance = USARTx; // 替换为实际的USART实例huartx.Init.BaudRate = 115200;// 其他初始化代码...
    }

在这个例子中,extern关键字允许main.c访问在uart_dma.c中定义的hdma_usartx_tx变量。

总结

extern的使用是为了在多个源文件之间共享变量。在STM32 HAL库中使用__HAL_LINKDMA时,如果DMA句柄是在另一个文件中定义的,你需要在当前文件中使用extern来声明它,以便能够链接到串口的handler。


http://www.ppmy.cn/news/1548447.html

相关文章

Kafka-创建topic源码

一、命令创建topic kafka-topics --create --topic quickstart-events --bootstrap-server cdh1:9092 --partitions 2 --replication-factor 2 二、kafka-topics脚本 exec $(dirname $0)/kafka-run-class.sh org.apache.kafka.tools.TopicCommand "$" 脚本中指定了…

深入理解 Vue 3 中的 emit

深入理解 Vue 3 中的 emit 在 Vue 3 中,组件通信是开发中非常重要的一部分,其中通过 emit 实现父子组件通信是最常见的方式之一。emit 的作用是:子组件可以通过触发自定义事件将数据传递给父组件。 在本篇文章中,我们将从以下几…

OpenProject安装部署与使用介绍

OpenProject安装部署与使用介绍 1. OpenProject简介 1-1. 什么是OpenProject ​ OpenProject是一个功能全面的开源项目管理软件,它提供了一套集成的工具来支持项目规划、协作和监控。它的核心功能包括任务和问题跟踪、时间管理、新闻和文档管理,以及集…

自动化生成测试用例:利用OpenAI提升电商网站测试覆盖率

导语 自动化生成测试用例是软件测试领域一个强大的应用,通过OpenAI的语言模型,测试工程师可以快速生成高质量的测试用例,尤其是在处理边界条件和极端情况时,提升测试覆盖率。本篇文章将结合一个典型的电商网站案例,介绍…

【无标题】网络命名空间中创建双网卡

这里写自定义目录标题 创建 veth peer 接口对将 veth1 移动到名为 ns1 的网络命名空间配置命名空间 veth1 的ip地址配置命名空间 路由规则配置命名空间 NAT 规则获取容器的命名空间 如果网络命名空间和宿主机的 IP 地址不在同一网段,它们之间仍然可以通过配置适当的…

编译报错:protoc did not exit cleanly. Review output for more information.

目录标题 解决“protoc did not exit cleanly”的报错问题检查.proto文件的语法 解决“protoc did not exit cleanly”的报错问题 今天做的项目需要用到grpc,然后需要编写proto然后编译后实现grpc的具体方法! 结果编译的时候报了protoc did not exit cl…

【Linux】用户和用户组管理

管理用户 1.添加用户账号——useradd命令 【实例2-1-1】 按系统默认配置添加指定用户账号st和stu。 # 添加用户账号st [rootlocalhost ~]# useradd st # 添加用户账号stu [rootlocalhost ~]# useradd stu【实例2-1-2】添加用户账号stu01,UID为1004&am…

矩阵论在图像算法中的应用

摘要: 本文详细阐述了矩阵论在图像算法中的广泛应用。首先介绍了图像在计算机中的矩阵表示形式,然后从图像压缩、图像变换、图像特征提取与识别、图像恢复与重建等多个方面深入分析了矩阵论相关技术的作用原理和优势。通过对这些应用的探讨,展…