sunny-sky

STM32学习笔记

在文章伊始:

请你铭记,任何时候不想学、看不懂其实都是因为学习方法不对

可能是你参考的资料太难,这时候你应该去寻找更基础的资料

可能是你自信心不足,请你相信自己,珍惜自己,重视自己!

 file:///C:/Users/admin/Desktop/%E6%80%BB%E4%BD%93%E5%AD%A6%E4%B9%A0%E8%A6%81%E6%B1%82.html

 

视频&配套的PPT和程序为主要参考

零死角那本书入门其实挺难看懂

 

数据手册主要用于芯片选型和设计原理图时参考,参考手册主要用于在编程的时候查阅

 

内部功能图

 

母线busmatrix

通过点亮LED灯全面理解寄存器编程

 

 

编译出错解决办法

对于error,可以双击则会自动跳到出错位置,在该位置上下几行寻找问题

实在找不到可以右键复制到剪贴板再百度求助

对于warning,如果不影响运行有一些可以忽略(比如定义的变量未使用),而若影响运行则需要同error一样解决

基本概念

keil的理解

Keil是公司名,uVision是集成开发环境(IDE),uVision5是其中最新的一个版本

搭建环境,就是需要编程用的语言和用什么进行编程,用什么进行调试(调试就是找有没有bug,所以调试器的英文叫做debugger)的这几个条件的总和

在我们这儿,就是用keil5提供的软件以汇编语言进行编程,用开发工具进行调试

开发工具包括MDK——支持ARM内核;c51——支持8051内核

软件本身的基础性作用就是把汇编语言编译生成单片机可执行的二进制代码,这样就可以烧写到单片机里面

编程时搭建环境、搭建框的含义详解

 

封装

F103指的是设计的晶圆型号,晶圆经过激光蚀刻(形成上亿的晶体管)每一小块滑下来就是一个MCU【感觉类似AD中的拼版】,晶圆取下来后就需要封装,下图就是双列直插式封装,连接金属引线的过程就是ponding[绑定]

 

 

 

 

 

 

 

 

 

BGA,LQFP是按照外形来划分的封装类型

这个是BGA(底部有点)

 

 

这个是LQFP(四周有脚),应用更为广泛

 

一般来说引脚少,功能少,内存也小,其他各方面均配套降低

图:数据手册中给出的封装使用说明

 

 

STM32ARM

 

STM32 使用ARM内核CPU

ARM属于一个微控制器,STM32自带了各种常用通信接口,比如 USART、I2C、SPI 等,

1、串口—USART,用于跟跟串口接口的设备通信,比如:USB转串口模块、ESP8266

WIFIGPS模块,GSM 模块,串口屏、指纹识别模块

2、内部集成电路—I2C,用于跟I2C接口的设备通信,比如:EEPROM、电容屏、陀螺

MPU60500.96OLED模块

3、串行通信接口—SPI,用于跟SPI接口的设备通信,比如:串行FLASH、以太网W5500、音频模块VS1053

4SDIOFSMC的超级、I2SADCGPIO

CPU,MCU,嵌入式系统联系与区别

 

 

 

 

 

MCU选型

一个原则:花最少的钱,做最多的事

在确定项目需求的情况下,一般按照下面的顺序来选择合适的MCU

1、选择哪种内核的芯片,内核越高意味着功耗也越高

2、选择多少引脚的芯片,引脚多少决定了资源的多少,也影响价格

3、选择多少RAMFLASH的芯片,FLASH越大,价格越贵

4、还要考虑所选型号采购是否容易,供货是否稳定

 

存储器概念辨析

存储器:

分类

 

内存一般指的RAM,SRAM无需刷新,所以速度比DRAM快,SRAM 一般只用于 CPU 内部的高速缓存(Cache),而外部扩展的内存一般使用 DRAM【但是霸道扩展用的SRAM】。

 

闪存指的是FLASH,容量比ROM大

其中NOR FLASH 一般应用在代码存储的场合

即我们平常所说的从FLASH读取到内存,可以简单粗暴的理解为从NOR FLASH读取到SRAM

SD 卡、U 盘以及固态硬盘是NAND FLASH

 

机械硬盘:

非易失性存储器种类非常多,半导体类的有 ROM FLASH,而其它的则包括光盘、

软盘及机械硬盘。

一般说的硬盘都是指的机械硬盘硬盘应当是计算机的外存储存空间 (Storage)指的就是硬盘的容量

各类型存储器区别与联系

 

DAP及串口ISP

串口isp是成本低的下载方式,现在在F4,7系列已经很少使用,DAP完全可以取代它(下载+调试+仿真)

debugger直译为调试器,但是一般却叫做仿真器

高速版HS——5M,全速版FS——1M

串口,JTAGSW均是下载模式的国际标准

高速版支持JTAGSW,全速版仅支持SWSWSWD是一样的】

内置ARMSWJ接口,包含了SWJTAG接口

 

注意:ARM【内核】是采用了一种叫做SWJ的接口,包含了SWJTAG两种接口;DAP【仿真器】是分成两种版本,支持不同接口

 

可见JTAG包含SWDSWCLK是时钟线,SWDIO是数据线,NJTRST是复位线

串口【COM口】功能只有下载程序

JTAGSW可在线调试和硬件仿真

关于JTAGSW的区别

串口中BOOT就是引导的意思,Boot模式设实际指的就是选择启动的起始地址区域,在STM32中存在以下三种模式可供选择,分别为片内Flash、系统内存、片内SRAM

 

 

 

寄存器

可以理解为CPU的零级缓存,它内置于各个IP外设中,是一种用于配置外设功能的存储器,就是一种内存,并且有相对应的地址。

 

存储器映射

存储器本身没有地址,给存储器分配地址的过程叫存储器映射

寄存器映射

寄存器本身就有地址

给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射。

sfr p0=0x80

野火寄存器点亮LED灯教程中避开了寄存器映射,采用对地址进行位操作

偏移地址

它的存在是历史原因所致

把存储单元的实际地址与其所在段的段地址之间的距离称为段内偏移,也称为有效地址或偏移量。 亦: 存储单元的实际地址与其所在段的段地址之间的距离。本质其实就是实际地址与其所在段的段地址之间的距离

更通俗一点讲,内存中存储数据的方式是:一个存储数据的实际地址”=段首地址+偏移量,

也可以这样理解:就像我们现实中的家庭地址”=“小区地址”+“门牌号

上面的偏移量就好比门牌号

其实就相当于C++的指针一样啦,指出确切的地址而已……

 

汇编语言

汇编语言基础知识

Heap(堆)

因为用户主动请求而划分出来的内存区域,叫做 Heap(堆)。它由起始地址开始,从低位(地址)向高位(地址)增长。Heap 的一个重要特点就是不会自动消失,必须手动释放,或者由垃圾回收机制来回收。

 

 

Stack(栈)

除了 Heap 以外,其他的内存占用叫做 Stack(栈)。简单说,Stack 是由于函数运行而临时占用的内存区域。

 

帧(frame

帧是栈的一部分

C语言

 

宏定义

条件编译

条件编译是一种宏定义,故有#,它的目的就是防止函数二次定义

最常用的方式就是

#ifndefine //如果未定义此函数

#define //则定义它

续行符

语法:“\”

表示续行符的下一行与续行符所在的代码是连接起来

应用续行符的时候要注意,在“\”后面不能有任何字符(包括注释、空格),只能直接

回车

指针

指针意思是通过它能找到以它为地址的内存单元

作个比喻,假设将电脑存储器当成一本书,一张内容记录了某个页码加上行号的便利贴,可以被当成是一个指向特定页面的指针

 

枚举

从同一类型的数据中抽出来一部分,就是枚举

Enum

 

 

结构体

把不同类型的数据重组在一块

 

 

 

 

typedefC语言的关键字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)。

init为初始化函数

浅析C语言之uint8_t / uint16_t / uint32_t /uint64_t

常用的结构体使用方法是:

1.在开头typedef struct

2.在后面分别对结构体中的数据类型进行细化定义

@defgroup

Static

在函数的返回类型前加上static,就是静态函数。其特性如下:

 

静态函数只能在声明它的文件中可见,其他文件不能引用该函数

不同的文件可以使用相同名字的静态函数,互不影响

变量

基本数据类型

 

 

 

 

数组

 

易变/修饰 只读变量

编译器有可能会对没有执行程序的变量进行优化

volatile 表示易变的变量,防止编译器优化

 

 

参数与变量区别

参数也是变量。变量很多种,参数变量是其中一种。

普通变量是你自己初始化的,参数变量是程序自动为你初始化的(就在你调用函数的一瞬间)

追问

那带参函数是什么意思

它与不带参数的有什么区别

追答

从道理上讲,既然有 带参数,那就有不带参数的情况。

货车可以装货,也可以不装货啊,尽管货车是用来装货的。

 

从技术讲,定义一个函数实际上是定义了一段代码,一段可以重复利用的代码

这段代码只有入口和出口,就像工厂的生产线,你送进去棉花,出来就是毛线。

 

定义一个函数

int plus(int a, int b) { retuan a + b};

定义一个函数

成品 生产(原料 棉花)      <---- 成品代表int  生产单表plus  原料代表int  棉花代表 a

 {

    return (棉花在生产线上经过七七四十九关处理变成——毛线);

}

有时候函数没有参数噻,这个就跟自然数为什么要发明一个0呢,一样道理。

函数这段代码有一个专门传入参数的地方,如果没有参数,这个地方就没用而已。

c语言参数和变量的区别

C语言形参和实参的区别(非常详细)

简单来说,形参就是无赋值,而实参就是有赋值

总线

I2C总线

 

SCL时钟控制线   SDA串行数据线

Serial clock data

 

 

固件库

中英文对照

Firmware library

模板:template

bspBoard support package板级支持包;就是只针对特定的开发板

为什么用固件库

 

固件库就是底层驱动程序,用来操作寄存器

 

 

Doxygen

/**

  * @brief  初始化控制LEDIO

  * @param  

  * @retval

  */

这一段是代码书写的规范,名为Doxygen”,如果在工程文件中按照这种规范去注释,可

以使用 Doxygen 软件自动根据注释生成帮助文档。

函数简介(@brief)、参数说明(\'@param\')和返回值说明(@retval)四部分

文件类型

.s是汇编语言

.h是头文件

.h中一般放的是宏定义以及同名.c文件中定义的变量、数组、函数的声明,需要让.c外部使用的声明。

.c文件一般放的是变量、数组、函数的具体定义。

用法

.c文件,以c为扩展名,一般存储具体功能的实现。

.h文件,称为头文件,一般存储类型的定义(宏定义),函数的声明等。通常,头文件被.c文件包含,使用#include 语句。但值得注意的是,这只是一种约定,而非强制。

Ps:为防止.h被不同.c文件调用而导致其中宏定义被多次定义【类似一个函数可以被声明多次,但是只能被定义一次】,在.h文件中宏定义时一定要用条件编译

 

 

文件作用

1-汇编编写的启动文件

startup_stm32f10x_hd.s:设置堆栈指针、设置PC指针、初始化中断向量表、配置系统时钟、使用库函数_main最终去到C的世界

 

2-时钟配置文件

system_stm32f10x.c:把外部时钟HSE=8M,经过PLL倍频为72M

 

3-外设相关的

stm32f10x.h:实现了内核之外的外设的寄存器映射

本质还是头文件

但是一般来说由于功能重要,故在main.c中必须要定义

 

xxxGPIOUSRATI2CSPIFSMC

stm32f10x_xx.c:外设的驱动函数库文件

stm32f10x_xx.h:存放外设的初始化结构体,外设初始化结构体成员的参数列表,外设固件库函数的声明

 

4-内核相关的

CMSIS - Cortex 微控制器软件接口标准

core_cm3.h:实现了内核里面外设的寄存器映射

core_cm3.c:内核外设的驱动固件库

 

NVIC(嵌套向量中断控制器)SysTick(系统滴答定时器)

misc.h

misc.c

 

5-头文件的配置文件

stm32f10x_conf.h:头文件的头文件

//stm32f10x_usart.h

//stm32f10x_i2c.h

//stm32f10x_spi.h

//stm32f10x_adc.h

//stm32f10x_fsmc.h

......

 

6-专门存放中断服务函数的C文件

stm32f10x_it.c

stm32f10x_it.h

 

中断服务函数可以随意放在其他的地方,并不是一定要放在stm32f10x_it.c

固件库调用逻辑

STARTUP文件启动[汇编语言,效率高]

调用CMSIS中的core_cm3.c[ARM内核相关程序]以及system_stm32f10x.c来配置时钟

使用FWLib添加固件库来关联main.c

在头文件main.c中对固件库进行调用

Ps:main.c前声明stm32f10x.h就可以调用这个库文件[其中对所有功能配置寄存器的地址进行了定义,之后就可以通过定义名来操作地址]

 

由于我们基本的函数执行均在main.c中完成,所以编写头文件的过程一般称作初始化xxx,因为头文件里面的内容是不需要全部调用的,而.c文件中如果有变量定义了而未进行使用,则会warning

 

野火新建工程文件存放方式

Fwlib-Template\Libraries\CMSIS\startup

Fwlib-Template\Libraries\CMSIS\core_cm3.c+stm32f10x.c

Fwlib-Template\Libraries\STM32F10x_StdPeriph_Driver\inc(.h)+src(函数.c)

Fwlib-Template\User\main.c+stm32f103_it.c

 

洋桃新建工程文件存放方式

CMSIS\core_cm3.c+stm32f10x.c

Lib\STM32F10x_StdPeriph_Driver\inc(.h)+src(函数.c)

startup

user\main.c+stm32f103_it.c

CMSIS:微控制器软件接口标准

 

———————————

GPIO

 

GPIO其实是厂商的说辞,本质还是I/O端口

 

翻转 toggle

中英文对照

PWM脉冲宽度调制

LSB,英文 least significant bit最低有效位

MSB,英文 most significant bit有效位

Alias,别名

 

引脚与I/O端口

I/O端口是引脚的一大类使用方式

引脚有3个要注意的地方:

  1. 大部分引脚也会有复用
  2. 少部分引脚可以自己映射(重定义)
  3. 大部分引脚兼容5V

 

GPIO中所用到的寄存器

CR:配置寄存器

DR:数据寄存器

每个GPI/O端口有两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH)LOW代表低电平,HIGH代表高电平方向控制

两个32位数据寄存器 (GPIOx_IDR和GPIOx_ODR)input output电平控制

一个32位置位/复位寄存器(GPIOx_BSRR)B代表bit    set  reset

一个16位复位寄存器(GPIOx_BRR)

一个32位锁定寄存器(GPIOx_LCKR):lock

GPIO8种输入方式

翻转速度指的是方波脉冲翻转速度

 

 

模拟输入即ADC输入

模拟和浮空都是断开上下拉电阻和输出端(绿色放大器),只有输入(黄色放大器)只不过输入信号不同

上拉/下拉的目的是保持端口悬空时的电平状态【上拉/下拉的电阻很大,故不会影响实际输入高/低电平】

推挽电流较大,有驱动外设工作的能力

开漏电流较小,只是一个输出电流

 

GPIO的分组

C51中以1.11.23.13.2这样的方式分组

STM32中以PA,PB,PC这样的方式分组,且并非所有端口都会列出来(有一些是内部自己使用了)

GPIO初始化配置函数解析

stm32 GPIO简单介绍及初始化配置(库函数)

延时函数代码解析

1.void Delay(__IO uint32_t nCount)  //简单的延时函数

{

for(; nCount != 0; nCount--);

}//具体时间与#define SOFT_DELAY Delay(0xFFFFF)以及时钟频率有关

初始化配置代码解析

 

 

 1 void LED_GPIO_Config(void)

2 {

3 /*定义一个 GPIO_InitTypeDef 类型的结构体*/

4 GPIO_InitTypeDef GPIO_InitStructure;

5

6 /*开启 LED 相关的 GPIO 外设时钟*/

7 RCC_APB2PeriphClockCmd( LED1_GPIO_CLK|

8  LED2_GPIO_CLK|

9  LED3_GPIO_CLK, ENABLE);

10 /*选择要控制的 GPIO 引脚*/

11 GPIO_InitStructure.GPIO_Pin = LED1_GPIO_PIN;

12

13 /*设置引脚模式为通用推挽输出*/

14 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

15

16 /*设置引脚速率为 50MHz */

17 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

18

19 /*调用库函数,初始化 GPIO*/

20 GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure);

21

22 /*选择要控制的 GPIO 引脚*/

23 GPIO_InitStructure.GPIO_Pin = LED2_GPIO_PIN;

24

25 /*调用库函数,初始化 GPIO*/

26 GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStructure);

27

28 /*选择要控制的 GPIO 引脚*/

29 GPIO_InitStructure.GPIO_Pin = LED3_GPIO_PIN;

30

31 /*调用库函数,初始化 GPIOF*/

32 GPIO_Init(LED3_GPIO_PORT, &GPIO_InitStructure);

33

34 /* 关闭所有 led */

35 GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);

36

37 /* 关闭所有 led */

38 GPIO_SetBits(LED2_GPIO_PORT, LED2_GPIO_PIN);

39

40 /* 关闭所有 led */

41 GPIO_SetBits(LED3_GPIO_PORT, LED3_GPIO_PIN);

42 }

附件:上述代码原图

 

 

 

位带操作(偏重寄存器,可忽略)

计算机位的理解

我们常常看到 32CPU64CPU 这样的名称,其实指的就是寄存器的大小

32位是说计算机一次最多能够处理32位数据,1byte=8bit,也就是说32位就是4字节

不同位支持的运行内存不同

 

每个存储单元可以存放八个二进制位,即一个零到二百五十五之间的整数、一个字母或一个标点符号等,叫做一个字节),即1字节=8 位存储器的容量就是以字节为基本单位的,每个单元都有唯一的序号,叫做地址。中央处理器凭借地址,准确地操纵着每个单元,处理数据。

Eg:比如外设外带区的地址为:0X40000000~0X40100000,大小就为 1MB

因为1在第6位,即16^5=2^20,单位byte,1MB=2^10KB,1KB=2^10byte

 

指针的寻址能力是4byte,段地址+偏移地址,可以通过一个地址找到整个寄存器

但是一个地址仍然对应着的是一个字节

参考手册原文:

 

寻址本身也是一种操作,所以寻址时时必须对整个32位寄存器进行操作

 

位操作和位带操作

位操作就是可以单独的对一个比特位【地址最末位】读和写

51单片机中通过关键字 sbit 来实现位定义

51 单片机里面并不是所有的寄存器都是可以比特位操作,有些寄存器还是得字节操作,比如 SBUF

 

STM32 没有这样的关键字,但是通过访问位带别名区可以实现对所有寄存器位操作

STM32 中,有两个特定的地方,一个是 SRAM 区的最低 1MB 空间,另一个是外设区最低 1MB 空间,称为位带,位带经过膨胀后得到位带别名区

对位带别名区的操作称为位带操作

 

 

RCC

RCC :reset clock control 复位和时钟控制器【注意该控制器有时钟和复位两种功能

对时钟的理解

 

时钟树

 

STM32中的高速时钟是给内核和外设用的,而低速时钟是给RTCIWDG用的

高速单位一般是MHz,低速是KHz

 

 

HSE

高速外部时钟信号HSE(High Speed External Clock signal)

来源:无源晶振(4-16M),通常使用8M。经过9倍频后得到72M

有源和无源区别:

有源晶振需要电源,但不需要附加的电容。它内部含有起振器。通常接到CPU的一根引脚即可OSC_IN。无源晶振不需要电源,但常需要和电容配合使用,它通常接到CPU的两根引脚上。OSC_IN OSC_OUT

目的:产生时钟信号(一般是方波)

 

控制:RCC_CR 时钟控制寄存器的位16HSEON控制使能;位17HSERDY控制结束

时钟一般都有一个位使能,一个位读取状态(使能是否成功)

 

时钟控制寄存器 CR control register

HSEON:外部高速时钟使能 (External high-speed clock enable)

HSERDY:外部高速时钟就绪标志 (External high-speed clock ready flag)

HSI

HSILow Speed Internal Clock signal,高速的内部时钟。

来源:芯片内部,大小为8M,当HSE故障时,系统时钟会自动切换到HSI,直到HSE启动成功。但是内部时钟会产生温漂

控制: RCC_CR 时钟控制寄存器的位0HSION控制使能;位1HSIRDY控制结束

锁相环时钟

分频prescaler

倍频PLL

锁相环时钟:PLLCLK

来源:(HSI/2HSE)经过倍频所得 。

控制:CFGRPLLXTPREPLLMUL

注意:PLL时钟源头使用HIS/2的时候,PLLMUL最大只能是16,这个时候PLLCLK最大只能是64M,小于ST官方推荐的最大时钟72M

时钟配置寄存器 CFGR configuration register

  1. PLLMUL:PLL倍频系数 (PLL multiplication factor)
  2. PLLXTPRE:HSE分频器作为PLL输入 (HSE divider for PLL entry)PRE想说的是预分频
  3. PLLSRC:PLL输入时钟源 (PLL entry clock source)

备份域控制寄存器BDCR:Backup Domain Control Register

控制/状态寄存器 CSR:control/status register

系统时钟

锁相环时钟:SYSCLK,最高为72MST官方推荐的)

来源:HSIHSEPLLCLK

控制:CFGRSW系统时钟切换

注意:通常的配置是SYSCLK=PLLCLK=72M

系统时钟是配置的总线AHB,APB1,APB2的时钟,外设时钟在具体外设.c文件中单独配置

HCLK时钟

HCLKAHB高速总线时钟,速度最高为72M。为AHB总线的外设提供时钟、为Cortex系统定时器提供时钟(SysTick)、为内核提供时钟(FCLK)。

AHBadvanced high-performance bus

来源:系统时钟分频得到,一般设置HCLK=SYSCLK=72M

控制: CFGRHPRE

PCLK1时钟

PCLK1APB1低速总线时钟,最高为36M。为APB1总线的外设提供时钟。2倍频之后则为APB1总线的定时器2-7提供时钟,最大为72M

来源:HCLK分频得到,一般配置PCLK1=HCLK/2=36M

控制: RCC_CFGR 时钟配置寄存器的PPRE1

PCLK2时钟

PCLK2APB2高速总线时钟,最高为72M。为APB1总线的外设提供时钟。为APB1总线的定时器18提供时钟,最大为72M

来源:HCLK分频得到,一般配置PCLK1=HCLK=72M

控制: RCC_CFGR 时钟配置寄存器的PPRE2

时钟配置函数

其他时钟

RTC时钟

RTC时钟:为芯片内部的RTC外设提供时钟。

来源:HSE_RTCHSE分频得到)、LSE(外部32.768KHZ的晶体提供)、LSI32KHZ)。

控制: RCC备份域控制寄存器RCC_BDCRRTCSEL位控制

 

独立看门狗时钟

IWDGCLK,由LSI提供

 

MCO时钟输出

MCOmicrocontroller clock output,微控制器时钟输出引脚,由PA8复用所得

来源:PLLCLK/2HSEHSISYSCLK

控制:CRGRMCO

主要作用是可以对外提供时钟,相当于一个有源晶振可以用来监控系统时钟

中断

Interrupt

对中断的理解

有关单片机中断系统的概念:什么是中断,我们从一个生活中的例程引入。你正在家中看书,突然电话铃响了,你放下书本,去接电话,和来电话的人交谈,然后放下电话,回来继续看你的书。这就是生活中的“中断”的现象,就是正常的工作过程被外部的事件打断了。仔细研究一下生活中的中断,对于我们学习单片机的中断也很有好处。

 

第一、什么可经引起中断,生活中很多事件能引起中断:有人按了门铃了,电话铃响了,你的闹钟闹响了,你烧的水开了.等等诸如此类的事件,我们把能引起中断的称之为中断源。

 

第二、中断的嵌套与优先级处理:设想一下,我们正在看书,电话铃响了,同时又有人按了门铃,你该先做那样呢?如果你正是在等一个很重要的电话,你一般不会去理会门铃的,而反之,你正在等一个重要的客人,则可能就不会去理会电话了。如果不是这两者(即不等电话,也不是等人上门),你可能会按你常常的习惯去处理。总之这里存在一个优先级的问题,单片机中也是如此,也有优先级的问题。优先级的问题不仅仅发生在两个中断同时产生的情况,也发生在一个中断已产生,又有一个中断产生的情况,比如你正接电话,有人按门铃的情况,或你正开门与人交谈,又有电话响了情况。考虑一下我们会怎么办吧。

 

第三、中断的响应过程:当有事件产生,进入中断之前我们必须先记住现在看书的第几页了,或拿一个书签放在当前页的位置,然后去处理不一样的事情(因为处理完了,我们还要回来继续看书):电话铃响我们要到放电话的地方去,门铃响我们要到门那边去,也说是不一样的中断,我们要在不一样的地点处理,而这个地点常常还是固定的。计算机中也是采用的这种办法,多个中断源,每个中断产生后都到一个固定的地方去找处理这个中断的程序,当然在去之前首先要保存下面将执行的指令的地址,以便处理完中断后回到原来的地方继续往下执行程序。具体地说,中断响应能分为以下几个步骤:

1、保护断点,即保存下一将要执行的指令的地址,就是把这个地址送入堆栈。

2、寻找中断入口,根据不一样的中断源所产生的中断,查找不一样的入口地址。

3、执行中断处理程序。

4、中断返回:执行完中断指令后,就从中断处返回到主程序,继续执行。

中断类型

STM32具有十分强大的中断系统,将中断分为两个类型:系统异常&外部中断

并将所有中断通过一个表编排起来,称之为stm32中断向量表

系统异常体现在内核水平,故也叫内核异常(10

外部中断体现在外设水平(60

内核异常不能够被打断,不能被设置优先级(也就是说优先级是凌驾于外部中断之上的)。常见的内核异常有以下几种:复位(reset),不可屏蔽中断(NMI),硬错误(Hardfault),其他的也可以在表上找到。

外部中断包含定时器中断,I2CSPI等所有的外设中断,可配置优先级

 

一般情况下中断和异常可以混用,不做区分

注意中断一定是终止内核的工作

 

 

NVIC

NVIC:嵌套向量中断控制器,属于内核外设,管理着包括内核和片上所有外设的中断相关的功能除了SYSTICK之外

 

NVIC是主要的中断控制器,外部内部中断均能处理。它跟内核紧密耦合,是内核里面的一个外设。但是各个芯片厂商在设计芯片的时候会对 Cortex-M3内核里面的 NVIC进行裁剪,把不需要的部分去掉,所以说 STM32 NVIC Cortex-M3 NVIC 的一个子集。

 

两个重要的库文件:core_cm3.hmisc.h

 

异常服务例程(ESR)Exception service routine

当内核响应了一个发生的异常后,对应的异常服务例程(ESR)就会执行

 

中断优先级寄存器IPinterrupt priority

 

优先级

分类

分成抢占优先级和子优先级。如果有多个中断同时响应,抢占优先级高的就会抢占 抢占优先级低的 优先得到执行,如果抢占优先级相同,就比较子优先级。如果抢占优先级和子优先级都相同的话,就比较他们的硬件中断编号,编号越小,优先级越高

 

优先级设定:NVIC->IPRx(ARM中将IP定义为8位,而stm32仅仅使用了高四位)

 

分组

优先级分组:SCB->AIRCR:PRIGROUP[10:8]    

系统控制块(System Control Block):也是内核里面的外设

应用程序中断及复位控制寄存器 AIRCRApplication Interrupt and Reset Control register

PRIGROUP:PriorityGroup

0组:所有的4位都有来表示响应优先级,能够配置16种不同的响应优先级。中断优先级则都相同。

1组:最高一位用来配置抢占优先级,剩余三位用来表示响应优先级。那么就有两种不同的抢占优先级(01)8种不同的响应优先级(0~7)

 

2组:高两位用来配置抢占优先级,低位用来配置响应优先级。那么两种优先级就各有4种。

3组:高三位用来配置抢占优先级,低位用来配置响应优先级。有8种抢占优先级和2种相应优先级。

4组:所有位都用来配置抢占优先级,即有16种抢占优先级,没有响应属性

5种不同的分配方式,根据项目的实际需求来配置。

配置的API如下:

NVIC_PriorityGroupConfig();

【APIApplication Programming Interface,应用程序接口)是一些预先定义的函数

其中括号内可以输入以下一个参数,代表不同的分配方式:

NVIC_PriorityGroup_0

NVIC_PriorityGroup_1

NVIC_PriorityGroup_2

NVIC_PriorityGroup_3

NVIC_PriorityGroup_4

中断编程

1-使能中断请求

外设相应寄存器发出使能中断请求,NVIC中的中断使能寄存器接收请求,产生中断

2-配置中断优先级分组

使用固件库函数NVIC_PriorityGroupConfig()

3-配置NVIC寄存器,初始化NVIC_InitTypeDef

NVIC_IRQChannel:中断源

NVIC_IRQChannelPreemptionPriority:抢占优先级

NVIC_IRQChannelSubPriority:子优先级

NVIC_IRQChannelCmd:使能或者失能

4-编写中断服务函数

中断服务函数名要怎么写?写错了怎么办?

在启动文件中有中断服务函数,并且进行了弱定义【weak】,即其他地方定义的函数先执行,若写错了无法执行则执行此中断服务函数,故编译器不会因为中断服务函数错误而报错

 

中断服务函数要写在什么地方?

专门存放中断服务函数的C文件

stm32f10x_it.c

stm32f10x_it.h

 

EXTI

EXTI(External interrupt/event controller—外部中断/事件控制器

负责管理所有外部中断/事件,然后交给NVIC处理

输入

输入线总共有多少,具体是哪一些?

EXTI 控制器有 19 个中断/事件输入线【20个是以太网唤醒事件(只适用互联型)

互联型指的是F105107等系列】,其中,EXTI0 EXTI15 用于 GPIO

当中断被触发后,程序要马上跳转到中断处理函数去执行中断操作,这个函数在工程创建时默认时没有的需要手动添加。这个函数在startup_stm32f10x_hd.s中

 

 

通过配置哪个寄存器来选择?

外部中断配置寄存器(AFIO_EXTICR)

AFIO_EXTICR寄存器组,总共有4 个,EXTICR1~ EXTICR 4。每个 EXTICR只用了其低16 位。

AFIO

stm32的引脚有两种用途:GPIO(general purpose io通用功能)和AFIO(alternate function io复用功能)

对于一些引脚(视芯片而定),这两种用途都没有,如在64脚产品中,OSC_IN/OSC_OUTOSC是外接石英晶体组成的振荡器,供给单片机时钟信号与作为GPIO端口的PD0/PD1共用一样的引脚,而在100、144引脚产品中,这四个功能各有引脚与之对应,不互相冲突,所以OSC_IN/OSC_OUT既不作GPIO也不作AFIO

一文看懂stm32的引脚的两种用途:GPIO和AFIO

EXTI寄存器

  1. EXTI本身的寄存器

IMR:中断屏蔽寄存器

这是一个 32 寄存器。但是只有前 19 位有效。当位 x 设置为1 时,则开启这个线上的中断,否则关闭该线上的中断。

EMR:事件屏蔽寄存器

IMR ,只是该寄存器是针对事件的屏蔽和开启。

RTSR:上升沿触发选择寄存器

该寄存器同IMR ,也是一个32为的寄存器,只有前 19位有效。位 x 对应线x 上的上升沿触发,如果设置为 1 ,则是允许上升沿触发中断/ 事件。否则,不允许。

FTSR:下降沿触发选择寄存器

PTSR,不过这个寄存器是设置下降沿的。下降沿和上升沿可以被同时设置,这样就变成了任意电平触发了。

SWIER:软件中断事件寄存器

通过向该寄存器的位x 写入 1 ,在未设置 IMR EMR的时候,将设置PR中相应位挂起。如果设置了IMR EMR时将产生一次中断。被设置的SWIER位,将会在PR中的对应位清除后清除。

 

PR:挂起寄存器

0 ,表示对应线上没有发生触发请求。

1,表示外部中断线上发生了选择的边沿事件。通过向该寄存器的对应位写入 1 可以清除该位。

在中断服务函数里面经常会要向该寄存器的对应位写1 来清除中断请求。

EXTI功能框图

 

GPIO中断实验

编程

1-初始化要连接到EXTIGPIO

2-初始化EXTI用于产生中断/事件

3-初始化NVIC,用于处理中断

4-编写中断服务函数

5-main函数

STM32-外部中断学习笔记

SYSTICK:嘀嗒定时器

 

 

 

 

中英文对照

Tick:发出嘀嗒声

 

DMA

中英文对照

Memory:存储器   Peripheral:外设  Configuration:配置

SRC:source:源头   DSTdestination):目的地

DIR:direction):方向

DMA_CPARxDMA channel x-Peripheral address register):DMA通道x外设地址寄存器(x=1...7)

理解为DMA的第x个通道的外设地址寄存器

同理

DMA_CCARx(DMA channel x-Configuration address register)DMA通道x配置地址寄存器(x=1...7)

PINC:外设地址增量模式 (Peripheral increment mode)

DMA_CNDTRx(DMA channel x-Number of data to transfer register)DMA通道x(数据)传输数量寄存器(x = 1…7)

 

DMA配置

DMA(Direct Memory Access,直接存储器访问)用来提供在外设Peripheral和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。

 

 

数据分为常量和变量,常量放在FLASH中,CPU通过ICode总线读取

变量放在SRAM中,CPU通过DCode总线读取

数据还可被DMA总线读取

取数时经过总线矩阵仲裁,决定哪个总线读取

 

同时,不同外设之间还可以通过DMA互相读取数据

DMA配置方法1

DMA配置方法2

 

ADC

中英文对照

ADC-DR :Analog-to-Digital Converter-Data Rigister模拟-数字转换器 数据寄存器

CR:Configuration register配置寄存器

参考例程

ADC

 

 

 

WDG

 

 

RTC

RTC:Real_Time Clock  实时时钟

32.768kHz是对应1

通讯功能

通信基本概念

串行与并行

 

串行信号:USARTI2CSPIW500

并行信号:SDIO,FSMC(16位并行),W5100

全双工、半双工&单工

 

全双工USARTSPI           RX,TX同时进行

半双工SPI(全/半均可)

单工I2C

注意很多通讯接口使用哪种不是唯一确定的

同步通讯&异步通讯

同步通讯:

异步通讯:

把时钟信号带入特性方程得到数据状态方程

通讯速率

Bitrate—比特率:每秒钟传输的二进制位数,单位为比特每秒(bit/s)

Baudrate—波特率:表示每秒钟传输的码元个数

因为很多常见的通讯中一个码元都是表示两种状态,人们常常直接以波特率来表示

比特率

USART

中英文对照

TX transmit 传送

RX receive接收

串口通讯协议

分层

物理层规定我们用嘴巴还是用肢体来交流(硬件部分)

协议层则规定我们用中文还是英文来交流(软件部分)

物理层标准

RS232&RS485标准

 

可见传输速率差别很大

 

一般直接从单片机中出来的电平都是TTL电平

51单片机中是5Vstm32中是3.3V

 

RS232标准串口主要用于工业设备直接通信因为它的电平差值30V,容错能力很强

电平转换芯片一般有MAX3232(这个就是我们电路板上面所使用的SP3232

 

串口、COM口、TTLRS-232的区别详解

USB转串口

USB常用TTL电平,串口常用电平RS232

 

1USB转串口主要用于设备跟电脑通信

2、电平转换芯片一般有CH340PL2303CP2102FT232

3、使用的时候电脑端需要安装电平转换芯片的驱动

 

原生的串口到串口

TTLTTL

 

1、原生的串口通信主要是控制器跟串口的设备或者传感器通信,不需要经过电平转换芯片来转换电平,直接就用TTL电平通信

2GPS模块、GSM模块、串口转WIFI模块、HC04蓝牙模块

 

协议层标准

协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准

 

起始位:由1个逻辑 0 的数据位表示

结束位:由 0.511.5 2 个逻辑 1 的数据位表示

有效数据:在起始位后紧接着的就是有效数据,有效数据的长度常被约定为 567 8 位长

STM32串口功能框图讲解

 

引脚

均为GPIO引脚

TX:数据发送

RX:是数据接收

SCLK:时钟,仅同步通信时使用而我们一般都是用的异步,故不用看

nRTS:请求发送(Request To Send)

nCTS:允许发送(Clear To Send)

 

注意串口1挂载到APB2,而其他的挂载到APB1,所以对应时钟也不同

对于可复用的引脚,在初始化时可以通过AFIO重映射配置成所需功能引脚

数据寄存器

USART_DR9位有效,包含一个发送数据寄存器TDR和一个接收数据寄存器RDR。一个地址对应了两个物理内存。

 

控制器

数据发送&接受状态和控制寄存器

USART_CR1M08bit19bit

USART_CR2STOP

USART_CR1PCEParity control enable检验控制使能)PSParity Selection检验选择)PEIEPE中断使能)

USART_SR  PEParity error校验错误)

 

USART_CR1UEUSART enableTEtransmitter enableREreceiver enable

编程时要令UE=1TE=1

USART_SRTXETransmit data register empty发送数据寄存器空

USART_CR1TXEIE发送缓冲区空中断使能

USART_SRTCTransmission complete发送完成

USART_CR1TCIE发送完成中断使能

USART_SRRXNERead data register not empty读数据寄存器非空

USART_CR1RXNEIE接收缓冲区非空中断使能

波特率

USART_BRR:波特率寄存器

 

USARTDIV:无符号的定点数

FCK:串口的时钟,注意区分APB2APB1两条总线

常用波特率:115200 9600 4800

写入时4位精度1/16

 

 

 

Eg:USARTUSART1,时钟为72M

波特率:115200

 

 

代码讲解

DeInitdefault init) 默认初始化:将所有寄存器复位成初始时状态

cmdcommand的缩写.即命令提示符(CMD

中断接收和发送

串口控制RGB灯亮灭

串口初始化结构体

SPI

串行外设接口

Serial peripheral interface

 

 

 

 

 

 

CAN

Controller Area Network

 

 

 

USB

 

 

 

CRC

 

 

分类:

技术点:

相关文章: