一、寄存器
-
寄存器的映射
根据每个单元的功能不同,以功能为名字给内存单元一个别名,而给这个已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器的映射。例如:GPIOB端口输出数据寄存器的地址是0x4001 0C0C,而ODR的寄存器是32bit,只有低16位有效,对相对应的IO写0或1控制低高电平【*(unsigned int *)(0x4001 0c0c)= 0xFFFF】一般我们都会用命名的方式来操作寄存器,这样不容易出错。
如:#define GPIOB_ODR (相对应地址…)GPIOB_ODR = 0xFF; -
偏移地址
偏移地址是指本寄存器相对于这个外设的基地址的偏移。例如:本寄存器的偏移地址是0x10,而在手册里面的GPIOA外设的基地址为0x4001 0800,我们可以推算出GPIOA_BSRR寄存器的地址为:0x4001 0800+0x10。 -
封装总线和外设基地址
首先定义了 “片上外设”基地址 PERIPH_BASE,接着在 PERIPH_BASE 上加入各个总线的地址偏移,得到 APB1、APB2 总线的地址 APB1PERIPH_BASE、APB2PERIPH_BASE,在其之上加入外设地址的偏移,得到 GPIOA-G 的外设地址,最后在外设地址上加入各寄存器的地址偏移,得到特定寄存器的地址。一旦有了具体地址,就可以用指针读写。例如: -
修改寄存器的位操作方法-清零
设a = 1001 1111 (0x9f)对其中的bit2清零有a &= ~(1〈〈 2);先对0000 0001左移两位,然后取反,再与a中的数做位与运算等到a = 1001 1011。如果需要连续的位清零就有a &= ~(x〈〈 y * z);其中x为连续位都为1时的16进制数值,y为每组地位数也就是连续的位有多少个,而z就是每一连续组的编号。 -
修改寄存器位操作的方法-赋值
设a = 1000 0011 , 假设对bit4和bit5赋值(从右开始数第五和第六个数)则有:a |= (1 << 2 * 2); -
修改寄存器位操作的方法-取反
设a = 1001 0011, 把bit6取反有 a ^= (1 << 6);
⚠️新建工程中的注意事项⚠️
- 在魔术棒的Target中选择微库“Use MicroLib”,目的是可以在以后用printf函数。
- 把文件都添加好,基础的话要有三个文件:startup_stm32f10x_hd.s (官方提供)、stm32f10x.h(目前这个文件为空用于存放寄存器映射的代码)和main.c(用于c程序的编写)。
二、寄存器的简单用法(LED灯)
-
GPIO简介
GPIO-通用输入输出端口的简称,是stm32可控制的引脚,当与外部设备连接起来的时候可以实现与外部通信、控制和采集信息的功能。 -
LED的亮灭
控制STM32引脚输出高低电平来实现开关的控制,输入低电平LED灯就会被点亮。
(硬件连接图解) -
准备stm32f10x.h文件
先把有关的寄存器映射代码都写到stm32f10x.h文件中,例如: -
mian文件的编写
初始学习阶段我的SystemInit没有定义,这个函数是用来初始stm32系统时钟的,这里先用一个空函数骗过编译器。例:void SystemInit(void) { ; }
之后我们可以操作地址的方法来点亮LED灯
上部分我学习了寄存器的映射,直接从我们写好的stm32f10x.h里面复制打包好的映射到main.c文件里面使用,如下图:
(附上次工程中已写好的stm32f10x.h文件里面的映射函数)
(学习书籍:《零死角玩转STM32》)