完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
//LCD地址结构体
typedef struct { u16 LCD_REG; u16 LCD_RAM; } LCD_TypeDef; 结构体定义成这样,如何让LCD_REG变量对应地址为0x6000 0000,LCD_RAM对应寄存器地址为0x6002 0000? |
|
相关推荐
11个回答
|
|
#define LCD ((LCD_TypeDef*)0X60000000 )
结构体每个成员变量都是16bit的。所以,第一个LCD->LCD_REG的地址0X60000000.第二个LCD->LCD_RAM地址自增2个字节。。。 |
|
|
|
dongyumin 发表于 2014-1-19 11:03 首先,谢谢您的回答,这个我知道,问题是我想让这个结构体第二个成员地址为0x6002 0000,后面用到LCD->LCD_REG和LCD->LCD_RAM这两个变量,名字不改了,但对应变量地址需要改变。 |
|
|
|
typedef struct { __IO uint16_t CR1; uint16_t RESERVED0; __IO uint16_t CR2; uint16_t RESERVED1; __IO uint16_t OAR1; uint16_t RESERVED2; __IO uint16_t OAR2; uint16_t RESERVED3; __IO uint16_t DR; uint16_t RESERVED4; __IO uint16_t SR1; uint16_t RESERVED5; __IO uint16_t SR2; uint16_t RESERVED6; __IO uint16_t CCR; uint16_t RESERVED7; __IO uint16_t TRISE; uint16_t RESERVED8; } I2C_TypeDef; 库里的结构体,定义了成员变量RESERVED来保留一些不用的地址空间,,,这些寄存器实质都是4字节的,而有效位都只有它们的低16位,软件上为了对齐,定义了保留成员变量用于填充内存。。。 |
|
|
|
我是不是可以理解为将第一个变量地址指定为0x6000 0000,中间填充保留变量(实际未用),一直到地址为0x6002 0000呢?可是这样定义的保留变量就太多了2的16次方个(65536)。能不能弄到一个结构体中呢?不能的话,怎样定义成该地址的指针变量啊?再次感谢! |
|
|
|
#define LCD_RAM ((volatile u16*)0x60020000)
#define LCD_REG ((volatile u16*)0x60000000) 直接这样变成指针吧、、、呵呵、 |
|
|
|
dongyumin 发表于 2014-1-19 18:10 好吧,谢谢啦~ |
|
|
|
本帖最后由 fanssun 于 2015-11-16 12:54 编辑
*注:一下内容来自 原子STM32开发板配套书籍《STM32F1开发指南-寄存器版本_V3.1 》 首先我们看看 51 中是怎么做的。 51 单片机开发中经常会引用一个 reg51.h 的头文件,下 面我们看看他是怎么把名字和寄存器联系起来的: sfr P0 =0x80; sfr 也是一种扩充数据类型,点用一个内存单元,值域为 0~255。利用它可以访问 51 单片 机内部的所有特殊功能寄存器。如用 sfr P1 = 0x90 这一句定义 P1 为 P1 端口在片内的寄存 器。然后我们往地址为 0x80 的寄存器设值的方法是: P0=value; 那么在 STM32 中,是否也可以这样做呢??答案是肯定的。肯定也可以通过同样的方 式来做,但是 STM32 因为寄存器太多太多,如果一一以这样的方式列出来,那要好大的篇 幅,既不方便开发,也显得太杂乱无序的感觉。所以 MDK 采用的方式是通过结构体来将 寄存器组织在一起。下面我们就讲解 MDK 是怎么把结构体和地址对应起来的,为什么我 们修改结构体成员变量的值就可以达到操作对应寄存器的值。这些事情都是在 stm32f10x.h 文件中完成的。我们通过 GPIOA 的几个寄存器的地址来讲解吧。 首先我们可以查看《 STM32 中文参考手册 V10》中的寄存器地址映射表(P159): ALIENTEK 战舰 STM32F103 V3 开发板教程 132 STM32F1 开发指南(库函数版) 图 4.6.1 GPIO 寄存器地址映像 从这个表我们可以看出, GPIOA 的 7 个寄存器都是 32 位的,所以每个寄存器占有 4 个地址,一共占用 28 个地址,地址偏移范围为( 000h~01Bh)。这个地址偏移是相对 GPIOA 的基地址而言的。 GPIOA 的基地址是怎么算出来的呢?因为 GPIO 都是挂载在 APB2 总线 之上,所以它的基地址是由 APB2 总线的基地址+GPIOA 在 APB2 总线上的偏移地址决定 的。同理依次类推,我们便可以算出 GPIOA 基地址了。这里设计到总线的一些知识,我们 在后面会讲到。下面我们打开 stm32f10x.h 定位到 GPIO_TypeDef 定义处: typedef struct { __IO uint32_t CRL; __IO uint32_t CRH; __IO uint32_t IDR; __IO uint32_t ODR; __IO uint32_t BSRR; __IO uint32_t BRR; __IO uint32_t LCKR; } GPIO_TypeDef; 然后定位到: #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) 可以看出, GPIOA 是将 GPIOA_BASE 强制转换为 GPIO_TypeDef 指针,这句话的意思是, GPIOA 指向地址 GPIOA_BASE, GPIOA_BASE 存放的数据类型为 GPIO_TypeDef。然后双 击“ GPIOA_BASE”选中之后右键选中“ Go to definition of ”,便可一查看 GPIOA_BASE 的宏定义: #define GPIOA_BASE (APB2PERIPH_BASE + 0x0800) 依次类推,可以找到最顶层: #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) #define PERIPH_BASE ((uint32_t)0x40000000) 所以我们便可以算出 GPIOA 的基地址位: ALIENTEK 战舰 STM32F103 V3 开发板教程 133 STM32F1 开发指南(库函数版) GPIOA_BASE= 0x40000000+0x10000+0x0800=0x40010800 下面我们再跟《 STM32 中文参考手册 V10》比较一下看看 GPIOA 的基地址是不是 0x40010800。截图 P28 存储器映射表我们可以看到, GPIOA 的起始地址也就是基地址确实 是 0x40010800: 图 4.6.2 GPIO 存储器地址映射表 同样的道理,我们可以推算出其他外设的基地址。 上面我们已经知道 GPIOA 的基地址,那么那些 GPIOA 的 7 个寄存器的地址又是怎么 算出来的呢??在上面我们讲过 GPIOA 的各个寄存器对于 GPIOA 基地址的偏移地址,所 以我们自然可以算出来每个寄存器的地址。 GPIOA 的寄存器的地址=GPIOA 基地址+寄存器相对 GPIOA 基地址的偏移值 这个偏移值在上面的寄存器地址映像表中可以查到。 那么在结构体里面这些寄存器又是怎么与地址一一对应的呢?这里就涉及到结构体的 一个特征,那就是结构体存储的成员他们的地址是连续的。上面讲到 GPIOA 是指向 GPIO_TypeDef 类型的指针,又由于 GPIO_TypeDef 是结构体,所以自然而然我们就可以算 出 GPIOA 指向的结构体成员变量对应地址了。 寄存器 偏移地址 实际地址=基地址+偏移地址 GPIOA->CRL 0x00 0x40010800+0x00 GPIOA->CRH; 0x04 0x40010800+0x04 GPIOA->IDR; 0x08 0x40010800+0x08 GPIOA->ODR 0x0c 0x40010800+0x0c GPIOA->BSRR 0x10 0x40010800+0x10 GPIOA->BRR 0x14 0x40010800+0x14 GPIOA->LCKR 0x18 0x40010800+0x18 表 4.6.3 GPIOA 各寄存器实际地址表 我们可以把 GPIO_TypeDef 的定义中的成员变量的顺序和 GPIOx 寄存器地址映像对比 可以发现,他们的顺序是一致的,如果不一致,就会导致地址混乱了。 这就是为什么固件库里面: GPIOA->BRR=value;就是设置地址为 0x40010800 +0x014(BRR 偏移量)=0x40010814 的寄存器 BRR 的值了。它和 51 里面 P0=value 是设置地 址为 0x80 的 P0 寄存器的值是一样的道理。 |
|
|
|
这个真的是极不错的
|
|
|
|
豁然开朗
|
|
|
|
问一个有点傻的问题啊,结构体变量在初定义时不就有自己的初始首地址吗?再强制定义一个这个类型的指针,指向的地址却是已知的啊
|
|
|
|
dddddddddddddddddddddddddddddddd
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-移植前准备之git管理内核源码
304 浏览 0 评论
【瑞萨RA2L1入门学习】+ MacOS安装e2studio
253 浏览 0 评论
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-本地仓库管理之分支间的操作
650 浏览 0 评论
【RA-Eco-RA4E2-64PIN-V1.0开发板试用】3D 图形显示
510 浏览 0 评论
641 浏览 1 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
12212 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-24 16:37 , Processed in 0.545542 second(s), Total 56, Slave 51 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号