STM32单片机寄存器的位置是如何定义的

一直都是用stm32做项目中的主控芯片,在编程的时候,之前一直忽视了一个问题,那就是寄存器的位置是如何定义的,为什么用一个usart1-》cr操作就能够给这个cr寄存器赋值?其实这是一个比较底层的问题,不懂这方面的知识也并不影响使用stm32,因为底层的定义工作,厂家一般都会做好,但是多了解一点原理性的东西,对自己还是很有帮助的。
这里我就以stm32f407的usart寄存器为例,介绍一下st厂家是如何做寄存器定义的。
首先在stm32f4xx.h中
typedefstruct
{
__iouint16_tsr;/*!
uint16_treserved0;/*!
__iouint16_tdr;/*!
uint16_treserved1;/*!
__iouint16_tbrr;/*!
uint16_treserved2;/*!
__iouint16_tcr1;/*!
uint16_treserved3;/*!
__iouint16_tcr2;/*!
uint16_treserved4;/*!
__iouint16_tcr3;/*!
uint16_treserved5;/*!
__iouint16_tgtpr;/*!
uint16_treserved6;/*!
}usart_typedef;
这是因为usart的寄存器组包括sr,dr,brr,cr1,cr2,cr3,gptr这几个寄存器,所以用一个usart_typedef结构体包含这些寄存器。如果在别的程序中用到这些寄存器,只需要如下:
usart_typedefusart1//任意取名,尽量与datasheet中给出的名字一致便于理解
usart1.sr=0x00000001;
或者
usart_typedef*usart1
usart1-》sr=0x00000001;
(*usart1).sr=0x00000011;
那么具体到各个寄存器的位置到底是怎样的呢?从datasheet和reference manual中可以看到
usart2属于apb1管理的外设,起始地址是0x4000 4400,stm32上所有的外设的基地址都是0x4000 0000(这其实是arm公司规定的),这也是apb1的起始地址,然后usart2的起始地址在apb1外设基地址的基础上偏移0x4400,于是便可以按照下面代码来分配各个外设的起始地址了
#defineperiph_base((uint32_t)0x40000000)
/*!
/*!
#defineapb1periph_baseperiph_base
#defineusart2_base(apb1periph_base+0x4400)
#defineusart3_base(apb1periph_base+0x4800)
#defineuart4_base(apb1periph_base+0x4c00)
#defineuart5_base(apb1periph_base+0x5000)
#defineusart2((usart_typedef*)usart2_base)
#defineusart3((usart_typedef*)usart3_base)
#defineuart4((usart_typedef*)uart4_base)
#defineuart5((usart_typedef*)uart5_base)
有了这些外设的基地址,加上上面提到的寄存器结构体,便可以操作各个寄存器了,例如,只需要如下语句,便可以使能usart2
usart_cmd(usart2,enable);
usart_cmd这是st官方给出的库函数,具体定义如下
voidusart_cmd(usart_typedef*usartx,functionalstatenewstate)
{
/*checktheparameters*/
assert_param(is_usart_all_periph(usartx));
assert_param(is_functional_state(newstate));
if(newstate!=disable)
{
/*enabletheselectedusartbysettingtheuebitinthecr1register*/
usartx-》cr1|=usart_cr1_ue;
}
else
{
/*disabletheselectedusartbyclearingtheuebitinthecr1register*/
usartx-》cr1&=(uint16_t)~((uint16_t)usart_cr1_ue);
}
}
如果理解了上述所讲的内容,你会发现,这种通过结构体定义寄存器的方法非常常见,这是因为现在的处理器,各种寄存器相当多(成百上千),如果按照传统的定义方法去操作寄存器,会相当的麻烦。不只是stm32,我知道的有ti的c2000系列dsp,nxp的arm系列mcu,瑞萨的arm r4 rz/t1处理器都是按这样的方法来定义寄存器。


江苏长晶发布FST2.0高性能IGBT系列产品
交流供电系统的作用
PCB红墨水测试的定义
教程|创建你的第一个Actor Framework
三星关闭工厂消息终于坐实,坚决不做下一个诺基亚
STM32单片机寄存器的位置是如何定义的
毫米波是推进5G持续商用的重要方向
基于HHARM2410嵌入式开发套件实现多输入H.264视频服务器的设计
中国台湾Getac在平板电脑中嵌入LiFi技术
国科微从多个维度提出固态硬盘国产化核心要素 以应对行业市场的需求
6月,上海等你!| 第二届生物医学光子学交叉融合学术论坛
标准电容器概述
电容容量选择规则与经验技巧
交换机的分类及特点
Intel推出集成高带宽存储器的FPGA
一氧化碳传感器在线监测烟道废气CO含量改善燃气锅炉的燃烧效率
造成磁翻板液位计出现假液位的原因有哪些
“生死看淡”的雷军要造车,这对中国的汽车产业意味着什么?
igbt真空回流焊空洞问题
电动不锈钢法兰球阀的声响密封方式介绍