什么是寄存器?
如何访问寄存器
这里我们以端口数据输出寄存器为例。 若想让端口输出1,就需要在寄存器中输入1。寄存器地址如下,Port B为地址。
地址偏移为0c,起始地址0x40010c00,所以寄存器的地址为0x40010c0c。星是取地址符号,如果p是指针(地址),那么*p就是p所指向的变量,(unsigned int星)是强制转化为指针变量。
但是这种做法也有缺点,就是很麻烦。
于是我们可以这样。
通过宏定义,将地址赋值给GPIOB_ODR,这样我们定义的变量就是一个指针。
如果这样的话,那么我们定义的变量是指针指向的变量,由于我不清楚到底指向哪里,姑且叫他寄存器变量。
那我我们可以给寄存器下一个定义。
STM32寄存器映射
以上是数据手册中寄存器的映像,其中三条总线APB1(低速),APB2与AHP(高速),外设就连接在三条总线上。
外设地址相对总线基地址也就是0x4000 0000的偏移。
C语言对寄存器的封装
想让PB10输出1,那怎么办,我们可以用GPIO_ODR=(1<<10)实现,即1左移了10位。
这种操作的弊端,第一次给PB10赋1没问题,再想给PB1赋1,那么PB10就被消失了。
那么我们的解决方法就是GPIO_ODR |=(1<<0); 或上1左移0位,或就是加,那么原本的PB10为1的状态就不会消失,同时我们还将PB0赋值为1
如果我们需要赋值低电平,那么就需要用到与。
GPIO_ODR & =~(1<<10);
1左移10位再取反,那么只有这个是0其余位全是1,或运算之后其余位不变,而目标位变成0。以此实现低电平。
总结一下就是下面:
由于访问寄存器地址比较麻烦,加之寄存器地址也是连续排列,与C语言结构体类似,于是:
然后:
或者使用更先进的方法: