STM32F103VET6学习(1)
一.前言
我是按照STM32售方光盘中的资料《玩转STM32F10x》(.pdf)来学习的,前面的基本原理看了好几天,因为有点微机原理的底子,所以有些内容看起来还觉得不是特别难。几天后,终于看到了GPIO的这节的LED点亮,我心里想着终于可以有一个上手实践的东西可以做了。谁知道有很多问题一个接一个,下来就逐一说下,给自己看看做个记录也好。
二.问题陈述与对应的解决过程以及衍生的新的问题以及最后的解决
- 参考着pdf,我写的第一个程序如下:
#include"stm32f10x.h"
int main(void)
{
RCC_APB2ENR |= (1<<3); //开启时钟
GPIOB_CRL &= ~( 0X0F << (4*0)); //清空控制PB0的端口位
GPIOB_CRL |= (1<<4*0);
GPIOB_ODR &= ~(1<<0);
while(1);
}
//骗过编译器有这样一个函数,不报错
void SystemInit(void)
{
}
这就是第一个程序,运行后报错:缺少core_cm3.h文件,于是我找到这个文件把它和与它在同一目录下的core_cm3.c文件也一同copy到了报错的目录下,重新运行,这个错倒是没了,不过又出来了三个错,就是上方代码中的:GPIOB_CRL、GPIOB_ODR和RCC_APB2ENR 都是undefined,没定义。很离谱啊,我调用的头文件中有这几个的定义啊(但是我没有去看头文件里面的代码,偷懒了)。于是我百度,直到刚才前几个小时,我就想:既然它说我没定义,按我就给它定义呗!
2.定义后的代码添加了如下宏定义内容:
#define PERIPH_BASE ((unsigned int)0x40000000)
#define APB2PERIPH_BASE (PERIPH_BASE+0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define GPIOB_BASE (APB2PERIPH_BASE+0X0C00)
#define GPIOB_CRL *(unsigned int*)(GPIOB_BASE + 0X00)
#define GPIOB_CRH *(unsigned int*)(GPIOB_BASE + 0X04)
#define GPIOB_ODR *(unsigned int*)(GPIOB_BASE + 0X0C)
#define RCC_BASE *(unsigned int*)(AHBPERIPH_BASE + 0X1000)
#define RCC_APB2ENR *(unsigned int*)(RCC_BASE + 0X18)
让我高兴但是也迷乱的就是在写前四行基址定义的时候,有几个警告,说的是这几个宏已经定义过了(这里画个重点,后面还要提起)。于是我就写了后面的内容,好了,刚才没定义的错给解决了,然后又出来了一个错:__main ,这个文件/向导找不到或者冲突。百度之后,很多类似问题都有ADS这个关键词,将它卸载,环境变量删除后就好了。我想来想去,觉得ADS很熟悉,最后终于想起这学期学了个嵌入式操作系统的皮毛,但是老师当时让安装了ADS这个软件,想了下,以后也不会再去用它了,毕竟也比较老了,就果断找到其目录删除并卸载,然后再把环境变量删除。这里我肯定我是没有删错的,因为当时我建文件夹的名字我都是有注意的,所以哪个文件在哪里我都很清楚,但是…
3.这下子刚才的错没有了,但是!又出来了30个Errors!我想着应该是ADS目录下的有些文件被keil5使用了,但是我真的不想再去找他并恢复了,因为ADS的环境变量我刚删了,所以重来吧,我觉得缺少的配置在重新安装过程中会自己完成的。
于是我毅然重来,把Keil5卸载重装了一次,然后**,设置Debug和各项配置,添加pack,一套走下来,十来分钟就完了。
将刚才的程序复制(这就要提到刚才说的宏的问题了),我没写那几行基址定义的宏,于是它又报错了,后面的几个宏涉及的宏我没有定义,来来回回操作了一会儿,我决定还是把它定义下吧。另外,我在“魔术棒”选项卡里进行了如下设置,添加了这个Include Path,他在固件库里:
这个Path里面我主要想要的就是stm32f10x.h这个头文件,这样确保我导入头文件的这句代码是有效地,以防报错说找不到我的头文件。
此外,我把core_cm3.h文件也放在了我的工程文件目录下,之后再次运行,终于!!!见图:
4.虽然我看pdf后面讲到固件库主要还是要自己来写的,因为纯依靠寄存器是容易出错且不好控制的。但是解决了这个bug我还是很开心的,至此在stm32上遇到的第一个非技术类的问题得到了解决!在下面附上这次的全部代码,其功能是点亮一个LED,具体为推挽式输出,速率为10MHz,对应的为PB0口的设置(这也是代码里都写得GPIOB的原因)
#include"stm32f10x.h"
#define PERIPH_BASE ((unsigned int)0x40000000)
#define APB2PERIPH_BASE (PERIPH_BASE+0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define GPIOB_BASE (APB2PERIPH_BASE+0X0C00)
//定义GPIO寄存器地址并强制转换为指针
#define GPIOB_CRL *(unsigned int*)(GPIOB_BASE + 0X00)
#define GPIOB_CRH *(unsigned int*)(GPIOB_BASE + 0X04)
#define GPIOB_ODR *(unsigned int*)(GPIOB_BASE + 0X0C)
//RCC外设基地址
#define RCC_BASE *(unsigned int*)(AHBPERIPH_BASE + 0X1000)
#define RCC_APB2ENR *(unsigned int*)(RCC_BASE + 0X18)
int main(void)
{
RCC_APB2ENR |= (1<<3);
GPIOB_CRL &= ~( 0X0F << (4*0));
GPIOB_CRL |= (1<<4*0);
GPIOB_ODR &= ~(1<<0);
while(1);
}
void SystemInit(void)
{
}
该工程下的文件结构如下,其中startup_stm32f10x_hd.s是用汇编语言写的“启动文件”,即执行代码是先从这里开始,之后才进入C的世界执行自己写的main.c中的代码。stm32f10x.h是我自己建立的头文件,用于存放寄存器映射的代码,暂时是空的,没用。
这次也没什么技术性的问题,但我就是做个记录,有人可能会用到吧,毕竟每次有问题去百度时,对于一个问题,百度里网友给出n种情况与解法,但我觉得自己的总是第n+1种问题,自己时常莫名其妙的就解决了。
所以做个记录,本次,完结!
上一篇: 前端SVG样式颜色等开发注意事项
下一篇: STM32F429 初试TouchGFX
推荐阅读
-
destoon实现调用自增数字从1开始的方法_PHP
-
判断t1树是否有与t2树拓扑结构完全相同的子树
-
贪心算法学习(喷水装置)
-
S1 S2 S3 S4 S5
-
html报表满足条件不同,每行显示的数据有1个不同
-
photoshop学习视频 PHP学习之PHP运算符
-
Thinkphp改变分页get,如/p/1.html改成/page/1.html
-
关于QT程序中出现collect2: ld returned 1 exit status
-
[zz]discuzX1核心资料class_core.php分析
-
pgjdbc: server-encoding として ISO-8859-1 を自動検出しました、メッセージが読めない場合はデータベースログおよび host, port, dbname, user,