野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11168|回复: 9

关于流水灯程序的疑问

[复制链接]
发表于 2015-3-18 20:31:12 | 显示全部楼层 |阅读模式
本帖最后由 kk62822336 于 2015-3-18 20:49 编辑

#define PERIPH_BASE           ((uint32_t)0x40000000)
#define APB1PERIPH_BASE       PERIPH_BASE
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)

#define GPIOB_BASE            (APB2PERIPH_BASE + 0x0C00)
#define GPIOB               ((GPIO_TypeDef *) GPIOB_BASE)


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;


1.这应该是GPIOB对应的是什么地址???上面寄存器的基址???
如果是基址 下面寄存器的地址都是+1??  而且这些地址从何而得??

2.GPIOA-GPIOE GPIO是普通I/O口的意思  这单单就是5个I/O口吧??

3.还有就是 转化为结构体指针 定义一个宏GPIOB来代替 为什么要这么做 结构体指针还是不明白
是不是说像int 整形那样 这个GPIOB 的元素只能来自结构体里面的元素??



QQ截图20150318201124.png
回复

使用道具 举报

发表于 2015-3-19 09:01:40 | 显示全部楼层
看《零死角玩转stm32》的详解流水灯章节,针对这些问题有很详细的解释了
回复 支持 反对

使用道具 举报

发表于 2015-3-19 10:08:26 | 显示全部楼层
1.GPIOB就是GPIO_BASE这个基地址转换为 GPIO_TypeDef类型,这个GPIOB类型的起始地址就是GPIO_BASE,另外,结构体里面的成员的地址是连续的,那么
__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
这几个成员的地址是连续的,就是说CRL是GPIO_BASE的0x00偏移,它的地址就是这个GPIO_BASE地址,CRH是GPIOB_BASE的0x04偏移,那它的地址就是GPIOB_BASE+0x04,定义的这几个成员都是32位的,4个字节,所以0x04偏移。后面也是一样。然后,这几个成员就成了GPIOB的寄存器了。而且,类似其他的GPIO也要这样,那就做一个结构体,都((GPIO_TypeDef *) GPIOx_BASE)一下,就都定义了这些GPIO的寄存器了。所以,下面的地址不是基地址+1,是+4,这可以参考stm32的数据手册,是因为这几个寄存器是32位的,而且相连,所以+4。
2、记得51单片机吗?P0就有P0.1。。。P0.7,这个GPIOB有pin0到pin15,不知道你用的是什么型号的芯片,别的芯片可能是A到G。这就是芯片的资源什么的。。。他们还有重映射的功能,比如说GPIOB的pin5,pin6,可以用作普通输入输出IO,也可复用成什么uart1(没看手册,不知道是不是uart1功能,我随便瞎说的,应该没说中)。
3、第三个问题没看懂。我就试着说一下吧。其实第一点就有说了一下。GPIOB这是这组寄存器的入口地址,基地址,你要操作GPIOB的这些寄存器,就GPIOB,不用记地址了。例如函数GPIOSeBbit(GPIOB,GPIO_Pin_5)将GPIOB的pin5置1,就是把GPIOB的基地址给过去,然后操作pin5.。。。做个结构体,是每个GPIO都有这些成员,你也可以这样用,定义GPIOB的CRL为GPIOB_CRL。。。等等,定义GPIOA的CRL为GPIOA_CRL。。。等等,这样看来,不觉得原来那种封装形式一目了然吗?而且很简洁吗?当然,你要是有时间,可以自己试试重定义这些的,哈哈。。。

那关于结构体,比如你用PID算法,你要做一个速度环pid,还有角度pid,这两个环的pid的参数都有p,i,d,误差error等,那就把这几个成员封装成
struct pid{
               ...
               }pid_速度,pid_角度;
这样看的话一下就知道你有两个pid,成员有什么。当然你也可以定义两组变量,角度_p,角度_i,...速度_p,速度_i.......
好吧,还是要多用F12这个键,就是查看定义什么的。还有,原子的视频的讲解比较详细哟。我用的是野火的开发板,两家的代码我都看,觉得原子的风格比较喜欢。原子的教程你可以找来看看的。
回复 支持 反对

使用道具 举报

发表于 2015-3-19 10:09:12 | 显示全部楼层
另外,我是个半桶水,发现我说错了,一定要指出来啊!!!!!!!!!!!!!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-3-19 16:01:42 | 显示全部楼层
liudijiang 发表于 2015-3-19 10:09
另外,我是个半桶水,发现我说错了,一定要指出来啊!!!!!!!!!!!!!

我的意思是定义成结构体指针,是否像int那样 只要是整形变量都可以  而这个GPIOB是一个宏代替那个结构体指针的,元素只能是里面的几个寄存器?
回复 支持 反对

使用道具 举报

发表于 2015-3-19 17:28:34 | 显示全部楼层
kk62822336 发表于 2015-3-19 16:01
我的意思是定义成结构体指针,是否像int那样 只要是整形变量都可以  而这个GPIOB是一个宏代替那个结构体 ...

定义成int指针,那就那个地址被定义成某个寄存器的地址了。一个GPIO有一段地址呢,要一个一个这么定义吗?比如说,有地址1,2,3,4,5,6,7,8,八个地址,GPIOA的地址是从1到4,B是5到8,那A,B的结构体都是四个成员,如果你A给了5个成员,最后一个成员地址其实就是B的。那你操作A的第五个成员,就是操作B的第一个地址的内容。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-3-19 17:55:18 | 显示全部楼层
本帖最后由 kk62822336 于 2015-3-19 17:59 编辑
liudijiang 发表于 2015-3-19 17:28
定义成int指针,那就那个地址被定义成某个寄存器的地址了。一个GPIO有一段地址呢,要一个一个这么定义吗 ...

你是说定义了结构体指针,其余变量就省去了定义的麻烦了是把?
这个问题呢
#define GPIOB               ((GPIO_TypeDef *) GPIOB_BASE)

GPIO_TypeDef是一个结构体变量名嘛 就像int一样 可以改写成这个一样
#define GPIOB               ((int *) GPIOB_BASE)


我有个疑问就是为什么是强制转化为指针???我查过书对结构体成员操作还有个  . 是把,就是GPIO_TypeDef.XX      转化为指针的话可以用那个箭头。
回复 支持 反对

使用道具 举报

发表于 2015-3-19 18:08:51 | 显示全部楼层
kk62822336 发表于 2015-3-19 17:55
你是说定义了结构体指针,其余变量就省去了定义的麻烦了是把?
这个问题呢
#define GPIOB              ...

为什么转化为指针。如果定义为int类型,那你想,你把一个地址定义为一个int,???????那你怎么操作这个地址的内容?你只有把这个地址定义为一个指针,通过指针你才能操作这个地址的数据啊。你定义成int,那这个int的地址是什么?你要操作的是这个地址啊,因为这个地址就是你要操作的寄存器的地址啊
回复 支持 反对

使用道具 举报

发表于 2015-3-19 18:17:56 | 显示全部楼层
kk62822336 发表于 2015-3-19 17:55
你是说定义了结构体指针,其余变量就省去了定义的麻烦了是把?
这个问题呢
#define GPIOB              ...

#define GPIOB               ((int *) GPIOB_BASE)
这个语句是把GPIOB_BASE转化为一个int指针,那GPIOB_BASE+0x04这个地址呢?你这个语句没有定义到。你要定义一下了。
#define GPIOB               ((GPIO_TypeDef *) GPIOB_BASE)
而这个呢?duang,从GPIOB_BASE开始有几个成员就定义了几个成员的地址,偏移都是+0x04
就是它一次操作,完成了所有变量的操作
你修改的那种操作,你要做好几次才完成它的操作。而且在以后调用的时候,你也没他那么灵活。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-3-31 20:12:41 | 显示全部楼层
liudijiang 发表于 2015-3-19 18:17
#define GPIOB               ((int *) GPIOB_BASE)
这个语句是把GPIOB_BASE转化为一个int指针,那GPIOB ...

最近忙于其他课程 新问题求助
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2025-1-14 18:04 , Processed in 0.034995 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表