mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED

【朱老师课程总结】

第一部分、章节目录

第二部分、章节介绍

3.5.1.STM32的GPIO模块数据手册详解1

本节讲解STM32数据手册中GPIO模块相关的部分,主要是GPIO的各种模式及其配置方法。

3.5.2.STM32的GPIO模块数据手册详解2

本节继续讲解STM32的数据手册中GPIO部分,主要是GPIO配置的寄存器列表及寄存器位详解。

3.5.3.原理图分析与MDK工程建立

本节分析ARM3.0的GPIO控制LED相关的原理图,并且建立MDK工程,简单讲一下启动文件。

3.5.4.写代码控制GPIO点亮熄灭LED1

本节编写代码控制GPIO以点亮熄灭LED,主要内容是寄存器地址的确定以及使用C语言操作寄存器的编程技巧。

3.5.5.写代码控制GPIO点亮熄灭LED2

本节解决了时钟模块没打开的问题,并且定义了宏来访问寄存器,使我们的代码更加规范。

3.5.6.STM32时钟设置函数移植与讲解1

本节移植STM32时钟设置函数,并且结合前面课程讲过的时钟框图对时钟设置函数进行讲解

3.5.7.STM32时钟设置函数移植与讲解2

本节接上节继续移植时钟部分的设置代码,到了HSE时钟稳定阶段

3.5.8.STM32时钟设置函数移植与讲解3

本节完成时钟设置的源码移植并且进行测试。

3.5.9.STM32时钟设置函数移植与讲解4

本节使用调试的方式寻找代码中的问题,解决了超时计算的bug和if判断中的bug,但是时钟还是有问题不能工作

3.5.10.STM32时钟设置函数移植与讲解5

本节添加了FLASH ACR寄存器相关的操作代码后,时钟终于正常工作了。并且通过flash函数的闪烁速度对比可以明显看出PLL启动后主频发生了改变。

3.5.11.在PZ6806L开发板上实现GPIO和时钟编程控制

本节在PZ6806L开发板上移植实现GPIO的控制和时钟模块的编程,这种移植可以让大家学会在不同硬件差异下编程的相同点和不同点。

3.5.12.在PZ6808L开发板上实现GPIO和时钟编程控制1

本节在PZ6808L开发板上移植实现GPIO的控制和时钟模块的编程,让大家看看在F4上编程和F1上有什么差异

3.5.13.在PZ6808L开发板上实现GPIO和时钟编程控制2

本节接上节在PZ6808L开发板上移植实现GPIO的控制和时钟模块的编程.

3.5.14.STM32外设编程经验总结

本节对整个课程进行总结,并对比了51单片机和stm32单片机外设编程的差别,告诉大家stm32学习的关键点和思路方法。

第三部分、随堂记录

3.5.1.STM32的GPIO模块数据手册详解1

数据手册第8章:通用和复用功能I/O(GPIO 和AFIO)

3.5.1.1、GPIO功能描述

(1)每个I/O端口(GPIOx)包含的寄存器

两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH)

两个32位数据输入/输出寄存器(GPIOx_IDR和GPIOx_ODR)

一个32位端口位置位/复位寄存器(GPIOx_BSRR)                置位:写1,复位:写0

一个16位端口位复位寄存器(GPIOx_BRR)                             也是32位寄存器,只不过高16位保留不用!

一个32位端口配置锁定寄存器(GPIOx_LCKR)

PS:BRR和BSRR复位功能相似、在STM32F103C8中每个GPIO端口包括16个引脚

(2)每个端口的每个位可以由软件分别配置成多种输入输出模式。

输入浮空

输入上拉

输入下拉

模拟输入

开漏输出

推挽式输出

推挽式复用功能

开漏复用功能

详细了解可以看这个文件:GPIO输入输出模式详解

(3)每个端口都可以配置三种最大输出翻转速度

在配置寄存器里设置即可

mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED_第1张图片

后面都是关于硬件设计的,只要做了解即可!

(4)外设的GPIO配置

3.5.2.STM32的GPIO模块数据手册详解2

(1)GPIO寄存器描述

GPIO的寄存器基地址是0x40010800

端口配置低寄存器 端口配置低寄存器(GPIOx_CRL) (x=A..E)

端口配置高寄存器 端口配置高寄存器(GPIOx_CRH) (x=A..E)

为什么会有两个端口配置寄存器呢?因为一个端口配置寄存器只能配置8个引脚,两个就可以配置一个端口!CNFx位和MODE位关联

端口输入数据寄存器 端口输入数据寄存器(GPIOx_IDR) (x=A..E)

端口输出数据寄存器 端口输出数据寄存器(GPIOx_ODR) (x=A..E)

端口位设置 端口位设置/ 清除寄存器(GPIOx_BSRR) (x=A..E)

是对ODR位置位/复位

如果BRy和BSy同时被置位,BSy有优先权。

mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED_第2张图片

端口位清除寄存器 端口位清除寄存器(GPIOx_BRR) (x=A..E)

端口配置锁定寄存器 端口配置锁定寄存器(GPIOx_LCKR) (x=A..E)

(2)复用

AFIO的起始地址:0x4001 0000

3.5.3.原理图分析与MDK工程建立

3.5.3.1、硬件接线

(1)杜邦现连接P0端口到LED接口J19,这样相当于8个LED分别对应PB8-PB15

PB8—LED0,PB9—LED1...

(2)LED是共阴,所以GPIO输出0就亮,输出1就灭!

3.5.3.2、MDK工程建立

(1)提取ST标准外设库文件

ST标准外设库里面源代码文件我们只需要使用部分文件。因此,提取需要使用的文件及文件夹到我们的工程中。

解压“STM32F10x_StdPeriph_Lib”,可以看到在主目录下面有四个文件夹:

_htmresc:图片文件夹(不提取)

Libraries:库文件夹(提取大部分)

Project:  示例工程(提取少部分)

Utilities: 公共代码、评估板代码(不提取)

(2)新建文件和文件夹

除了上面提取的文件之外,我们需要建立存放自己代码的文件和文件夹。我这里主要新建三个文件夹:

App: 应用部分代码

Bsp: 底层部分代码

Doc: 说明文档

在新建的文件夹下面还需要新建自己的源文件,源文件里面添加源代码。

mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED_第3张图片

(3)新建工程

建立工程的步骤是基础,也比较简单,下面一步一步教大家新建一个空的工程。

A.打开软件,新建立工程(Project -> New uVision Project)

mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED_第4张图片

B.选择保存路径,保存名称

mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED_第5张图片

C.选择芯片型号

mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED_第6张图片

mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED_第7张图片

D.基础工程

mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED_第8张图片

一个基础的工程就完成了,但还不够,还需要下面的步骤。

3.2 添加文件

准确的来说,应该是添加组(文件夹)和添加文件。直接的说,就是将你自己的源代码(前面提取的库、新建的文件等)添加到工程中。

这里的工程项目管理可根据自己的想法来定义(类似于自己分类、命名文件夹和文件),我这里按照常规的方式进行管理项目。

点击“项目管理”快捷按钮,或者Project -> Manage -> Project Items 进入“项目管理”界面。

mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED_第9张图片

mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED_第10张图片

一步一步添加,直到最后完成

mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED_第11张图片

3.3 配置工程

配置工程对于初学者来说,大部分内容只需要默认即可,这里只讲述几个常见的配置,能满足基本的功能。

A.点击“工程目标选项”进入配置(或Project -> Options for Target)

mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED_第12张图片

B.输出Hex文件

很多朋友初学的朋友都会问怎么输出Hex,只需要勾选上【Project -> Options for Target -> Output】“Create HEX File”即可。

mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED_第13张图片

C.C/C++配置

这个选项的配置参数比较多,对于大型项目来说比较重要,但对于初学者来说,只需要简单配置两项就行。

第一处配置---预定义:

【这里以STM32F103大容量芯片为例】

mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED_第14张图片

预定义STM32F10X_HD,等同于#define STM32F10X_HD.

有些工程还预定义USE_STDPERIPH_DRIVER。由于都是使用“标准外设库”,我个人习惯把USE_STDPERIPH_DRIVER,定义在stm32f10x.h文件里面,所以在这里就看不到我定义的这一项了。

第二处配置---包含路径:

由于我们前面工程中有很多文件夹,因此需要添加对应的路径,这样编译器才能找得到。

mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED_第15张图片

mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED_第16张图片

一步一步添加,直到最后完成

mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED_第17张图片

D.选择下载调试工具

这个选项根据自己的下载调试器来选择(比如:ST-Link)

mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED_第18张图片

E.下载复位并运行设置

有些初学的朋友说“为什么我下载程序之后,需要按一下复位键才能运行?”,只需要在工程中勾选上“Reset and Run”就可实现,下载完程序马上运行了。

mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED_第19张图片

mdk5用C 语言的库函数移植,【STM32单片机学习】第四课:GPIO控制LED_第20张图片

至此,一个新建立的工程就算完成了(当然,我新建的文件是添加了正确的源代码),只需要编译,接上下载器就可以下载运行了。

3.5.4_5.写代码控制GPIO点亮熄灭LED1_2

3.5.4.1、寄存器信息确认

(1)STM32 PortB的起始地址是:0x40010C00

(2)有可能涉及到的GPIO的地址:

寄存器名         偏移量        寄存器地址

GPIOB_CRL     0x00        0x40010C00

GPIOB_CRH    0x04        0x40010C04            *

GPIOB_IDR      0x08        0x40010C08

GPIOB_ODR    0x0C        0x40010C0C           *

GPIOB_BSRR  0x10        0x40010C10            ?

GPIOB_BRR    0x14        0x40010C14            ?

3.5.4.2、C语言操作寄存器

(1)ARM是内存与IO统一编址的,所以ARM中的所有外设都是通过寄存器的方式来操作的

(2)每个寄存器都有地址,C语言通过这些地址来操作这些寄存器位,用到的C语言技巧主要是C语言的位操作和C语言指针。

(3)常见面试题:用C语言向内存地址0x30000004写入16

*(unsigned int *)0x30000004 = 16;            或者:

unsigned int *p = (unsigned int *)0x30000004;    *p = 16;

(4)向CRH寄存器写内容,将GPIO8-GPIO15配置为输出模式

通用推挽输出

CRH = 0x33333333

3.5.6_7.STM32时钟设置函数移植与讲解1_2

3.5.6.1、时钟模块回顾

(1)一个疑惑:前面代码并没有设置时钟为什么能够运行

(2)时钟框图

3.5.6.2、时钟设置示例代码分析

(1)相关寄存器及定义

(2)代码详解

RCC->CR 就相当于是rRCC_APB2ENR

3.5.6.3、时钟代码移植

3.5.8_9_10.STM32时钟设置函数移植与讲解3_4_5

3.5.11.STM32外设编程经验总结

3.5.14.1、STM32和51或其他简单单片机的相同

(1)开关环境都是Keil

(2)都是看原理图和数据手册

(3)都是用C语言

3.5.14.2、STM32和51或其他简单单片机的不同

(1)工程会更复杂,会用到Keil的一些高级设置

(2)原理图和数据手册比简单单片机更复杂(复杂不是难)

(3)STM32会用到C语言的更多高级特性

3.5.14.3、外设编程思路

(1)都是套路

(2)会出现问题,这时候就需要调试能力(不一定非要调试器)

(3)注意熟悉和体会这种套路,后面引入库函数就是从这里讲起的

你可能感兴趣的:(mdk5用C,语言的库函数移植)