STM32 固件寄存器配置

2019-03-23 20:05发布

请教高手:我还是不太明白,固件寄存器是怎么和PPPI_nitTypeDef中的参数联系起来的?为什么不需要对固件寄存器进行 OX xxxx 的赋值来配置呢? 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
9条回答
daicheng
1楼-- · 2019-03-24 03:16
/ 你可以拿出一个例子,我给你讲一下:
GPIO为例:GPIO_InitTypeDef GPIO_InitStructure;先初始化一个GPIO的结构体
                       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8;
                       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
                       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
                       GPIO_Init(GPIOB, &GPIO_InitStructure);写到寄存器中。
#define GPIO_Pin_0                 ((u16)0x0001)  /* Pin 0 selected */这里定义数值
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)写入寄存器的
你可以单步走,了解过程!
mikyy
2楼-- · 2019-03-24 06:01
lai xue xi xue xi le
wenjin0386
3楼-- · 2019-03-24 07:59
 精彩回答 2  元偷偷看……
lf200036077
4楼-- · 2019-03-24 13:00

以固件库v3.5为例
第一步:
#define FLASH_BASE        ((uint32_t)0x08000000)
#define SRAM_BASE             ((uint32_t)0x20000000)
#define PERIPH_BASE           ((uint32_t)0x40000000)
#define SRAM_BB_BASE          ((uint32_t)0x22000000)
#define PERIPH_BB_BASE        ((uint32_t)0x42000000)
#define FSMC_R_BASE           ((uint32_t)0xA0000000)
以PERIPH_BASE为例:
说明,mcu把所有外设的寄存器地址在40000000开始向后0x22000000之前的单元中。
这是也可以看出mcu设计者的设计思想。

第二步:在第一步的基础上进一步分段
#define APB1PERIPH_BASE       PERIPH_BASE
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE        (PERIPH_BASE + 0x20000)
我们可以看出,以PERIPH_BASE(40000000)为首地址的寄存器段
分三部分 :挂在总线APB1的外设,挂在总线APB2的外设,挂在高速总线AHB的外设
分别对应:APB1PERIPH_BASE,APB2PERIPH_BASE,AHBPERIPH_BASE

第三步:在第二步的基础上进一步分段
#define GPIOA_BASE            (APB2PERIPH_BASE + 0x0800)
#define GPIOB_BASE            (APB2PERIPH_BASE + 0x0C00)
#define GPIOC_BASE            (APB2PERIPH_BASE + 0x1000)
#define GPIOD_BASE            (APB2PERIPH_BASE + 0x1400)
#define GPIOE_BASE            (APB2PERIPH_BASE + 0x1800)
#define GPIOF_BASE            (APB2PERIPH_BASE + 0x1C00)
其它外设的基地址定义也如此,
至此可以大致看到,各外设寄存器的大致分布。

第四步:在前三步的基础上进行具体定义
#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
#define GPIOB               ((GPIO_TypeDef *) GPIOB_BASE)
#define GPIOC               ((GPIO_TypeDef *) GPIOC_BASE)
#define GPIOD               ((GPIO_TypeDef *) GPIOD_BASE)
#define GPIOE               ((GPIO_TypeDef *) GPIOE_BASE)
可以看出GPIOA是指向GPIOA_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;
这样各功能外设的寄存器地址,就映射到 其对应的结构体指针上了。
如访问 GPIOA->CRL

lf200036077
5楼-- · 2019-03-24 14:58
为什么不直接用,这个就是编程思想了
编程的时候,思维连续,是顺着忘下走的,而且不乱。就好像分类存放了东西
假如没有这样的结构,你的编程的思维就是跳着走,思考编程的时候,不自然的感觉每个寄存器都是独立的。
lf200036077
6楼-- · 2019-03-24 15:58
 精彩回答 2  元偷偷看……

一周热门 更多>