STM32单片机可以使用库函数进行操作,再加上现在越来越强大的MDK ARM编译环境,使用库函数开发简直是不二的选择,但是工具越来越强大的同时意味着对编程人员降低了要求,在很大程度上降低了准入门槛,我们因此高兴吗?我倒是觉得这很像温水煮青蛙,所以库函数固然好用却也不应该抛弃最初的做法——寄存器操作。
先从启动文件开始介绍:这里介绍比较常见的一种启动方式(从内部的的FLASH启动,至于另外两个是否常用本人不甚了解),在启动代码了首先对栈和堆的大小进行定义,并在代码的起始处建立中断向量表,其第一个表项是栈顶(__initial_sp )地址,第二个表项是复位中断服务( Reset_Handler )入口地址。然后在复位中断服务程序中跳转C/C++标准实时库的__main函数,完成用户堆栈等的初始化后,跳转.c文件中的main函数开始执行C程序。STM32从内部FLASH启动,中断向量表起始地位为0x8000000,则栈顶地址存放于0x8000000处,而复位中断服务入口地址存放于0x8000004处。当STM32遇到复位信号后,则从0x80000004处取出复位中断服务入口地址,继而执行复位中断服务程序,然后跳转__main函数,完成这些事情在才始进入最耗费我们精力的main函数。以上内容是否重要,因项目而异,不过栈大小和堆大小可能会需要改动的,如果有机会学习cortex-A系列的SoC,比如三星的S5PV210之类一定会接触到启动文件(bootloader)的。
一个插曲,就是systeminit ,这个函数在官方提供的3.5版本的固件库的启动文件里是在main函数之前运行的,也就是说在官方给的库函数里面是有这个函数的,并且里面的内容是官方给出的,目的是设置系统的频率,一般是72M,但是我希望直接操作寄存器一定要写这个函数吗,或者一定要在main函数之前执行吗,答案是不一定,一个简单粗暴的办法就是直接写一个空的systeminit函数,写一个空的并不建议因为毕竟要调整这个SoC各个总线的频率,不如添加上。直接在启动文件里删去关于systeminit的代码也是可以的,在之后的操作里面写main函数的时候先调用systeminit函数,自己设置频率。
进入主题,说说寄存器,从官方给出的存储器映像可以看出各个外设的的基地址,这些基地址在加上相应的偏移量就是我们希望的寄存器的地址,之后修改寄存器的内容就可以,原理就是这样,关键是如何构造好的数据结构对这些寄存器进行操作。下面通过实例介绍三种方法:
实例:让GPIOB0置位,方式推挽输出,思路是1、开GPIOB的时钟 2、设置输出方式 3、端口置位
第一种:直接宏定义精确到各个具体的寄存器。GPIOB开始的地址是0X40010C00,其中端口配置低寄存器(GPIOx_CRL)偏移地址是0x00,这样(0X40010C00+0x00)就是CRL寄存器的地址,使用(long *)(0X40010C00+0x00),将这个地址强制转换成指针类型,在利用*((long *)(0X40010C00+0x00))操作(0X40010C00+0x00)地址里的内容。
#define GPIOB_CRL (*((long *)(0X40010C00+0x00)))
#define RCC_APB2ENR (*((long *)(0x40021000+0x18)))
#define GPIOB_ODR (*((long *)(0X40010C00+0x0C)))
这样就可以像上面的思路操作了。
RCC_APB2ENR|=(1<<3);//开GPIOB的时钟
GPIOB_CRL=3;//设置输出方式
GPIOB_ODR=0XFFFF;//端口置位
这样操作直观,但是需要的宏太多,容易出现问题,稍不留神偏移量写错就前功尽弃了。
第二种:构造结构体,将GPIO的寄存器全部写进结构体,相比上面的方法让编译器帮我们进行计算,减少出错的可能,本来像上面那样体现不出C语言这个工具的强大。首先构造
typedef struct
{
int CRL;
int CRH;
int IDR;
int ODR;
int BSRR;
int BRR;
int LCKR;
} GPIO_TypeDef;
之后
#define GPIOB ((GPIO_TypeDef*)(0X40010C00))
这样就可以用指针的方式操作GPIOB的各个寄存器了,这里的GPIO_TypeDef类型的数据结构保证操作的寄存器全是GPIO的寄存器不会越界,具体的原因是C语言的问题,这里不做过多的解释,以免跑题。下面按照最开始的操作思路进行:
RCC->APB2ENR|=(1<<3);//开GPIOB的时钟
GPIOB->CRL=3;//设置输出方式
GPIOB->ODR=0XFFFF;//端口置位
显然这种方式借助C语言这个工具和编译器帮我们解决了很多的问题。
第三种方法:查看库文件stm32f10x.h有以下的宏定义
#define PERIPH_BASE ((uint32_t)0x40000000)
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)
要知道define定义就是简单的字符串替换,替换之后的结果是
#define GPIOB ((GPIO_TypeDef *) 0x40000000 + 0x10000 + 0x0C00)
可以看出就是第二种方法里面的
#define GPIOB ((GPIO_TypeDef*)(0X40010C00))
所以既然官方已经帮我们做好了我们为什么不用呢。所以直接包含头文件#include “stm32f10x.h” 就可以了。说到这里似乎又回到了起点,这不是还是使用了官方的库函数吗?但是这和#include
使用库函数还是直接操作寄存器更好,以上的例子并没有说明问题,我们看到的只是库函数无外乎是操作寄存器,没有看到的是库函数的函数多级调用,这里不做说明。
最后一句,对于我们使用的人来说一定不要被层层的外包装所迷惑。
上一篇:STM32 GPIO几个寄存器的理解
下一篇:STM32库函数和寄存器操作的思考
推荐阅读
史海拾趣
随着公司的发展,浙江东亚电子不断拓展其产业布局。除了传统的电力电子元件、分流器等产品外,公司还涉足新能源汽车、充电桩、变频器和储能等领域。特别是在新能源汽车和充电桩领域,公司紧跟国家“新基建”发展战略,推出了一系列具有竞争力的产品,为公司带来了新的增长点。
FDI深知客户需求的重要性,因此他们始终将客户服务放在首位。公司建立了一套完善的客户服务体系,从售前咨询、方案设计到售后支持,全程为客户提供专业、贴心的服务。此外,FDI还针对客户的特定需求,提供定制化解决方案。他们能够从概念设计、原型开发到大规模生产,全程参与客户的项目,确保产品能够完全符合客户的期望和要求。这种服务模式赢得了客户的广泛赞誉和信赖。
在光学镜片领域,产品质量是企业的生命线。康奈特深知这一点,因此从原材料采购到生产制造的每一个环节都建立了严格的品控体系。公司引进了先进的检测设备和技术手段,对每一片镜片都进行严格的检测和筛选。这种对质量的执着追求不仅赢得了消费者的信赖和认可,也为公司赢得了良好的口碑和市场份额。
Compensated Devices Inc(简称CDI)最初是一家小型电子元件制造商,专注于生产高精度电阻器。随着科技的飞速发展,传统电阻器已无法满足新兴市场的需求。CDI的创始人李先生敏锐地洞察到这一点,决定投入大量资源进行研发,推出了具有温度补偿和自动校准功能的新型电阻器。这一创新产品迅速获得了市场的认可,CDI也因此逐渐在电子行业中崭露头角。
随着技术的不断进步,AINFO Inc公司不断推出创新产品,满足市场的多样化需求。公司注重产品的质量和性能,通过优化设计和生产工艺,提高了产品的竞争力。同时,公司积极开拓国内外市场,与多家知名企业建立了合作关系,实现了产品的广泛应用。
Astema公司自创立之初,就专注于研发创新的电子技术。公司投入大量资源于研发部门,不断推出具有竞争力的新产品。其中,一款具有高效能、低功耗特点的芯片产品,在市场上获得了巨大成功,为公司带来了可观的收入。这一成功促使Astema在行业内建立了良好的声誉,吸引了更多的客户和合作伙伴。
马万里,赵建明,吴纬国 (电子科技大学 微电子与固体电子学院, 成都 610054) 摘 要:主要针对光刻对准特性,从单项工艺和工艺集成的角度,分析了影响光刻对准的各个主要因素,主要包括对准标记、工艺层、 ...… 查看全部问答∨ |
|
void LcdWriteData(unsigned char data) { CheckBusy(); //忙检查 DDRB=0xff; //数据端口设置为输出 SET_RD; ...… 查看全部问答∨ |
|
求教debug 调试程序出现 has exited with code 0 (0x0). 第一次在开发板上测试就遇到这种奇怪问题... build 已经成功,在PPC2003模拟器上也运行正常,但是接到开发板上就出现问题,程序无法打开。 用网线联调 发现output 内容如下: Load module: /FlashDrv/My_PJtest/My_PJtest-armv4i-IngenicMedia (M ...… 查看全部问答∨ |
|
ST将在9月份在全国10个城市举办STM32的技术研讨会!最新消息 ST将在9月份在全国10个城市举办STM32的技术研讨会,这次研讨会的一个主要目的是对大家在使用STM32过程中的一些疑问进行解答和澄清。目前我们正在准备一些技术方面的文档,为了更广泛的满足大家的要求,在这里我请大家提出一些建议,包括:-你 ...… 查看全部问答∨ |
|