欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

STM32F103VET6学习(1)

程序员文章站 2022-03-06 08:05:26
...

一.前言

我是按照STM32售方光盘中的资料《玩转STM32F10x》(.pdf)来学习的,前面的基本原理看了好几天,因为有点微机原理的底子,所以有些内容看起来还觉得不是特别难。几天后,终于看到了GPIO的这节的LED点亮,我心里想着终于可以有一个上手实践的东西可以做了。谁知道有很多问题一个接一个,下来就逐一说下,给自己看看做个记录也好。

二.问题陈述与对应的解决过程以及衍生的新的问题以及最后的解决

  1. 参考着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,他在固件库里:
STM32F103VET6学习(1)
这个Path里面我主要想要的就是stm32f10x.h这个头文件,这样确保我导入头文件的这句代码是有效地,以防报错说找不到我的头文件。
此外,我把core_cm3.h文件也放在了我的工程文件目录下,之后再次运行,终于!!!见图:

STM32F103VET6学习(1)
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是我自己建立的头文件,用于存放寄存器映射的代码,暂时是空的,没用。
STM32F103VET6学习(1)
这次也没什么技术性的问题,但我就是做个记录,有人可能会用到吧,毕竟每次有问题去百度时,对于一个问题,百度里网友给出n种情况与解法,但我觉得自己的总是第n+1种问题,自己时常莫名其妙的就解决了。
所以做个记录,本次,完结!

相关标签: STM32学习 stm32