江协科技STM32学习笔记(第01章 STM32简介及开发环境搭建)

第01章 STM32简介及开发环境搭建

01 STM32简介

1.1 STM32F103C8T6

系列:主流系列STM32F1

内核:ARM Cortex-M3

主频:72MHz

RAM:20KSRAM

ROM:64KFlash

供电:2.0~3.6V(标准3.3V

51单片机是5V供电。USB输出的电压也是5V供电,不能直接给STM32供电,如果是5V电压,需要加一个稳压芯片,把电压降到3.3V,再给STM32供电。

封装:LQFP48,如下图所示。

1.2 STM32F1系列片上资源/外设 

英文缩写

名称

英文缩写

名称

NVIC

嵌套向量中断控制器

CAN

CAN通信

SysTick

系统滴答定时器

USB

USB通信

RCC

复位和时钟控制

RTC

实时时钟

GPIO

通用IO

CRC

CRC校验

AFIO

复用IO

PWR

电源控制

EXTI

外部中断

BKP

备份寄存器

TIM

定时器

IWDG

独立看门狗

ADC

模数转换器

WWDG

窗口看门狗

DMA

直接内存访问

DAC

数模转换器

USART

同步/异步串口通信

SDIO

SD卡接口

I2C

I2C通信

FSMC

可变静态存储控制器

SPI

SPI通信

USB OTG

USB主机接口

NVIC/SysTick是位于Cortex-M3内核里面的外设,剩下的都是内核外的外设。

NVIC(嵌套向量中断控制器):内核里面用于管理中断的设备,比如配置中断优先级这些东西。

SysTick(系统滴答定时器):内核里面的一个定时器,主要用来给操作系统提供定时服务的。STM32是可以加入操作系统的,比如FreeRTOS、UCOS等。如果使用了这些操作系统,就需要SysTick提供定时来进行任务切换的功能。可以用这个定时器来完成Delay函数的功能。

RCC(复位和时钟控制):对系统的时钟进行配置,使能各模块的时钟。在STM32中,其它的外设在上电的情况下默认是没有时钟的,不给时钟的情况下,操作外设是无效的,外设也不会工作,这样的目的是降低功耗。所以在操作外设之前,必须要先使能它的时钟,这就需要我们用RCC来完成时钟的使能。

GPIO(通用IO口):通用IO口,可以用GPIO来点灯,读取按键等。

AFIO(复用IO口):完成复用端口的重定义,还有中断端口的配置。

EXTI(外部中断):外部中断,配置好外部中断后,当引脚有电平变化时,就可以触发中断,让CPU来处理任务。

TIM(定时器):也是STM32最常用、功能最多的外设;分为高级定时器、通用定时器、基本定时器三种类型,其中高级定时器最为复杂,常用的是通用定时器,这个定时器不仅可以完成定时中断的任务,还可以完成测频率、生成PWM波形、配置成专用的编码器接口等功能,像PWM波形,就是电机驱动、舵机驱动最基本的要求。

ADC(模数转换器):模数转换器,STM32内置了12位的AD转换器,可以直接读取IO口的模拟电压值,无需外部连接AD芯片,使用非常方便。

DMA(直接内存访问):可以帮助CPU完成搬运大量数据这样的繁杂任务。

USART(同步/异步串口通信):同步或异步串口,平常用的UART是异步串口的意思,USART即支持同步串口,也支持异步串口,当然实际使用还是异步串口比较多。

I2C和SPI:非常常用的两种通信协议,STM32内置了它们的控制器,可以用硬件来输出时序波形,使用起来更高效,当然用通用IO口来模拟时序波形也是没有问题的。

CAN和USB:也是通信协议,CAN通信一般用于汽车领域,生活中到处都是USB设备,利用STM32的USB外设,可以做模拟鼠标、模拟U盘等设备。

RTC(实时时钟):在STM32内部完成年月日、时分秒的计时功能,而且可以接外部备用电池,即使掉电也能正常进行。

CRC(CRC校验):数据校验方式,用于判断数据的正确性,有了在这个外设的支持,进行CRC校验会更加方便一些。

PWR(电源控制):可以让芯片进入睡眠模式等状态,来达到省电的目的。

BKP(备份寄存器):这是一段存储器,当系统掉电时,仍可由备用电池保持数据,这个根据需要,可以完成一些特殊功能。

IWDG和WWDG(独立看门狗和窗口看门狗):当单片机因为电磁干扰死机或者程序设计不合理出现死循环时,看门狗可以及时复位芯片,保证系统的稳定性。

DAC(数模转换器):可以在IO直接输出模拟电压,是ADC模数转换的逆过程。

SDIO(SD卡接口):可以用来读取SD卡。

FSMC(可变静态存储控制器):可以用于扩展内存或者配置成其他总线协议,用于某些硬件的操作。

USB OTG(USB主机接口):用OTG功能,可以让STM32作为USB主机去读取其他USB设备。

需要注意的是:以上是STM32F1整个系列的所有外设,并非所有型号都拥有全部的外设。比如STM32F103C8T6没有后面四个外设。具体芯片有哪些外设,需要查看相应数据手册。

1.3 芯片命名规则

1.4 芯片系统结构

可以分为以下四个部分:

(1)Cortex-M3内核引出了三条总线[ICode(指令总线)、DCode(数据总线)、System(系统总线)]。

(2)ICode(指令总线)和DCode(数据总线)主要用来连接Flash闪存,Flash里面存储的是我们编写的程序,ICode(指令总线)就是用来加载程序指令的;DCode数据总线就是用来加载数据的,比如常量和调试数据这些。

(3)System(系统总线)连到其它东西上面,比如SRAM,用于存储程序运行时的变量数据;还有FSMC,本课程不会用到;AHB系统总线,用于挂载主要的外设,AHB指的是先进高性能总线,挂载的一般是最基本的或者性能比较高的外设,比如复位和时钟控制这些最基本的电路,还有SDIO也是挂载在AHB上的;再后来是两个桥接,接到APB1和APB2两个外设总线上,这个APB的意思是先进外设总线,用于连接一般的外设;因为AHB和APB的总线协议、总线速度、还有数据传送格式的差异,所以中间需要加两个桥接,来完成数据的转换和缓存;AHB的整体性能比APB高一些,其中APB2的性能又比APB1高一些,APB2一般和AHB同频率,都是72MHz,APB1一般是36MHz,所以APB2连接的都是一般外设中稍微重要的部分,比如GPIO端口,还有一些外设的1号选手等(比如USART1、SPI1、TIM1、TIM8(TIM1和TIM8一样,也是高级定时器,所以也是重要的外设),还有ADC、EXTI、AFIO,也是接在APB2上面的),其它的像2、3、4、5号的外设,还有DAC、PWR、BKP等,这些次要一点的外设,都会分配到APB1上去。在使用的时候,个人一般感觉不到APB2和APB1的性能差异, 只需要知道这个外设是挂载到哪个总线上既可以。

(4)DMA可以当作内核CPU的小秘书,比如一些大量的数据搬运的活,让CPU来干太浪费时间。比如一个外设ADC模数转换,这个模数转换可以配置成连续模式,比如1ms转换一次,转换完的数据必须得转运出来,否则数据就会被覆盖丢失。如果直接让CPU来干这个工作,那么PCU每过1ms就得来转运一下数据,会费时费力,影响CPU的正常工作。但这个任务就是简单的数据搬运,没必要让CPU做,于是DMA就出现了,主要就是干数据搬运这样简单而反复要干的工作,那DMA通过DMA总线连接到总线矩阵上,它可以拥有和CPU总线一样的总线控制权,用于访问这些外设小弟,当需要DMA搬运数据时,外设小弟就会通过请求线发送DMA请求,然后DMA就会获得总线控制权,访问并转运数据,整个过程不需要CPU的参与,省下了CPU的时间来干其它的事情,这就是DMA的用途。

1.5 芯片引脚定义

下图标红色是电源相关的引脚,标蓝色的是最小系统相关的引脚,标绿色的是IO口、功能口这些引脚。

类型:S代表电源、I代表输入、O代表输出、IO代表输入输出 。

I/O口电平:代表IO口所能容忍的电压,有FT的,代表它能容忍5V的电压,没有FT的,只能容忍3.3V的电压。如果没有FT需要接5V的电平,就需要加装电平转换电路了。

主功能:上电后默认的功能,一般和引脚名称相同,如果不同的话,引脚的实际功能是主功能而不是引脚名称的功能。

默认复用功能:IO口上同时连接的外设功能引脚,这个配置IO口的时候可以选择是通用IO口还是复用功能。

重定义功能:作用是如果有两个功能同时复用在了一个IO口上,并且确实需要用到这两个功能,可以把其中一个复用功能映射到其它端口上,当然前提是重定义功能的表里有对应的端口。

推荐优先使用加粗的IO口,没有加粗的IO口可能需要配置或者兼具其它功能,使用时需要注意一下。

引脚定义:

1号引脚VBAT:备用电池供电的引脚,在这个引脚可以接一个3V的电池,当系统电源断电时,备用电池可以给内部得RTC时钟和备份寄存器提供电源。

2号引脚PC13-TAMPER-RTC(IO口/侵入检测/RTC):IO口可以根据程序输出或读取高低电平,是最基本也是最常用的功能;侵入检测可以用来做安全保障的功能(比如产品安全性比较高,可以在外壳加一些防拆的触点,然后街上电路到这个引脚,若有人强行拆开设备,那触点断开,这个引脚的电平变化,就会触发STM32的侵入信号,然后就会清空数据来保证安全);RTC引脚可以用来输出RTC校准时钟、STC闹钟脉冲或者秒脉冲。

3号4号引脚PC14-OSC32_IN和PC15-OSC32_OUT:IO口或者32.768KHz的RTC晶振。

5号6号引脚OSC_IN和OSC_OUT:接系统的主晶振,一般是8MHz的,然后芯片内有锁相环电路,可以对这个8MHz的频率进行倍频,最终产生72MHz的频率,作为系统的主时钟。

7号引脚NRST(系统复位引脚):N代表它是低电平复位的。

8号9号引脚VSSA和VDDA:内部模拟部分的电源,比如ADC、RC震荡器等,VSS是负极,接GND;VDD是正极,接3.3V。

10号-19号引脚:IO口,其中PA0兼具了WKUP的功能,这个可以用于唤醒处于待机模式的STM32。

20号引脚:IO口或者BOOT1引脚,BOOT引脚是用来配置启动模式的。

21号-22号引脚:IO口。

21号-22号引脚VSS_1和VDD_1:系统的主电源口,VSS是负极,VDD是正极。

35号-36号引脚VSS_2和VDD_2:系统的主电源口,VSS是负极,VDD是正极。

47号-48号引脚VSS_3和VDD_3:系统的主电源口,VSS是负极,VDD是正极。

STM32采用了分区供电的方式,所以供电口比较多,在使用时,把VSS都接GND,VDD都接3.3V即可。

25号-33号引脚:IO口。

34号和37号-40引脚:IO口或者调试端口,默认的主功能是调试端口,调试端口就是用来调试和下载程序的,这款STM32支持SWD和JTAG两种调试方式;SWD需要两根线,分别是SWIDO和SWCLK;JTAG需要5根线,分别是JTMS、JTCK、JTDI、JTDO、NJTRST。教程采用STLINK来下载调试程序,STLINK用的是SWD的方式,所以只需要占用PA13和PA14这两个端口,在使用SWD的调试方式时,剩下的PA15、PB3、PB4可以切换位普通的IO口来使用,但要在程序中进行配置,不配置的话默认是不会用作IO口的。

41号-43号引脚和45号-46号引脚:IO口。

44号引脚BOOT0:和BOOT1一样,是用来做启动配置的。

1.6 启动配置

这个启动配置的作用就是指定程序开始运行的位置,一般情况下,程序都是在Flash程序存储器开始执行,但是在某些情况下,也可以让程序在别的地方开始执行,用以完成特殊的功能。

BOOT0接0,BOOT1接1或者0时:采用主闪存存储器启动模式;

BOOT0接1,BOOT1接0时:采用系统存储器启动模式:

这个模式就是用来做串口下载用的,这个系统存储器寸的就是STM32中的一段BootLoader程序,BootLoader程序的作用就是接收串口的数据,然后刷新到主闪存中,这样就可以使用串口下载程序了,一般我们需要串口下载程序的时候会配置到这个模式上。

什么时候需要用到串口下载呢?34号和37号-40引脚,如果在程序中把这5各端口全部配置成IO口,那么这个芯片就没有调试端口了,也就不能下载程序了,所以配置端口的时候需要注意。

如果想使用串口下载,就需要配置BOOT1为0,BOOT0为1;如果没有STLINK,也没有JLINK,那就可以使用串口来进行下载程序。

BOOT0接1,BOOT1接1时:采用内置SRAM启动模式:

主要用来进行程序调试,现阶段使用比较少。

BOOT引脚的值是在上电复位后的一瞬间有效的,之后就随便了。BOOT1/和PB2是在同一个引脚上的,也就是在上电的瞬间是BOOT1的功能,当第4个时钟过后,就是PB2的功能。

根据引脚定义表。如果想要STM32正常工作,首先就需要把电源部分和最小系统部分的电路连接好,也就是表中标红色和蓝色部分。

1.7 STM32最小系统电路

 一般来说,单片机只有一个芯片是无法工作的,需要为它连接最基本的电路。这些最基本的电路就叫做最小系统电路。

分区供电的主电源和模拟部分电源都接了供电引脚。VSS都连接了GND,VDD都连接了3V3,也就是3.3V。在3.3V和GND之间,一般会连接一个滤波电容,这个电容可以把保证供电电压的稳定,我们在设计电路的时候,一般只要遇到供电,都会习惯的加上几个滤波电容。

VBAT是接备用电池的,如果需要接备用电池,可以选择一个3V的纽扣电池,正极接VBAT,负极接GND就行了。备用电池是给RTC和备份寄存器服务的,如果不需要这些功能,就不用接备用电池。那这个VBAT直接接3.3V即可,或者悬空也是没问题的。

晶振电路:

接了一个8MHz的主时钟晶振,STM32的主晶振一般都是8MHz,8MHz经过内部锁相环倍频,得到72MHz的主频,这个晶振的两根引脚分别通过两个网络标号接到STM32的5、6号引脚;另外还需要接两个20pF的电容,作为启震电容,电容的另一端接地即可,这就是晶振电路,如果需要RTC功能的话,还需要再接一个32.768KHz的晶振,电路和在这个一样,接在3、4号引脚。

这个OSC32就是32.768KHz晶振的意思,为什么要用32.768KHz,因为32768是2的15次方,内部RTC电路经过2的15次方分频,就可以生成1s的时间信号了。

复位电路:

一个10K的电阻和一个0.1uF的电容组成的,用来给单片机提供复位信号,中间的NRST接在STM32的7号引脚,NRST是低电平复位的,当这个复位电路在上电的瞬间,电容是没有电的,电源通过电阻向电容充电,并且此时电容呈现的是短路状态,当电容逐渐充满电后,电容就相当于断路,此时NRST就会被R1上拉为高电平,那上电瞬间的波形就是先低电平,然后逐渐高电平,这个低电平就可以提供STM32的上电复位信号,让然电容充电是非常快的,所以在我们看来单片机在上电的一瞬间就复位了,这就是复位电路的作用;电容的左边还并联了一个按键,可以提供一个手动复位的功能,当我们按下按键时,电容被放电,并且NRST引脚也通过按键被直接接地了,这就相当于通过手动产生了低电平复位信号,按键松手后,NRST又回归高电平,此时单片机就从复位状态转换为工作状态,平时我们也可以见到这种复位按键,一般在设备上有个小孔,当设备死机并且还不方便断电重启时,我们使用针戳一下小孔里的按键,这样就会使设备复位了,这就是手动复位的功能,按下按键,程序就从头开始运行的意思。

启动配置电路:

H1相当于开干的作用,拨动这个开关,就可以让BOOT引脚选择接3.3V还是GND了。

下载端口电路:

使用STLINK下载程序的话,需要把SWDIO和SWCLK这两个引脚印出来方便接线,另外再把3.3V和GND引出来,这个GND是必须引出来的,3.3V如果板子自己有供电的话,可以不引,不过建议都引出来,方便一些。

02 软件安装

2.1 Keil5 MDK安装

略,微信公众号上破解版很多。

2.2 安装器件支持包

新建一个工程。

如果电脑上安装时是C51和MDK共存的情况,想要切换C51, 在下拉列表选择Legacy Device即可切换。

2.2.1 离线安装

 找到我们需要安装的相应芯片支持包,双击进入安装程序,会默认选中keil安装目录,点击next,安装完后Finish。

2.2.2 在线安装

2.2.3 keil软件注册

(1)以管理员身份运行keil软件

(2)

(3)以管理员身份运行破解工具,注意关闭杀毒软件

(4)

出现以下窗口表示没有以管理员身份运行。 

2.3 安装STLINK驱动

(1)将STLINK查到电脑上,打开设备管理器

(2) 安装驱动

2.4 安装USB转串口驱动

(1)将CH340插到电脑上

(2)安装驱动 

03 新建工程 

目前STM32的开发方式主要有基于寄存器的方式基于标准库也就是库函数的方式基于HAL库的方式

(1)基于寄存器的方式与51单片机开发方式一样,是用程序直接配置寄存器,来达到我们想要的功能,这种方式最底层、最直接、效率会更高一些。但是由于STM32结构复杂、寄存器太多,所以基于寄存器的方式目前是不推荐的。

(2)基于库函数的方式是使用ST官方提供的封装好的函数,通过调用这些函数来间接的配置寄存器。由于ST对寄存器封装的比较好,所以这种方式既能满足对寄存器的配置,对开发人员比较友好,有利于提高开发效率,本课程就是使用库函数开发方式

(3)基于HAL库的方式可以用图形化界面快速配置STM32,比较适合快速上手STM32的情况,但是这种方式隐藏了底层逻辑,如果对STM32不熟悉,基本只能停留在很浅的水平。建议学过标准准库以后,了解一下这种方式。

使用固件库的方式需要提前准备好固件库的资料。库函数文件夹目录如下:

Libraries:库函数的文件;

Project:官方提供的工程示例和模板 ;

Utilities:STM32官方评估板的相关例程,官方用STM32做的一个小电路板,用来评测STM32的,这个文件夹里面存放的就是这个小电路板的测评程序;

Release_Notes.html:库函数的发布文档,里面有一些版本说明;

stm32f10x_stdperiph_lib_um.chm:库函数的使用手册,使用手册里有教怎么使用这个库函数。

3.1 新建基于标准库的工程

3.1.1 新建工程

(1)先建一个存放工程的文件夹

(2)新建工程:

选择器件型号:

 下图暂时不用,关闭。

工程创建完毕,如下图所示:

3.1.2 添加工程所需要的必要文件
3.1.2.1 添加STM32的启动文件

复制上图启动文件, 在工程文件夹下新建一个“Start”文件夹,将启动文件拷贝进去。

 3.1.2.2 添加STM32外设寄存器文件

stm32f10x.h:STM32的外设寄存器描述文件,它的作用就跟51单片机的头文件“RGEX52.H”一样,是用来描述STM32有哪些寄存器和它对应的地址的;

system_stm32f10x.csystem_stm32f10x.h文件:主要是用来配置时钟的,STM32主频72MHz,就是system文件里的函数配置的。

将上述3个文件复制粘贴到“Start”文件夹下。

 3.1.2.3 添加STM32内核寄存器文件

因为STM32是内核和内核外围的设备组成的,而且内核的寄存器描述和外围设备的描述文件不是在一起的,所以还需要添加内核寄存器文件。

将上述两个文件粘贴到 “Start”文件夹下。

3.1.2.4 将以上文件添加到工程中

 将以下文件添加进去(md.s文件以及.c和.h文件):

以上文件都是STM32里最基本的文件,是不需要修改的,添加进来即可。 文件图标上带了个钥匙🔑,表示这些文件是只读文件,无法被修改。

3.1.2.5 在工程选项里添加Start文件夹头文件路径

3.1.3 添加源代码文件

创建“User”文件夹,用来存放main函数等文件 。

 这个工程还没有添加STM32的库函数,还是一个基于寄存器开发的工程,如果想用寄存器开发STM32,那么工程建立到这里就可以了。

 3.1.4 通过寄存器的方式完成点灯的操作

修改编辑器字体大小:

(1)连接电路:

3.1.4.1  配置调试器

接在PC13引脚的LED灯停止闪烁。 

3.1.4.2 配置寄存器点灯 

(1) 首先配置RCC的一个寄存器,来使能GPIOC的时钟,GPIO都是APB2的外设。

因为测试LED灯接在PC13引脚,参照STM32引脚定义 ,该引脚主功能为IO口,再参照STM32芯片系统结构,GPIO都是APB2的外设。

位4写1就是打开GPIOC的时钟,其它的无关项都给0, 那么将整个RCC时钟控制信号换成16进制便是0x0000 0010;

(2)配置GPIOC的模式

换算成16进制就是0x0030 0000。

(3)配置端口输出数据寄存器

main.c代码如下:

#include "stm32f10x.h"                  // Device header

int main(void)                          //main函数是一个int型返回值,void参数的函数
{
	RCC->APB2ENR = 0x00000010;          //打开GPIOC的时钟
	GPIOC->CRH = 0x00300000;            //配置GPIOC的输出模式
	GPIOC->ODR = 0x00002000;            //这个灯是低电平点亮,给0x00002000就是灭,给0x00000000就是亮
	while(1)
	{
		
	}
}

3.2 通过库函数的方式点灯 

在通过寄存器的基础上进行。

3.2.1 添加库函数

(1)工程文件夹下新建“Library”文件夹

(2)将库函数复制到 “Library”文件夹下。

①复制库函数的源文件。

misc.c:内核的库函数,其它的都是内核外的外设库函数。misc就是混杂的意思。

将以上文件全部复制到 “Library”文件夹下。

②复制库函数的头文件粘贴到“Library”文件夹下。

(3)将库函数文件添加进工程

但是这个库函数还不能直接使用。

(4)添加库函数头文件包含文件

stm32f10x_conf.h 

用来配置库函数头文件的包含关系的,另外里面还有个用来参数检查的函数定义,这是所有库函数都需要的。

stm32f10x_it.h和stm32f10x_it.c 

用来存放中断函数。

将上述三个文件复制粘贴到“User”文件夹下。

将这三个文件添加进工程:

3.2.2 配置库函数

#ifdef USE_STDPERIPH_DRIVER                //如果定义了USE_STDPERIPH_DRIVER这个字符串,下面的"stm32f10x_conf.h"才有效
  #include "stm32f10x_conf.h"
#endif

复制“USE_STDPERIPH_DRIVER

将 “Library”文件夹和“User”文件夹也添加到目录里。

 这样,基于库函数的工程就建好了,“Library”里面的库函数也都带了钥匙🔑,不需要更改。位移需要更改的是“User”里面的文件。

点击上图所示按钮,挪一下文件组的位置。

3.2.3 通过库函数点灯

 库函数也是间接的配置寄存器,所以步骤是一样的。

(1)配置RCC外设时钟 

查看函数简介 :

/**
  * @brief  Enables or disables the High Speed APB (APB2) peripheral clock. //这个函数用来使能或失能APB2的外设时钟
  * @param  RCC_APB2Periph: specifies the APB2 peripheral to gates its clock.
  *   This parameter can be any combination of the following values://第一个参数可以是下面这些值                    
  *     @arg RCC_APB2Periph_AFIO, RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB,
  *          RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE,
  *          RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG, RCC_APB2Periph_ADC1,
  *          RCC_APB2Periph_ADC2, RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1,
  *          RCC_APB2Periph_TIM8, RCC_APB2Periph_USART1, RCC_APB2Periph_ADC3,
  *          RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, RCC_APB2Periph_TIM17,
  *          RCC_APB2Periph_TIM9, RCC_APB2Periph_TIM10, RCC_APB2Periph_TIM11     
  * @param  NewState: new state of the specified peripheral clock.//第二个参数可以是ENABLE or DISABLE
  *   This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
{
  /* Check the parameters */
  /* 内部还是配置RCC_APB2ENR这个寄存器,但是经过函数的包装,我们不需要查手册,确认哪一位的作用
	而且函数中已经使用"|="和"&="使得这个库函数的配置不会影响到寄存器的其它位*/
  assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  if (NewState != DISABLE)
  {
    RCC->APB2ENR |= RCC_APB2Periph;
  }
  else
  {
    RCC->APB2ENR &= ~RCC_APB2Periph;
  }
}

(2)配置端口模式

查看函数简介:

/**
  * @brief  Initializes the GPIOx peripheral according to the specified   
  *         parameters in the GPIO_InitStruct.//根据GPIO_Init结构体的参数来配置GPIO
  * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.//第一个参数GPIOx,其中x可以是A到G,来选择需要配置哪个GPIO
  * @param  GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that//第二个参数是一个GPIO_InitTypeDef的结构体,因此需要先定义一个GPIO_InitTypeDef结构体
  *         contains the configuration information for the specified GPIO peripheral.
  * @retval None
  */
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)

查看GPIO_Mode的定义:

通过查找可查看GPIO_Mode可以使用哪些参数,GPIO_Pin和GPIO_Speed同理。

查看GPIO_Pin的定义:

以上是通过库函数点亮PC13口LED的库函数方法,最终"main.c"文件如下:

#include "stm32f10x.h"                  // Device header

int main(void)                          //main函数是一个int型返回值,void参数的函数
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); //配置GPIOC外部时钟
	GPIO_InitTypeDef GPIO_InitStructure;                 //定义一个GPIO_InitTypeDef结构体,名字最好取为GPIO_InitStructure,然后配置其三个参数
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;     //配置GPIO模式是通用推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC,&GPIO_InitStructure);                //配置GPIOC端口的输出模式
//	GPIO_SetBits(GPIOC,GPIO_Pin_13);                     //设置GPIO_Pin_13高电平,灯灭
	GPIO_ResetBits(GPIOC,GPIO_Pin_13);                   //设置GPIO_Pin_13低电平,灯亮
	while(1)
	{
		
	}
}

3.3 关于启动文件的注意事项 

新建工程以后第一个加的就是启动文件,这个启动文件有很多类型,我们要根据芯片型号来选择。

下表是STM32F1系列中的型号分类 

缩写

释义

Flash容量

型号

LD_VL

小容量产品超值系列

16~32K

STM32F100

MD_VL

中容量产品超值系列

64~128K

STM32F100

HD_VL

大容量产品超值系列

256~512K

STM32F100

LD

小容量产品

16~32K

STM32F101/102/103

MD

中容量产品

64~128K

STM32F101/102/103

HD

大容量产品

256~512K

STM32F101/102/103

XL

加大容量产品

大于512K

STM32F101/102/103

CL

互联型产品

-

STM32F105/107

如果使用的是STM32F100的型号,就选择带VL的启动文件,然后再根据Flash的大小选择LD、MD还是HD。

如果使用的是STM32F101/102/103的型号,就选择不带VL的启动文件,然后再根据Flash的大小选择LD、MD、HD还是XL。

如果使用的是STM32F105/107的型号,就选择CL的启动文件。

3.4 工程架构

startup启动文件,这个是程序执行最基本的文件,keil中启动文件是用汇编写的,启动文件内定义了中断向量表、中断服务函数等。中断服务函数中有个复位中断,这就是整个程序的入口,当STM

32上电复位或者按下复位键后,程序就会进入复位中断函数执行,复位中断函数主要做两件事情,第一个是调用SystemInit函数,第二个是调用main函数。

startup_xx.sStrt 

sstartup_xx.startup_xx.sstartup_xx.s 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值