This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
您好!
我对 RM46微控制器的编程有几个问题。 这是一个有点长的帖子、我试图解释我到目前为止所做的工作以及我不确定的问题、我需要您的帮助来解决这些问题。
我试图在不使用 HALCoGen 的情况下对其进行编程、因此撞上了一堵超越中国长城的巨大墙(去看、哈哈)。
我想指出、我不想使用 HALCoGen、我想自己写下所有内容。 如果您想知道、我为什么会给出两个原因、因为我担心讨论会以"使用 HALCOGEN "的方式进行、我想避免这样做:
例如、让我们谈谈我编写自己的 GPIO。 我下载了技术参考手册(大约2000页、这是我迄今为止阅读过的最长的手册)、以熟悉我需要在每个寄存器中写入的内容、从而获得所需的结果。 假设我要打开 GPIO。 我需要使用 GIOGCR0寄存器。 也就是说、如果我在位0上写入1、它将启用 GPIO。 但极其奇怪的是、只要我在.h 文件中写入 GIOGCR0、我就不会收到任何错误、并且我的程序会编译(我发现这是奇怪的后者)。 但是、我收到警告:"此声明没有存储类或类型说明符"。 自从我与 Eclipse 合作对 Arduino 进行编程以来、我最初并没有对它多加注意、并且每个寄存器名称都会发出警告。 当我开始认真对待警告时、叉子是我开始编写利用 GIODIN 的函数时。 我无法真正在头文件中写入该内容、因此我在头文件中写入函数原型的同时跳转到.c 文件中写入该内容。 让我感到惊讶的是、我遇到了两个主要错误。 第一个问题是 Code Composer Studio 不了解 uint32_t 或 uint32类型。 第二个问题是找不到 GIODIN 寄存器。 这让我很好奇、所以我决定做我能想到的最愚蠢的事情>>让我们删除 Gio.c 并在.h 文件中写入 GIODIN 寄存器、这样我得到了更令人困惑的结果。 编译仅通过少量警告。 这时我意识到编译器无法找到该寄存器的存储器地址、该地址本应会导致错误、但没有。 奇怪、不是吗?
然后、我决定转到 Google、尝试找到每个寄存器的已定义存储器位置的库。 没有、因为每个人都使用 HALCoGen。。。 这似乎是我在那里唯一的怪人,这就是为什么我在这里。 然后我决定再次挑选冗长的技术手册、因为我没有其他选择、所以第一次编写自己的寄存器文件、我不知道如何执行、所以我需要您的帮助。 我首先发现的是:
表2-3. 模块寄存器/存储器存储器映射(续)
GIO PS[16] 0xFFF7_BC00 0xFFF7_BCFF 256 B 256 B 读取返回零、写入无效
让我们还说、我不知道什么是 PS[16]、也不知道它是存储器选择。
从这个开始、我意识到 GIO 端口被从0xFFF7BC00寻址到0xFFF7BCFF、这是很好的、但是我不能对该信息做很多事情、除非我知道在该位置映射的每个寄存器的存储器地址。
接下来我注意到的是 、如果我想对 PORTB 偏移54h 使用 GIODIR、请参见表25-1。 寄存器的说明。 在这种情况下、什么是"h"? 这会影响什么吗?
我想知道的是 、如果该寄存器的地址为0xFFF7_BC54、我如何指定它只应向上直到0xFFF7_BC58、这是 GIODIN 寄存器启动的地址? 我假设使用 UINT32、因为它是两个寄存器之间的长度、所以有助于#define 语句、但 Code Composer Studio 仍然不知道 UINT32是什么、这对于基于微控制器的 IDE 来说很烦人。
到目前为止、我还不需要自己写下这些内容、因此我不确定如何执行、因为我仍然遇到错误。
假设我有 gio_register.h 文件、我将在其中写下:
#define GIOGCR0 ((uint32_t *) 0xFFF7BC00)
#define GIOINTDET (volatile UINT32_t *) 0xFFF7BC08
#define GIOPOL ((unti32_t *) 0xFFF7BC0C)
。
。
。
#define GIODIRB (((uint32_t *) 0xFFF7BC54)
#define GIODINB ((volatile UINT32_t *) 0xFFF7BC58)
。
。
。
#define GIOPSLB (((uint32_t *) 0xFFF7BC70)
这是否起作用? 我是否需要指定每个寄存器都是易失性的? 我并不是完全确定这一点。 在我看来、只需要更改时间的寄存器、如 GIODIR、但如 GIOCR0、则不需要、因为它们仅在开始时初始化。 您对此有何看法? 如果不需要关闭优化、我不是关闭优化的粉丝、但在这种情况下、由于 TI 拥有令人惊叹的处理器、它不会产生任何明显的结果。 当我第一次被引入'volatil'关键字时、我被告知:"将其添加到任何地方、以防万一"... 我不能赞同这一说法。
很明显、即使这样做可行、我仍有一个问题、那就是 Code Composer Studio 不知道什么 UINT32与某些用于微控制器的其他 IDE 不同。 我知道 UINT32是 typedef、但为什么默认情况下 Code Composer Studio 无法识别它? 要做什么?
此外、我还必须参考到目前为止遇到的问题来提出其他问题。
我在 HALCoGen 生成的代码中看到的是:#define gioREG ((gioBASE-t *) 0xFFF7BC00U)
它后来被称为、例如: gioREG->GCR0 = 1U;
由于 GCR0是 typedef 结构的第一个成员、因此它会保留该结构中的前32位、因此毫无疑问、它的地址是0xFFFFFF7BC00。 但是、该 U 会附加到分配给 gioREG (1U) GCR0成员的地址(0xFF7bc00U)和编号后是什么? 它是否与偏移中的"h"有关(例如56h)? 这是否意味着无符号数? 或者它是什么?
因此,如果是 HALCoGen 生成的代码,则为 gioREG->GCR0赋值时,这四个值是否相同?
如果不是、会有什么差异?
是否可以省略 U 起始地址? 这两者是否相同?
与 HALCoGen 提供的这种看似巧妙的解决方案相反、我不想分配新的易失性 typedef、甚至位字段。 我只想让每个寄存器定义其准确的存储器位置并直接使用、因此:#define GIODIN ((volatile UINT32_t *) 0xSOME_ADDRESS)、然后后者被调用、如 GIODIN = 0x01;
还有一件事,我要总结一下,这是一篇文章。 由于我知道 Eclipse IDE 不支持字类、例如、与用于 C 编程的 Microsoft Visual Studio 不同、我想知道它是否支持"或_的二进制/八进制/十六进制定义、例如:
GIOGCR0 = 0b0000'0000'0000'0000'0000'0000'0000'0000'0000;
或
#define REG_NAME ((uint8_t *) 0x1234_5678)
这是否会在 Code Composer Studio 中顺利通过?
提前感谢您阅读所有这些内容、并希望能帮助我解决问题!
Nemanja、
我会看到与控制器、HALCoGen 生成的代码、编译器和常规 C 相关的问题
我将介绍通用 C One:
> 第一个原因是 Code Composer Studio 不了解 uint32_t 或 uint32类型。
在 stdint.h 和中定义的 uint32_t
HALCoGen 中定义的 UINT32生成了 HL_hal_stdtypes.h
>、是否可以省略 U 起始地址? 这两者是否相同?
> 0xFFF7BC00U
> 0xFFF7BC00
U 表示它被显式预定义为无符号常量。
事实上、如果编译器在不指定 U 后缀时将其视为无符号或有符号、则会有点复杂、
根据它所适应的变量大小,您正在编程的设备的架构,...
>" 此声明没有存储类或类型说明符"
您是否正在尝试在 C 程序中使用 C++结构?
[引用用户="Jan Cumps"]
>" 此声明没有存储类或类型说明符"
您是否正在尝试在 C 程序中使用 C++结构?
[/报价]
感谢您的回答。 我理解你写的所有内容。
不幸的是、我认为您误解了该警告的发生。 否、我不使用 C++。 这就是为什么我试图解释我正在做的事情、以避免这种混乱、所以我将以不同的方式再次尝试。
此警告是由以下行引起的:
GIOGCR0 = 0x01;
换句话说、我将为 GIOGCR0寄存器分配值1以将其打开。
正如我已经指出的、似乎找不到 GIOGCR0寄存器。 当 HALCoGen 生成代码时、它会生成名为 reg_gio.h 的库、其中它使用 typedef 结构存储寄存器的存储器地址。
现在、我需要做的是、不生成 HALCoGen 代码、而是自己创建该位置。
当我写入时(我已包含 stdint.h):
#define GIOGCR0 ((uint32_t *) 0xFFF7BC00
或
#define GIOGCR0 ((uint32_t *) 0xFFF7BC00U
然后说
GIOGRC0 = 0x01;
或
GIOGCR0 = 1U;
我会同时收到警告和错误。
警告保持不变>>'此声明没有存储类或类型说明符'
错误提示>>'uint32_t has already been declared in the current scope'
现在、它不仅不了解什么是 GIOGCR0、而且不会将其解释为任何地址。
有没有关于如何解决此问题的想法?
如果创建了容纳 unit32_t 的结构、并使指针指向该结构、则可以分配一个值。
在标题中:
typedef volatile struct GCR0 { INT GCR0; /**< 0x0000:全局控制寄存器*/ }GCR0_t; #define GCR0REG ((GCR0_t *) 0xFFF7BC00U)
在.c 文件中:
GCR0REG -> GCR0 = 0x01U;
未经测试、但它可以与以下原语配合使用:
typedef volatile int GCR0_t; #define GCR0REG ((GCR0_t *) 0xFFF7BC00U) // *GCR0REG = 0x01U;
[引用用户="Nemanja Tomovic"]Aye! 感谢所有的帮助! :)这起作用。
此外、如果我只执行以下操作、它就会起作用:
#define GIOGCR0 ((UINT32 *) 0xFFF7BC00U)
GIOGCR0 = 0x00;
不再有问题了。
所以、唯一的问题是 uint32_t。。。。 :(
再次感谢你们! )
[/报价]
我的测试在此方面失败:
#define GIOGCR0 ((UINT32 *) 0xFFF7BC00U) GIOGCR0 = 0x00;
在 GCC 中: 错误:需要使用值作为赋值的左操作数
在 TI 编译器中: 错误#138:表达式必须是可修改的值
这是一个链接器警告、用于指出您的链接器定义文件不符合预期。
在无 HALCoGen-less 路径上继续前进:
您会发现、一旦能够将二进制文件加载到控制器、您的程序很可能无法真正 运行。
Hercules 很复杂,在启动 main()之前需要设置许多寄存器。 (检查 hl_sys_core.asm 和 hl_sys_startup.c 文件,以了解调用 main()之前运行的代码的印象)。
您需要定义和初始化中断矢量,使加载代码的部分可执行,设置内存高速缓存选项,初始化 PLL 和时钟域,电源域,...
如果您可以完成并控制 GIO 引脚、这是一项大胆的练习。