STM32的操作过程,寄存器配置与调试过程

2019-12-03来源: eefocus关键字:STM32  操作过程  寄存器配置  调试过程

很多学习stm32的,为什么学习stm32他也不知道,我们所知道的就是各个论坛讨论stm32的很多,而我们很多人之所以学习stm32是很多的淘宝卖家做了大量的图片文字宣传,于是我们经不住诱惑就买了板子,然后我们就开始了我们的学习之旅。


在淘宝卖家的眼里有着齐全的入门资料是板子的最大的卖点,于是当我们拿到开发板的时候,我们感觉我们永远不能和别人说自己熟悉stm32,因为脱离了网络的资料我们什么都做不了,这是我们最害怕的事情。


今天我就就像在这里记录下自己一无所有建立stm32工程的过程,是我自己的一个探索过程,同时也是大家互相交流的过程。

第一步:当然是新建一个工程我把它命名为small(这个随便你,青菜萝卜各有所爱……)

 

第二部:就是选择芯片的型号了,这个按照每个人手上的板子的不同就选择不同的芯片型号。

 

 

选择完了之后按确认,然后会出来一个对话框,是问你要不要添加启动文件的,这个简单我们都是白手起家了,别人好不容易送你点东西我们当然照单全收,直接点是啊!哈哈。。。。。

 

点完是后我们的工程就是差不多建立好了,大家可以看到里面就一个代码文件,是以.s结尾的,是一个启动文件里面的代码全是汇编的,看了有点晕死。。。。,以后再说吧这个。。。。

 

要不我们编译了看看结果?

 

一串鸟文的错误,看不怎么懂,但是好像是说什么没有main函数。想想也是啊,自己确实没写main函数,要不我们自己建立一个.c文件,然后写一个main函数?说做就做。。。。。


直接点击file下面的新建图标,然后写一个名字保存,注意别忘保存好之后在工程里面“add files to group”,然后我们再自己写一个空的main函数,大家看看我做的对不对?

这下可以编译了吧?

编译有警告说什么main函数的返回值必须是int。。。。不知道为什么?

百度看了下好像是编译器和c语言标准规范的问题,没办法那就修改下main函数的返回值吧,把前面的main前面的void变成int就好了。


编译通过了。。。

要不我们接下来设置工程属性看看?这个是很多教程中有的,我不想多少,大家自己找找吧。。。。

 

你看都可以仿真,哈哈那就说明系统运行起来了。。。。但是我们什么都看不到,接下来我们的任务就是想办法点亮一个led灯。


首先我们要控制灯的话就要操作寄存器,还记得我们在51里面要操作P0口吗?是用P0=0x00,这里面简单的说下51里面操作IO口的原理,我们看到这里有一个P0,这个P0是哪里来的?显然不像是int一样是是c语言本身自带的,也不是某一个变量是我们自己定的,其实这个是在reg52.h里面定义的,有图有真相。

 

可以看到在我们一直使用reg52.h里面他做了这样一件事情,就是把我们的真实物理地址是0x90的这个P1寄存器和P1这个代名词相互联系了,其实P1只是一个代名词,假如我在reg52.h里面修改 把sfr P1 = 0x90;修改为sfr XX = 0x90;这样也是可以用的,只不过下一次你要对P1口进行操作的时候要写XX=0x00;了,所以为了好记我们就把名字取成P1,现在我们知道了51的原理,我们可以依葫芦画瓢来操作stm32的GPIO,先不管我们要操作什么寄存器,我们要接解决的第一个问题怎么使用c语言操作单片机中知道绝对物理地址的寄存器,比如我们通过查资料RM0008的179页知道了关于IO操作的一个寄存器GPIOA_CRL的绝对地址是0x40010800+0x00(其中0x40010800是起始地址,0x00是偏移地址),接下来我们怎么操作他呢?用 sfr?好像sfr是51汇编特有的指令,在arm里面没有。。。这时候我们是否想到c语言的一个和地址紧密相关的内容----指针,我们在上课的时候知道指针的本质就是地址,这样我们是否可以通过它来把实际的物理地址和c语言变量建立关系呢?首先我们要把绝地地址变为指针变量 ,肯定是强制类型转换了(int*(0x40010800+0x00))通过这一步我们已经有一个int类型的指针,这个指针指向的地址就是我们GPIOA_CRL的绝对地址(0x40010800+0x00),有了指针之后我们要取变量,那么很简单只要一个简单的*取变量运算符就可以了(int*(0x40010800+0x00)),这下变量有了那么我们是不是需要给变量取一个名字啊?


那就这样#define GPIOA_CRL *((int*)(0x40010800+0x00)) 好了完成了我们终于可以再c语言的环境中操作我们的寄存器了,接下来我们只要给GPIOA_CRL 这个变量赋值就是我们在给GPIOA_CRL 这个寄存器赋值,先休息下再说。。。。。


这篇文章其实我是一边写代码做测试一边写的,就在上面我想要控制IO的时候花了好长的时间,就是因为自己的不仔细吧!犯了几个小错误。先看我的最终代码。

代码非常的简单,但是为了这几行代码花了我好久的时间,我已经在代码后面写了注释了,具体的怎么来的让我婉婉道来,首先是上面那几行的define的机构我在上面已经介绍过了,具体的地址是怎么知道的?下面我来简单的说下,在stm32的

RM0008 
Reference manual 
STM32F101xx, STM32F102xx, STM32F103xx, STM32F105xx 
and STM32F107xx advanced ARM-based 32-bit MCUs

这个开发文档中的44页内存映射表,如下图

 

我截图的只是上半部分,还有下半部分,在下半部分我们可以看到

从这里可以看到和GPIOA相关的寄存器的起始地址是0x40010400所以代码中的一开始的基址是这个,然后我们需要知道不同的寄存器的偏移地址,这个是在后面的跳转的链接可以看到的,跳转到179页,偏移地址的表格

这样的话上面的几个define的计算也就水落石出了。


这里简单的说下自己当时犯的一个错误。我一开始写的#define GPIOA_CRL *((int*)0x40010800+0x00) 是这样的,调试后死活不是我想要的工作效果,后来花了好大的力气才想起来原来是宏定义的括号的问题,大家仔细比对下我在代码中的写的和我上面的写法,发现什么端倪没?#define GPIOA_CRL *((int*)(0x40010800+0x00)) 看到红色的括号没?就是因为一个小小的括号耽误了很长时间。


花了这么长的时间我们终于可以操作IO口了,那怎么操作呢?在学过51的人的眼里那是很简单的,就是直接把我们要IO口输出的值送到数据寄存器中不就好了,但是毕竟他是高级的stm32,所以要复杂点,首先我们要开启GPIOA的端口时钟,这也许大家会疑惑了,怎么还和时钟有关系了。。。。还是看资料吧!

可以看到GPIOA是挂载在AHB2总线上面的,他们都有自己的时钟信号的控制端,这是由stm32的机构决定的,我想之所以这样做,一方面可以降低系统功耗,让工作的模块的时钟使能,不工作的就不使能,其实这里的时钟信号就好比是模块的心脏一样,只有先让他工作了我们才可以去对他进行操作,这就是代码上RCC_APB2ENR=0x00000004;//开启GPIOA的端口时钟这一句的作用,我尝试过,假如去掉这一句话的话,即使我后面对寄存器赋值了,也是没有作用的。所以这一句很重要,而且与下面的顺序是不好交换的。接下来就是设置GPIO的工作方式什么输入输出 模式之类的,对于只学过51的人来说有点新鲜感觉,如果学过其他高级点单片机的 估计已经习以为常了,就那么回事,具体的寄存器的每一位我就多说了,直接看stm32f10XXXX参考手册的113页上满写的很清楚了。

这里再顺便解释下下我看到的一个现象,先看文档

从这里面我们知道任何IO在复位之后都处于浮空输入状态,这是PDF上说的通过我的代码大家看到我只是改变GPIOA0这位的状态所以其他IO口应该还是浮空输入的模式,但是实际上是的吗?


看仿真截图:

大家可以看到其他几个口还是听话的就是PA12 PA13 PA14 PA15不怎么对劲,怎么回事呢?一开始我也疑惑,后来突然想起来了,这不是我们仿真用的jtag口吗?这样的话就对了,于是为了验证我的想法,我查看jtag用的其他IO口的情况,都不是默认的浮空输入模式,这样的话就应该是这个原因了。(提醒大家一下以后设计硬件的时候尽量避免使用jtag口,如果实在避免不了的话在设计程序的时候就要注意关闭jtag模式释放那几个IO口,在此做一个友情提醒因为被坑过几次。。。)

关键字:STM32  操作过程  寄存器配置  调试过程 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic481823.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32-modbus rtu 之从机程序
下一篇:STM32学习之路之入门篇

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM8S存储器的读写操作
/************************************************************************************************************************************ Name    : STM8S存储器的读写操作* Author  : MingMing* Release : 2014/1/2* Update  : 2014/1/2* E-mail  : clint.wang@foxmail.com
发表于 2019-12-05
stm8l051 halt之后外部中断唤醒问题
最近用到stm8l051 halt,在halt之后开启了外部中断,有时灵,有时不灵,设置下降沿触发,但是按键(低有效)放开了才会从HALT退出,最后发现在进去外部中断的时候一直在外部中断里面不退出。在外部中断程序里面把端口的外部中断和端口使能的外部中断功能关闭,问题解决,可以在下降沿从halt退出。1、开启halt,其他代码省略,只贴halt部分:    /* 禁止TIM3 */    TIM3->SR1 = (uint8_t)(~(uint8_t)TIM3_IT_Update);    CLK_PeripheralClockConfig
发表于 2019-12-05
STM8L052低功耗模式
Stm8L系列单片机的低功耗有五种模式:§ wait模式§ Lowpower run模式§ Lowpower wait模式§ Active-haltwith full RTC模式§ Halt模式最低功耗的就是就是halt模式。这里也主要总结一下如何进入halt模式,进入以后可以通过什么方式唤醒,以及有很多客户会关心的如何自动唤醒。Halt模式进入很简单,执行一条halt指令,调用库函数也就是halt()就行了。但是进入前要注意把所有的中断挂起标志给清除掉。要是不清零又恰巧有中断标志的时候进入该模式也会被立马唤醒。进入这种模式,所有的外设全都关闭了,所有时钟关闭。这时候它自己是醒不过来的,只能靠掐人中(给个外部中断)或者重新复活
发表于 2019-12-05
解决STM8类型单片机空间太小,使用不了printf串口打印问题
概述:在使用STM8L101F3这款单片机时,由于它只有8K的flash,空间非常小,只要调用C库函数printf编译后整个文件很大,直接程序溢出。这也就意味着我们实现printf串口打印调试就没办法进行。既然使用不了库函数,那么我们就可以自己动手封装类似printf的函数,这样我们就可以实现数据串口打印啦。这里就直接放上我的STM8L101F3的部分源码了,希望可以给你一些参考。源码:#include "stdarg.h"#include "stm8l10x.h" void USART_Config(void){    /*Set the USART RX
发表于 2019-12-04
解决STM8类型单片机空间太小,使用不了printf串口打印问题
基于STM8的IIC协议--协议篇
4.3.8代码示例。3.6 数据有效性  I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。3.7 I2C通信总过程 4. 例程4.1 编译环境:  我的编译环境是IAR,这款软件是现在STM8的主流平台,比较推荐。不过我打算等到STCubeMX更新出比较方便的版本后再去使用Keil5,因为我在用STM32的时候就是利用Keil5,的确很方便,你们也可以学着用一下。4.2 主芯片:  我的主芯片是STM8S系列中的103,其中STM8S的003、005、和103、105,配置一样(外设和CPU频率,FLASH),在代码相同的
发表于 2019-12-04
基于STM8的IIC协议--协议篇
基于STM8的ADC读取---STM8-第四章
和连续转换的扫描模式具有上限和下限门槛的模拟看门狗模拟看门狗时间发生可产生中断----------------------------------------------------------------------------------------------------------------------------------3. 例程3.1 编译环境  我的编译环境是IAR,这款软件是现在STM8的主流平台,比较推荐。不过我打算等到STCubeMX更新出比较方便的版本后再去使用Keil5,因为我在用STM32的时候就是利用Keil5,的确很方便,你们也可以学着用一下。3.2 主芯片  我的主芯片是STM8S系列中的103
发表于 2019-12-04
基于STM8的ADC读取---STM8-第四章
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved