TM4C123G学习记录(4)--关于ROM前缀函数和HWREG函数

博主为准备电赛学习TM4C123G并记录内容。介绍了ROM前缀函数,使用该函数可节省内存,还分析了其调用过程;同时讲解了HWREG函数,它用于操作硬件寄存器,通过转换指针可方便对寄存器读写。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 为了准备电赛临时学一下TM4C123G,简单记录学习内容
  • 大家可以在这里下载我收集的资源,非常全面,花了很大功夫收集来的,还有书籍、例程代码等
  • 还可以在TI官网下载相关文档TI官网

这两天学习TM4C的时候,看到了不少ROM前缀的库函数(比如ROM_SysCtlClockSet),还有很多库函数底层用了HWREG函数,比较迷糊,查资料学习了一下,在此稍作总结

一、ROM前缀函数

1、介绍

  • M4的ROM中集成了外设驱动库等代码。使用带ROM的函数,会直接跳转到ROM中去执行。如果不带ROM的话,代码会在Flash中执行。也就是说使用ROM函数可以节省内存空间,而带ROM前缀的函数在功能上和不带的没有区别
  • 使用ROM前,需要包含头文件#include "rom.h",并且按这个头文件中的格式定义芯片型号(因为不同型号芯片,函数在ROM中的存储情况不一样,rom.h中会根据这个芯片选择定义进行条件编译,打开看一下就知道了),如TARGET_IS_TM4C123_RB1,一般这种选型的定义可以放在MDK的Opinion菜单的C/C++选项栏中
    在这里插入图片描述

2、ROM函数调用分析

ROM_SysCtlClockSet函数为例,分析一下调用过程

(1)直接Goto Defination,如下

	#if defined(TARGET_IS_TM4C123_RA1) ||                                         \
   		defined(TARGET_IS_TM4C123_RA3) ||                                         \
    	defined(TARGET_IS_TM4C123_RB1) ||                                         \
    	defined(TARGET_IS_TM4C123_RB2)
	#define ROM_SysCtlClockSet                                                    \
        	((void (*)(uint32_t ui32Config))ROM_SYSCTLTABLE[23])
	#endif
  • 首先可以看出定义芯片信号TARGET_IS_TM4C123_RB1的作用,这里是一个条件编译
  • 分析ROM_SysCtlClockSet的定义,可以看到这里是一个强制类型转换,把ROM_SYSCTLTABLE[23]转换为一个函数指针void (*)(uint32_t ui32Config),指向地址ROM_SYSCTLTABLE[23]

(2)看一下ROM_SYSCTLTABLE[23]是什么

	#define ROM_APITABLE            ((uint32_t *)0x01000010)
	#define ROM_VERSION             (ROM_APITABLE[0])
	....
	#define ROM_SYSCTLTABLE         ((uint32_t *)(ROM_APITABLE[13]))
  • 看到这里是一个基址寻址,ROM_APITABLE是一个uint32_t型指针,指向地址 0x01000010,这样可以把它看做一个uint32_t数组
  • ROM_SYSCTLTABLE(uint32_t *)(ROM_APITABLE[13]),即取ROM_APITABLE数组的第13个元素(地址为0x01000010+13*4)的值,然后用一个unt32_t型指针指向这个值。可以推测,ROM_APITABLE数组存储的应当也是地址值

(3)小结一下

  • ROM中API表从地址0x0100010开始,每4个字节存一个uint32_t型数据,指向一个子表的首地址
  • 子表中,每4个字节存一个uint32_t型数据,指向一个函数地址
    在这里插入图片描述

二、HWREG函数

(1)顾名思义HWREG()的意思就是操作硬件寄存器的意思,里面的参数是tm4c芯片的硬件外设寄存器地址,可以在芯片手册memory地址分配找到。
(2)查看一下定义,有不少类似的函数

	//*****************************************************************************
	//
	// Macros for hardware access, both direct and via the bit-band region.
	//
	//*****************************************************************************
	#define HWREG(x)                                                              \
     	   (*((volatile uint32_t *)(x)))
	#define HWREGH(x)                                                             \
    	    (*((volatile uint16_t *)(x)))
	#define HWREGB(x)                                                             \
    	    (*((volatile uint8_t *)(x)))
	#define HWREGBITW(x, b)                                                       \
    	    HWREG(((uint32_t)(x) & 0xF0000000) | 0x02000000 |                     \
       	       		(((uint32_t)(x) & 0x000FFFFF) << 5) | ((b) << 2))
	#define HWREGBITH(x, b)                                                       \
    	    HWREGH(((uint32_t)(x) & 0xF0000000) | 0x02000000 |                    \
       	        	(((uint32_t)(x) & 0x000FFFFF) << 5) | ((b) << 2))
	#define HWREGBITB(x, b)                                                       \
    	    HWREGB(((uint32_t)(x) & 0xF0000000) | 0x02000000 |                    \
        	       (((uint32_t)(x) & 0x000FFFFF) << 5) | ((b) << 2))
  • 由定义不难看出,HWREG(x)函数的作用,就是先把x转为一个指向x的volatile uint32_t指针,然后从中取值,这样只要知道寄存器地址,我们就可以方便地对其进行读写操作

(3)更多介绍,参考TIVA中HWREG()使用详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云端FFF

所有博文免费阅读,求打赏鼓励~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值