根据《STM32库开发实战指南——基于野火指南者开发板》整理,
https://gitee.com/Embedfire-stm32f103-zhinanzhe/ebf_stm32f103_zhinanzhe_
std_tutorial
在整理的过程中,还参考了其他的一些STM32资料
使用了“幕布”这款软件,添加了一些思维导图
整理框架目的:
1.梳理知识脉络
2.复习知识
命名
STM32F10xx 系统框图
总线
被动单元的地址划分
CMSIS标准
ST标准库(STD库)
ST标准库(STD库)中的启动文件
上图是汇编指令及对应作用
启动文件由汇编编写,是系统上电复位后第一个执行的程序。主要做了以下工作:
初始化堆栈指针SP=_initial_sp
初始化PC 指针=Reset_Handler
初始化中断向量表
配置系统时钟
调用C 库函数_main 初始化用户堆栈,从而最终调用main 函数去到C 的世界
ST标准库(STD库)中的stm32f10x.h
F103在内核水平上搭载了一个异常响应系统,支持系统异常和外部中断。具体的系统异常和外部中断可在标准库文件stm32f10x.h 这个头文件查询到,在IRQn_Type 这个结构体里面包含了F103 系列全部的异常声明
ST标准库(STD库)中的启动文件startup_stm32f10x_hd.s
在启动文件startup_stm32f10x_hd.s中预先为每个中断都写了一个中断服务函数,只是初始化中断向量表。实际的中断服务函数都需要重新编写。中断服务函数的函数名必须跟启动文件里面预先设置的一样,如果写错,系统就在中断向量表中找不到中断服务函数的入口,直接跳转到启动文件里面预先写好的空函数,并且在里面无限循环,实现不了中断
ST标准库(STD库)中的core_cm3.h
CM3内核中的外设(SysTick),有关寄存器的定义和库函数在core_cm3.h中
MDK编译过程
映像文件“.axf”或“.elf”
Flash格式文件(下载格式文件)“.bin”或“.hex”
图中未提到的armar,用于把.o文件打包成lib文件
域及堆栈空间
堆和栈用的ram
51 单片机不区分堆和栈空间,因为在51上用不了malloc,资源太稀缺了
编译工具链
MDK工程的文件类型
按键
按键抖动:按键机械触点断开、闭合时,由于触点的弹性作用,按键开关不会马上稳定接通或一下子断开,使用按键时会产生带波纹信号
按键消抖->软件消抖
软件消抖处理滤波
按键消抖->硬件消抖
硬件消抖功能,利用电容充放电的延时,消除波纹,从而简化软件的处理
这些按键在没有被按下的时候,GPIO 引脚的输入状态为低电平(按键所在的电路不通,引脚接地),当按键按下时,GPIO 引脚的输入状态为高电平(按键所在的电路导通,引脚接到电源)。只要检测引脚的输入电平,即可判断按键是否被按下。外部下拉配置成浮空模式,引脚的默认电平受按键电路影响
位带
STM32通过访问位带别名区来实现访问位带区某个比特位的目的。在STM32 中,有两个地方实现了位带,一个是SRAM 区的最低1MB 空间,另一个是外设区最低1MB 空间。这两个空间除了可以像正常的RAM 一样操作外,还有自己的位带别名区,位带别名区把这1MB 的空间的每一个位膨胀成一个32 位的字,当通过指针的形式操作这些位带别名区地址时,就可以达到访问位带区某个比特位的目的
时钟系统
时钟树
常用设置方法:
HSE 高速外部时钟信号:HSE 是高速的外部时钟信号,可以由有源晶振或者无源晶振提供,频率从4-16MHZ 不等。当使用有源晶振时,时钟从OSC_IN 引脚进入,OSC_OUT 引脚悬空,当选用无源晶振时,时钟从OSC_IN 和OSC_OUT 进入,并且要配谐振电容
HSE 常用8M 的无源晶振。当确定PLL 时钟来源的时候,HSE 可以不分频或者2分频
HSI内部高速的时钟信号:频率为8M,根据温度和环境的情况频率会有漂移,使用场景:当HSE 故障的时候,如果PLL 的时钟来源是HSE,那么当HSE 故障的时候,不仅HSE 不能使用,连PLL 也会被关闭,这个时候系统会自动切换HSI 作为系统时钟
PLL(锁相环)时钟源:PLL 时钟来源可以有两个,一个来自HSE,另外一个是HSI/2,具体用哪个由时钟配置寄存器CFGR 的位16:PLLSRC 设置。HSI一般不作为PLL 的时钟来源
锁相环时钟PLLCLK:通过设置PLL 的倍频因子,可以对PLL 的时钟来源进行倍频,倍频因子可以是:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]。我们这里设置为9 倍频,因为上一步设置PLL的时钟来源为HSE=8M,所以经过PLL 倍频之后的PLL 时钟:PLLCLK = 8M *9 =72M。72M 是ST 官方推荐的稳定运行时钟,如果想超频的话,增大倍频因子即可,最高为128M。这里设置PLL 时钟:PLLCLK = 8M *9 = 72M
系统时钟SYSCLK:系统时钟来源可以是:HSI、PLLCLK、HSE。使用HSE,系统时钟SYSCLK 最高是128M。启动文件:statup_stm32f10x_hd.s 已经调用SystemInit() 函数把系统时钟初始化成72MHZ,SystemInit()在库文件:system_stm32f10x.c 中定义。这里设置系统时钟:SYSCLK = PLLCLK = 72M
AHB 总线时钟HCLK:系统时钟SYSCLK 经过AHB 预分频器分频之后得到时钟叫APB 总线时钟,即HCLK,分频因子可以是:[1,2,4,8,16,64,128,256,512]。片上大部分外设的时钟都是经过HCLK 分频得到,至于AHB总线上的外设的时钟设置为多少,得等到我们使用该外设的时候才设置,这里只需粗线条的设置好APB 的时钟即可。这里设置为1分频,即HCLK=SYSCLK=72M(高速总线)
APB2 总线时钟PCLK2:APB2 总线时钟PCLK2 由HCLK 经过高速APB2 预分频器得到,分频因子可以是:[1,2,4,8,16],具体由时钟配置寄存器CFGR 的位13-11:PPRE2[2:0] 决定。PCLK2属于高速的总线时钟,片上高速的外设就挂载到这条总线上,比如全部的GPIO、USART1、SPI1 等。至于APB2 总线上的外设的时钟设置为多少,得等到我们使用该外设的时候才设置,这里只需粗线条的设置好APB2 的时钟即可。我们设置为1 分频,即PCLK2 = HCLK = 72M(高速总线)
RCC
RCC :reset clock control 复位和时钟控制器。设置系统时钟SYSCLK、设置AHB 分频因子(决定HCLK 等于多少)、设置APB2 分频因子(决定PCLK2 等于多少)、设置APB1 分频因子(决定PCLK1 等于多少)、设置各个外设的分频因子;控制AHB、APB2 和APB1 这三条总线时钟的开启、控制每个外设的时钟的开启。函数时钟系统时钟函数:**SetSysClockTo72();**这个函数是库的默认系统时钟设置函数,该函数截取自固件库文件system_stm32f10x.c。该函数的功能是利用HSE 把时钟设置为:PCLK2 = HCLK = SYSCLK = 72M,PCLK1=HCLK/2 = 36M
中断系统
STM32的中断系统主要有几个关键点:中断向量表、NVIC(内嵌向量中断控制器)、中断使能、中断服务函数
中断向量表
中断向量表是一个表,这个表里面存放的是中断向量。中断服务程序的入口地址或存放中断服务程序的首地址成为中断向量,因此中断向量表是一系列中断服务程序入口地址组成的表。这些中断服务程序(函数)在中断向量表中的位置是由半导体厂商定好的,当某个中断被触发以后就会自动跳转到中断向量表中对应的中断服务程序(函数)入口地址处。中断向量表在整个程序的最前面,比如STM32F103的中断向量表如下所示:
中断向量表都是链接到代码的最前面,比如一般ARM处理器都是从地址0X00000000开始执行指令的,那么中断向量表就是从0X00000000开始存放的。代码中第1行的“__initial_sp”就是第一条中断向量,存放的是栈顶指针,接下来是第2行复位中断复位函数Reset_Handler的入口地址,直到第27行的最后一个中断服务函数的入口地址,这样STM32F103的中断向量表就建好了。
中断向量表偏移
STM32的代码是下载到0X8000000开始的存储区域中。因此中断向量表是存放到0X8000000地址处的,而不是0X00000000?为了解决这个问题,Cortex-M架构引入了一个新的概念——中断向量表偏移,通过中断向量表偏移就可以将中断向量表存放到任意地址,中断向量表偏移配置在函数SystemInit中完成,通过向SCB_VTOR寄存器写入新的中断向量表首地址即可,代码如下所示:
NVIC(内嵌向量中断控制器)
对于STM32这种Cortex-M内核的单片机来说,中断系统的管理机构叫做NVIC,全称叫做Nested Vectored Interrupt Controller
SysTick(系统定时器)
属于CM3内核中的一个外设,内嵌在NVIC中,有关寄存器的定义和库函数在core_cm3.h中。系统定时器是一个24bit的向下递减的计数器,计数器每计数一次的时间为1/SYSCLK,一般设置系统时钟SYSCLK等于72M。当重装载数值寄存器的值递减到0 的时候,系统定时器就产生一次中断,以此循环往复。系统定时器一般用于操作系统,用于产生时基,维持操作系统的心跳
内核外设的优先级:因为SysTick 属于内核外设,所以没有抢占优先级和子优先级。如果要修改内核外设的优先级,只需要修改内核SCB 这个外设的寄存器:SHPRx(x=1.2.3)对应的某个字段即可
SysTick—系统定时器有4个寄存器。在使用SysTick 产生定时的时候,只需要配置前三个寄存器,最后一个校准寄存器不需要使用
Counter(递减计数器)在时钟的驱动下,从reload(重装载寄存器)初值开始往下递减计数到0,产生中断和置位COUNTFLAG标志。然后又从reload值开始重新递减计数,如此循环
定时时间计算:
t = reload ( 1/clk )
Clk = 72M时,t = (72)(1/ 72 M )= 1US
Clk = 72M时,t = (72000)(1/ 72 M )= 1MS
1-t:一个计数循环的时间,跟reload和CLK有关(一般使用ms)
2-CLK:72M或者9M,由CTRL寄存器配置
3-RELOAD:24位,用户自己配置
时间单位换算:
1s = 1000ms = 1000 000 us = 1000 000 000ns
区分内核外设和片上外设的中断优先级:
比如配置一个外设的中断优先级分组为2,抢占优先级为1,子优先级也为1,systick 的优先级为固件库默认配置的15。当我们比较内核外设和片上外设的中断优先级的时候,我们只需要抓住NVIC 的中断优先级分组不仅对片上外设有效,同样对内核的外设也有效。我们把systick 的优先级15 转换成二进制值就是1111(0b),又因为NVIC 的优先级分组2,那么前两位的11(0b) 就是3,后两位的11(0b) 也是3。无论从抢占还是子优先级都比我们设定的外设的优先级低。如果当两个的软件优先级都配置成一样,那么就比较他们在中断向量表中的硬件编号,编号越小,优先级越高
中断服务函数
当中断发生以后中断服务函数就会被调用,我们要处理的工作就可以放到中断服务函数中去完成。以STM32F103的EXTI为例,其中断服务函数如下所示
F103在内核水平上搭载了一个异常响应系统,支持系统异常和外部中断。具体的系统异常和外部中断可在标准库文件stm32f10x.h 这个头文件查询到,在IRQn_Type 这个结构体里面包含了F103 系列全部的异常声明
中断优先级
在NVIC中中断优先级寄存器NVIC_IPRx,用来配置中断的优先级,数值越小,优先级越高。绝大多数CM3芯片会精简设计,实际上支持的优先级数减少,在F103中,只使用了高4bit
抢占(主)优先级和子优先级(响应优先级):用于表达外部中断优先级的这4bit,又被分组成抢占优先级和子优先级。如果有多个中断同时响应,抢占优先级高的就会抢占抢占优先级低的优先得到执行(抢占优先级支持嵌套),如果抢占优先级相同,就比较子优先级。如果抢占优先级和子优先级都相同的话,就比较他们的硬件中断编号(中断向量表里的位置),编号越小,优先级越高,如果优先级分组为0,则抢占优先级就不存在,优先级就全部由子优先级控制。设置优先级分组可调用库函数NVIC_PriorityGroupConfig()实现。NVIC_PriorityGroupConfig整个程序中只需要设置一次,NVIC_PriorityGroupConfig适合放在main()函数中
中断服务函数
在启动文件startup_stm32f10x_hd.s中预先为每个中断都写了一个中断服务函数,只是初始化中断向量表。实际的中断服务函数都需要重新编写,为了方便管理,一般把中断服务函数统一写在stm32f10x_it.c库文件中。中断服务函数的函数名必须跟启动文件里面预先设置的一样,如果写错,系统就在中断向量表中找不到中断服务函数的入口,直接跳转到启动文件里面预先写好的空函数,并且在里面无限循环,实现不了中断
EXTI(外部中断/事件控制器)
EXTI(External interrupt/event controller,外部中断/事件控制器):管理了控制器的20 个中断/事件线,EXTI0至EXTI15用于GPIO,通过编程控制可以实现任意一个GPIO作为EXTI 的输入,其余用于特定的外设事件。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测。EXTI可以实现对每个中断/事件线进行单独配置,可以单独配置为中断或者事件,以及触发事件的属性。EXTI在APB2总线上。配置EXTI信号源的时候需要用到AFIO的外部中断控制寄存器AFIO_EXTICRx
EXTI(外部中断/事件控制器)功能框图
1.很多信号线上打一个斜杠并标注“20”字样,表示在控制器内部类似的信号线路有20个,与EXTI有20个中断/事件线吻合。只要明白其中一个的原理,其他线路原理也就知道了
2.EXTI 可分为两大部分功能,一个是产生中断,另一个是产生事件,这两个功能从硬件上就有所不同
红色虚线指示的电路流程是一个产生中断的线路,最终信号流入到NVIC控制器内。产生中断线路目的是把输入信号输入到NVIC,进一步会运行中断服务函数,实现功能,这样是软件级的
编号1 是输入线,EXTI 控制器中断/事件输入线可以通过寄存器设置为任意一个GPIO,也可以是一些外设的事件。输入线一般是存在电平变化的信号
编号2是一个边沿检测电路,它会根据上升沿触发选择寄存器(EXTI_RTSR) 和下降沿触发选择寄存器(EXTI_FTSR) 对应位的设置来控制信号触发。这两个寄存器可以控制器需要检测哪些类型的电平跳变过程,可以是只有上升沿触发、只有下降沿触发或者上升沿和下降沿都触发。边沿检测电路以输入线作为信号输入端,如果检测到有边沿跳变就输出有效信号1给编号3电路,否则输出无效信号0
编号3电路是一个或门电路,它一个输入来自编号2电路,另外一个输入来自软件中断事件寄存器(EXTI_SWIER)。EXTI_SWIER允许通过程序控制就可以启动中断/事件线。这两个输入一个有有效信号1就可以输出1 给编号4和编号6电路
编号4电路是一个与门电路,它一个输入是编号3 电路,另外一个输入来自中断屏蔽寄存器(EXTI_IMR),可以控制EXTI_IMR来实现是否产生中断。编号4电路输出的信号会被保存到挂起寄存器(EXTI_PR)内,如果确定编号4电路输出为1就会把EXTI_PR对应位置1
编号5将EXTI_PR寄存器内容输出到NVIC,从而实现系统中断事件控制
绿色虚线指示的电路流程是一个产生事件的线路,最终输出一个脉冲信号。产生事件线路目的是传输一个脉冲信号给其他外设(ADC采集、TIM定时)使用,并且是电路级别的信号传输,属于硬件级的
产生事件线路是在编号3电路之后与中断线路有所不同,之前电路都是共用的。编号6 电路是一个与门,它一个输入来自编号3 电路,另外一个输入来自事件屏蔽寄存器(EXTI_EMR)。如果EXTI_EMR 设置为0 时,最终编号6 电路输出的信号都为0;如果EXTI_EMR 设置为1 时,最终编号6 电路输出的信号才由编号3 电路的输出信号决定,可以控制EXTI_EMR 来实现是否产生事件
编号7是一个脉冲发生器电路,当输入端(编号6电路的输出端),是一个有效信号1时就会产生一个脉冲;如果输入端是无效信号就不会输出脉冲
编号8是一个脉冲信号,是产生事件的线路最终的产物,这个脉冲信号可以给其他外设电路使用,比如定时器TIM、模拟数字转换器ADC 等等,这样的脉冲信号一般用来触发TIM 或者ADC开始转换
GPIO
电流、电压(电气属性)相关术语
灌电流:输出高电平时,电流输出到负载,叫灌电流,即推
拉电流:输出低电平时,负载电流流向芯片,叫拉电流,即挽。
高阻态:引脚既不输出高电平,也不输出低电平,为高阻态
电平不匹配:如需要输出5 伏的高电平,就可以在外部接一个上拉电阻,上拉电源为5伏,并且把GPIO 设置为开漏模式,当输出高阻态时,由上拉电阻和电源向外输出5 伏的电平
TTL、CMOS、RS232电平标准如上
GPIO结构框图
保护二级管:引脚的两个保护二级管可以防止引脚外部过高或过低的电压输入,当引脚电压高于VDD(3.3V)时,上方的二极管导通,当引脚电压低于VSS(0V)时,下方的二极管导通,防止不正常电压引入芯片导致芯片烧毁
STM32的引脚直接外接大功率驱动器件,如直接驱动电机,强制驱动要么电机不转,要么导致芯片烧坏:电机启动有反向电流、反向电动势,电压有过冲,尖峰时间短,二极管没有起到开关的作用,过冲电压直接进入芯片内部,烧毁芯片。必须要加大功率及隔离电路驱动
GPIO输出模式
推挽输出模式一般应用在输出电平为0(VSS)和3.3伏(VDD)而且需要高速切换开关状态的场合。在STM32的应用中一般使用推挽输出模式,除了必须用开漏模式的场合。
推挽输出模式:在该结构中输入高电平时,经过反向后,上方的P-MOS 导通,下方的N-MOS 关闭,对外输出高电平;而在该结构中输入低电平时,经过反向后,N-MOS 管导通,P-MOS 关闭,对外输出低电平。当引脚高低电平切换时,两个管子轮流导通,P 管负责灌电流,N 管负责拉电流,使其负载能力和开关速度都比普通的方式有很大的提高
1、可以输出高低电平,用于连接数字器件,高电平由VDD决定,低电平由VSS决定
2、推挽结构指两个三极管受两路互补的信号控制,总是在一个导通的时候另外一个截止,优点开关效率效率高,电流大,驱动能力强
3、输出高电平时,电流输出到负载,叫灌电流,即推,输出低电平时,负载电流流向芯片,叫拉电流,即挽
开漏输出模式:上方的P-MOS 管完全不工作。如果控制输出为0,低电平,则P-MOS管关闭,N-MOS 管导通,使输出接地,若控制输出为1 (它无法直接输出高电平) 时,则P-MOS管和N-MOS 管都关闭,此时引脚既不输出高电平,也不输出低电平,为高阻态。为正常使用时必须外部接上拉电阻。它具有“线与”特性,也就是说,若有很多个开漏模式引脚连接到一起时,只有当所有引脚都输出高阻态,才由上拉电阻提供高电平。若其中一个引脚为低电平,那线路就相当于短路接地,使得整条线路都为低电平,0伏
1、只能输出低电平,不能输出高电平
2、如果要输出高电平,则需要外接上拉。(此高电平的电压为外部上拉电阻所接的电源的电压)
3、开漏输出具有“线与”功能,一个为低,全部为低,开漏输出一般应用在I2C、SMBUS 通讯等需要“线与”功能的总线电路中和电平不匹配的场合
复用功能输出模式: “复用功能输出”中的“复用”是指STM32 的其它片上外设对GPIO 引脚进行控制,此时GPIO 引脚用作该外设功能的一部分,算是第二用途
例如(串口TX)使用USART 串口通讯时,需要用到某个GPIO 引脚作为通讯发送引脚,这个时候就可以把该GPIO 引脚配置成USART 串口复用功能,由串口外设控制该引脚,发送数据
模拟输出模式:当GPIO 引脚用于DAC 作为模拟电压输出通道时,此时作为“模拟输出”功能,DAC 的模拟信号输出就不经过双MOS 管结构,模拟信号直接输出到引脚
GPIO输入模式
在输入模式(模拟/浮空/上拉/下拉)时,施密特触发器(TTL肖特基触发器,TTL输入,高于2V为1,低于1.2V为0)打开,输出被禁止,上拉和下拉输入,默认的电平由上拉或者下拉决定。浮空输入的电平是不确定的,完全由外部的输入决定,一般接按键的时候用的是这个模式。模拟输入则用于ADC 采集
上/下拉输入模式:GPIO 结构框图的上半部分,GPIO 引脚经过内部的上、下拉电阻,可以配置成上/下拉输入,然后再连接到施密特触发器,信号经过触发器后,模拟信号转化为0、1 的数字信号,然后存储在“输入数据寄存器GPIOx_IDR”中,通过读取该寄存器就可以了解GPIO 引脚的电平状态
模拟输入模式:“当GPIO 引脚用于ADC 采集电压的输入通道时,用作“模拟输入”功能,此时信号是不经过施密特触发器的,因为经过施密特触发器后信号只有0、1 两种状态,所以ADC 外设要采集到原始的模拟信号,信号源输入必须在施密特触发器之前。
模拟输入用于ADC 采集
浮空输入模式:浮空输入的电平是不确定的,完全由外部的输入决定,
一般接按键的时候用的是浮空模式
复用输入模式:在“复用功能输入模式”时,GPIO 引脚的信号传输到STM32 其它片上外设,由该外设读取引脚状态
例如使用USART 串口通讯时,需要用到某个GPIO 引脚作为通讯接收引脚,这个时候就可以把该GPIO 引脚配置成USART 串口复用功能,使USART 可以通过该通讯引脚的接收远端数据
通讯
通讯分类、常用概念
UART串行异步全双工、SPI串行同步半双工、I2C串行同步全双工
串行通讯:串行通讯是指设备之间通过少量数据信号线(一般是8 根以下),地线以及控制信号线,同一时刻只能传输一个数据位的数据(USART、I2C、SPI)
并行通讯:并行通讯一般是指使用8、16、32 及64 根或更多的数据线进行传输的通讯方式,可以同时传输多个数据位的数据(SDIO、FSMC)
在数据传输速率相同的情况下,并行通讯传输的数据量要大得多,而串行通讯则可以节省数据线的硬件成本(特别是远距离时) 以及PCB 的布线面积
根据通讯方向,通讯分为全双工、半双工、单工通讯
同步通讯:在同步通讯中,收发设备双方会使用一根信号线表示时钟信号,在时钟信号的驱动下双方进行协调,同步数据。通讯中通常双方会统一规定在时钟信号的上升沿或下降沿对数据线进行采样
异步通讯:在异步通讯中不使用时钟信号进行数据同步,它们直接在数据信号中穿插一些同步用的信号位,或者把主体数据进行打包,以数据帧的格式传输数据,某些通讯中由于没有时钟信号,所以两个通讯设备之间需要约定好波特率,以便对信号进行解码
通讯速率:衡量通讯性能的重要参数,通常以比特率(Bitrate)来表示
比特率(Bitrate):单位时间内传输的比特数,单位bit/s(bps)。
波特率(Baudrate):指数据信号对载波的调制速率,它用单位时间内载波调制状态改变次数来表示,单位为波特。每秒钟传输了多少个码元。
码元:码元是通讯信号调制的概念,通讯中常用时间间隔相同的符号来表示一个二进制数字,这样的信号称为码元。如常见的通讯传输中,用0V表示数字0,5V表示数字1,那么一个码元可以表示两种状态0和1,所以一个码元等于一个二进制比特位,此时波特率的大小与比特率一致;如果在通讯传输中,有0V、2V、4V 以及6V 分别表示二进制数00、01、10、11,那么每个码元可以表示四种状态,即两个二进制比特位,所以码元数是二进制比特位数的一半,这个时候的波特率为比特率的一半
通讯协议的内容可以分为物理层和协议层
物理层:物理层规定通讯系统中具有机械、电子功能部分的特性,确保原始数据在物理媒体的传输
协议层:协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准
RS-232
串口通信和串行通信的区别:
串口通信和串行通信是两个不同的概念。
串口通信(Serial Port Communication)是一种通过串行接口进行的数据传输方式。在计算机中,串口通常指的是RS-232串口(串口通讯的物理层有很多标准及变种, RS-232标准主要规定了信号的用途、通讯接口以及信号的电平标准),它是一种标准的串行通信接口,用于在计算机和外部设备之间传输数据。串口通信可以通过串行线路传输数据,一次只能传输一个比特,数据传输速率相对较慢。串口通信常用于连接设备,如打印机、调制解调器、传感器等。
串行通信(Serial Communication)是一种通过串行传输方式进行的数据传输方式。在串行通信中,数据按照一定的顺序一个接一个地传输,每个数据位逐个传输。串行通信可以使用多种物理接口,包括串口、USB、以太网等。串行通信速率可以很高,但需要较为复杂的通信协议和处理方式。
因此,串口通信是一种串行通信的实现方式,而串行通信则是一种更为通用的数据传输方式。
物理层
RS-232电平标准的信号不能直接被控制器直接识别,这些信号会经过一个“电平转换芯片”(MA3232\SP3232芯片)转换成控制器能识别的“TTL标准”的电平信号,才能实现通讯
串口通讯中一般只使用RXD、TXD 以及GND三条信号线,传输数据信号,RTS、CTS、DSR、DTR、DCD信号被裁剪掉了。串口通讯的数据包由发送设备的TXD接口传输到接收设备的RXD接口
协议层
在串口通讯的协议层中,规定了数据包的内容,它由启始位、主体数据、校验位以及停止位组成,通讯双方的数据包格式要约定一致才能正常收发数据
通讯的起始和停止信号:串口通讯的一个数据包从起始信号开始,直到停止信号结束。数据包的起始信号由一个逻辑0 的数据位表示,数据包的停止信号可由0.5、1、1.5 或2 个逻辑1 的数据位表示,只要双方约定一致即可
有效数据:在数据包的起始位之后紧接着的就是要传输的主体数据内容,也称为有效数据,有效数据的长度常被约定为5、6、7 或8 位长。
数据校验:由于数据通信相对更容易受到外部干扰导致传输数据出现偏差,在有效数据之后,有一个可选的数据校验位。校验方法有奇校验(odd)、偶校验(even)、0校验(space)、1校验(mark)以及无校验(noparity)。奇校验要求有效数据和校验位中“1”的个数为奇数,偶校验要求帧数据和校验位中“1”的个数为偶数,0校验校验位总为“0”,1校验是校验位总为“1”
I2C
I2C通讯协议(Inter-Integrated Circuit) :由Phiilps公司开发,只有两根引脚,由于它引脚少,硬件实现简单,可扩展性强,不需要USART、CAN等通讯协议的外部收发设备,被广泛应用在系统内多个集成电路(IC)间的通讯
在参考手册查找GPIO配置模式
物理层
(1)它是一个支持设备的总线。在一个I2C通讯总线中,可连接多个I2C通讯设备,支持多个通讯主机及多个通讯从机
(2)一个I2C总线使用两条总线线路,双向串行数据线(SDA)用来表示数据,串行时钟线(SCL) 用于数据收发同步
(3)寻址,每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备之间的访问
(4)总线通过上拉电阻(一根总线一个电阻,共两个,一般4.7kΩ,防止其他设备干扰)接电源。当I2C设备空闲,会输出高阻态(可以理解为线路断开),当所有设备都空闲,由上拉电阻把总线拉成高电平
(5)多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占用总线
(6)GPIO采用开漏输出模式(输出高阻态),具有三种传输模式:标准模式传输速率为100kbit/s,快速模式为400kbit/s ,高速模式下可达3.4Mbit/s,但目前大多I2C设备尚不支持高速模式
(7)电气特性要求,连接到相同总线的IC数量受到总线的最大电容400pF限制
协议层
I2C 的协议定义了通讯的起始和停止信号、数据有效性、响应、仲裁、时钟同步和地址广播等环节
数据有效性
I2C使用SDA信号线来传输数据,使用SCL信号线进行数据同步。SDA数据线在SCL的每个时钟周期传输一位数据。传输时,SCL为高电平的时候SDA表示的数据有效iiiiiii即此时的SDA为高电平时表示数据“1”,为低电平时表示数据“0”。当SCL为低电平时,SDA的数据无效,一般在这个时候SDA进行电平切换,为下一次表示数据做好准备。每次数据传输都以字节为单位,每次传输的字节数不受限制
传输起始信号(S)
由主机的I2C接口产生的传输起始信号(S),这时连接到I2C总线上的所有从机都会接收到这个信号。当SCL线是高电平时,SDA线从高电平向低电平(下降沿)切换,表示通讯的起始。当SCL是高电平时,SDA线由低电平向高电平(上升沿)切换,表示通讯的停止
从机地址信号(SLAVE_ADDRESS)*
起始信号产生后,所有从机就开始等待主机通过SDA信号线广播的从机地址信号。当主机广播的地址与某个设备地址相同时,这个设备就被选中了,没被选中的设备将会忽略之后的数据信号。I2C协议规定设备地址可以是7位或10位,实际中7位的地址应用比较广泛
传输方向的选择位
在地址位之后一个数据位用来表示数据传输方向,它是数据方向位(R/),第8位或第11位。为0时,数据传输方向是由主机传输至从机,即主机向从机写数据。为1时,主机由从机读数据
响应
I2C的数据和地址传输都带响应。响应包括“应答(ACK)”和“非应答(NACK)”两种信号。从机接收到匹配的地址后,主机或从机会返回一个应答(ACK) 或非应答(NACK) 信号,只有接收到应答信号后,主机才能继续发送或接收数据。若向对方发送“非应答(NACK)”信号,发送方接收到该信号后会产生一个停止信号,结束信号传输。SDA为高电平,表示非应答信号(NACK),SDA低电平表示应答信号(ACK)
SDA线的数据包序列高位先行发送
主机写数据到从机:主机产生起始信号,广播完地址,接收到应答信号后,主机开始正式向从机传输数据(DATA),数据包的大小为8 位,主机每发送完一个字节数据,都要等待从机的应答信号(ACK),重复这个过程,可以向从机传输N个数据,这个N没有大小限制。当数据传输结束时,主机向从机发送一个停止传输信号§,表示不再传输数据
主机读从机数据:主机产生起始信号,广播完地址,接收到应答信号后,从机开始向主机返回数据(DATA),数据包大小也为8位,从机每发送完一个数据,都会等待主机的应答信号(ACK),重复这个过程,可以返回N个数据,N没有大小限制。当主机希望停止接收数据时,就向从机返回一个非应答信号(NACK),则从机自动停止数据传输
复合格式:传输过程有两次起始信号(S)。一般在第一次传输中,主机通过SLAVE_ADDRESS 寻找到从设备后,发送一段“数据”,通常用于表示从设备内部的寄存器或存储器地址;在第二次的传输中,对该地址的内容进行读或写。也就是说,第一次通讯是告诉从机读写地址,第二次则是读写的实际内容。一般第一次传输是主机写数据到从机(选择存储单元),第二次传输是主机读从机数据(读存储单元的内容)
STM32的I2C外设
软件模拟协议:由CPU控制每个时刻的引脚状态,直接控制STM32的两个GPIO引脚电平,分别用作SCL及SDA,按照上述信号的时序要求,就可以实现I2C通讯。按照USART的要求去控制引脚,能实现USART通讯
硬件协议:STM32的I2C片上外设专门负责实现I2C通讯协议,只要配置好该外设,它就会自动根据协议要求产生通讯信号,收发数据并缓存起来,CPU只要检测该外设的状态和访问数据寄存器,就能完成数据收发。这种由硬件外设处理I2C协议的方式减轻了CPU的工作,且使软件设计更加简单
STM32的I2C外设:可用作通讯的主机及从机,支持100Kbit/s和400Kbit/s的速率(通讯双方都要支持),支持7 位、10位设备地址,支持DMA数据传输,并具有数据校验功能。I2C外设支持SMBus2.0协议,SMBus协议与I2C类似,主要应用于笔记本电脑的电池管理中
通讯引脚:SCL和SDA连接I2C总线的两个引脚,(SMBA用于SMBUS的警告信号)。I2C外设的I2C通讯信号引出到不同的GPIO引脚上,使用时配置到这些引脚
时钟控制逻辑:配置I2C 的CCR 寄存器可修改通讯速率相关的参数
数据控制逻辑:I2C的SDA连接到数据移位寄存器上,数据移位寄存器的数据来源及目标是数据寄存器(DR)、地址寄存器(OAR)、PEC寄存器以及SDA数据线。
当向外发送数据的时候,数据移位寄存器以“数据寄存器”为数据源,把数据一位一位地通过SDA信号线发送出去
当从外部接收数据的时候,数据移位寄存器把SDA信号线采样到的数据一位一位地存到“数据寄存器”中。若使能了数据校验,接收到的数据会经过PCE计算器运算,运算结果存储在“PEC寄存器”中。当STM32的I2C工作在从机模式,接收到设备地址信号时,比较器会把接收到的地址与STM32的 “I2C 地址寄存器”的值作比较,以便响应主机的寻址。STM32的I2C地址可通过修改“自身地址寄存器”修改,支持同时使用两个I2C设备地址,两个地址分别存储在OAR1和OAR2中
整体控制逻辑:控制逻辑的工作模式根据 “控制寄存器(CR1/CR2)”的参数而改变。在外设工作时,控制逻辑会根据外设的工作状态修改“状态寄存器(SR1 和SR2)”,读取这些寄存器相关的寄存器位,了解I2C的工作状态。控制逻辑根据要求,控制产生I2C中断信号、DMA请求及各种I2C的通讯信号(起始、停止、响应信号等
通讯过程,使用I2C外设通讯时,读取“状态寄存器(SR1及SR2)”的寄存器标志来了解通讯状态
主发送器:作为I2C通讯的主机端时,向外发送数据
主发送器发送流程及事件:
(1)控制产生起始信号(S):当发生起始信号后,产生事件“EV5”,并会对SR1寄存器的“SB”位置1,表示起始信号已经发送;
(2)发送设备地址并等待应答信号:若有从机应答,产生事件“EV6”及“EV8”,并会对SR1寄存器的“ADDR”位及“TXE”位置1,ADDR为1表示地址已经发送,TXE为1表示数据寄存器为空
(3)对ADDR位清零后,往I2C的“数据寄存器DR”写入要发送的数据,TXE位会被重置0,表示数据寄存器非空,I2C外设通过SDA信号线一位位把数据发送出去后,产生“EV8”事件,即TXE位被置1,重复这个过程,就可以发送多个字节数据了
(4) 当发送数据完成后,控制I2C设备产生一个停止信号§,产生EV8_2 事件,SR1的TXE 位及BTF位都被置1,表示通讯结束。
假如使能了I2C中断,以上所有事件产生时,都会产生I2C中断信号,进入同一个中断服务
函数,到I2C中断服务程序后,再通过检查寄存器位来判断是哪一个事件
主接收器:作为I2C通讯的主机端时,从外部接收数据
主接收器接收流程及事件:
(1)起始信号(S):由主机端产生,控制发生起始信号后,产生事件“EV5”,并会对SR1寄存器的“SB”位置1,表示起始信号已经发送
(2)发送设备地址并等待应答信号:若有从机应答,产生事件“EV6”,SR1寄存器的“ADDR”位被置1,表示地址已经发送
(3)从机端接收到地址后,开始向主机端发送数据。当主机接收到这些数据后,产生“EV7”事件,SR1寄存器的RXNE被置1,表示接收数据寄存器非空,读取该寄存器后,可对数据寄存器清空,以便接收下一次数据。此时可以控制I2C发送应答信号(ACK) 或非应答信号(NACK),若应答,则重复以上步骤接收数据,若非应答,则停止传输
(4)发送非应答信号后,产生停止信号§,结束传输
在发送和接收过程中,有的事件不只是标志了上面提到的状态位,还可能同时标志主机状态之类的状态位,而且读了之后还需要清除标志位,比较复杂。可使用STM32标准库函数来直接检测这些事件的复合标志,降低编程难度
SPI
SPI(Serial Peripheral Interface,串行外围设备接口):SPI是由摩托罗拉公司提出的通讯协议,是一种高速(I2C一般用在低速的场合)全双工的通信总线。被广泛应用在ADC、LCD 等设备与MCU 间,要求通讯速率较高的场合
物理层
SPI通讯当有多个SPI从设备与SPI主机相连时,设备的信号线SCK、MOSI及MISO同时并联到相同的SPI总线上,从设备共用这3条总线;每个从设备都有独立的这一条NSS信号线,本信号线独占主机的一个引脚,有多少个从设备,就有多少条片选信号线
(1) NSS/CS(Slave Select,从设备选择信号线,片选信号线):I2C协议中通过设备地址来寻址、选中总线上的某个设备并与其进行通讯;SPI协议中没有设备地址,使用NSS信号线寻址,当主机要选择从设备时,把该从设备的NSS 信号线设置为低电平,该从设备即被选中,即片选有效,接着主机开始与被选中的从设备进行SPI通讯。SPI通讯以NSS线置低电平为开始信号,以NSS线被拉高作为结束信号
(2) SCK(Serial Clock,时钟信号线):用于通讯数据同步。由通讯主机产生,决定了通讯的速率,不同的设备支持的最高时钟频率不一样,如STM32的SPI时钟频率最大为fpclk/2,两个设备之间通讯时,通讯速率受限于低速设备
(3) MOSI(Master Output,Slave Input,主设备输出/从设备输入引脚):主机的数据从这条信号线输出,从机由这条信号线读入主机发送的数据,即这条线上数据的方向为主机到从机
(4) MISO(Master Input,,Slave Output,主设备输入/从设备输出引脚):主机从这条信号线读入数据,从机的数据由这条信号线输出到主机,即在这条线上数据的方向为从机到主机
协议层
SPI协议定义了通讯的起始和停止信号、数据有效性、时钟同步等环节
NSS、SCK、MOSI信号由主机控制产生,而MISO的信号由从机产生,主机通过该信号线读取从机的数据。MOSI与MISO的信号只在NSS为低电平的时候才有效,在SCK的每个时钟周期MOSI和MISO传输一位数据
NSS、SCK、MOSI信号由主机控制产生,而MISO的信号由从机产生,主机通过该信号线读取从机的数据。MOSI与MISO的信号只在NSS为低电平的时候才有效,在SCK的每个时钟周期MOSI和MISO传输一位数据
通讯的起始和停止信号
NSS信号线由高变低,是SPI通讯的起始信号。NSS是每个从机各自独占的信号线,当从机在自己的NSS线检测到起始信号后,从机被主机选中,开始准备与主机通讯。NSS信号由低变高,是SPI通讯的停止信号,表示本次通讯结束,从机的选中状态被取消
数据有效性
SPI使用MOSI及MISO信号线来传输数据,使用SCK信号线进行数据同步。MOSI及MISO数据线在SCK的每个时钟周期传输一位数据,且数据输入输出是同时进行的。数据传输时,MSB先行或LSB先行没有规定,但要保证两个SPI通讯设备之间使用同样的协定,一般都会MSB先行模式。MOSI及MISO的数据在SCK的上升沿时变化输出,在SCK的下降沿时被采样。在SCK的下降沿时刻,高电平时表示数据“1”,低电平时表示数据“0”。其它时刻,数据无效,MOSI及MISO为下一次表示数据做准备。SPI每次数据传输以8位或16位为单位,每次传输的单位数不受限制
CPOL(时钟极性)/CPHA及通讯模式
上面中的SPI通讯时序只是一种通讯模式,SPI 一共有四种通讯模式,主要区别是总线空闲时SCK的时钟状态以及数据采样时刻。CPOL 是SPI 通讯设备处于空闲状态时(SPI通讯开始前、NSS 线为高电平时),SCK信号线的电平信号。CPOL=0时,SCK在空闲状态时为低电平,CPOL=1时,则相时钟相位CPHA是指数据的采样的时刻,当CPHA=0时,MOSI或MISO数据线上的信号将会在SCK时钟线的“奇数边沿”被采样。当CPHA=1时,数据线在SCK 的“偶数边沿”采样
由CPOL及CPHA的不同状态,SPI分成了四种模式,主机与从机需要工作在相同的模式下才可以正常通讯,实际中采用较多的是“模式0”与“模式3”
CPHA=0的时序图
SCK信号线在空闲状态为低电平时,CPOL=0;空闲状态为高电平时,CPOL=1。无论CPOL=0还是=1,采样时刻都是在SCK的奇数边沿,不是由上升/下降沿决定的。当CPOL=0,时钟的奇数边沿是上升沿,当CPOL=1,时钟的奇数边沿是下降沿。MOSI和MISO数据线的有效信号在SCK的奇数边沿保持不变,在非采样时刻,MOSI和MISO的有效信号发生切换
当CPHA=1时,不受CPOL的影响,数据信号在SCK的偶数边沿被采样
STM32的SPI外设
STM32的SPI外设可用作通讯的主机及从机,支持最高SCK时钟频率为fpclk/2 (STM32F103型号的芯片默认fpclk1为36MHz,fpclk2为72MHz),支持SPI协议的4种模式,数据帧长度可设置为8位或16位,可设置数据MSB先行或LSB先行。支持双线全双工、双线单向以及单线模式。双线单向模式可以同时使用MOSI及MISO数据线向一个方向传输数据,可以加快一倍的传输速度。单线模式可以减少硬件接线,速率会受到影响
通讯引脚
STM32芯片SPI外设的SPI通讯信号引出到不同的GPIO引脚上,使用时必须配置到这些指定的引脚。GPIO引脚的复用功能,可查阅《STM32F10x规格书》。SPI1是APB2上的设备,最高通信速率36Mbtis/s,SPI2、SPI3 是APB1上的设备,最高通信速率为18Mbits/s。除了通讯速率,在其它功能上没有差异
时钟控制逻辑
SCK线的时钟信号,由波特率发生器根据“控制寄存器CR1”中的BR[0:2] 位(对fpclk时钟的分频因子)控制,对fpclk的分频结果是SCK引脚的输出时钟频率
数据控制逻辑
SPI的MOSI及MISO连接到数据移位寄存器上,数据移位寄存器的数据来源及目标接收、发送缓冲区以及MISO、MOSI线。当向外发送数据的时候,数据移位寄存器以“发送缓冲区”为数据源,把数据一位一位地通过数据线发送出去;当从外部接收数据的时候,数据移位寄存器把数据线采样到的数据一位一位地存储到“接收缓冲区”中。通过写SPI 的“数据寄存器DR”把数据填充到发送缓冲区中,通讯读“数据寄存器DR”,可以获取接收缓冲区中的内容。其中数据帧长度可以通过“控制寄存器CR1”的“DFF 位”配置成8 位及16 位模式;配置“LSBFIRST 位”可选择MSB 先行还是LSB 先行
整体控制逻辑
负责协调整个SPI外设,控制逻辑的工作模式根据 “控制寄存器(CR1/CR2)”的参数而改变,基本的控制参数包括SPI模式、波特率、LSB 先行、主从模式、单双向模式等等。在外设工作时,控制逻辑会根据外设的工作状态修改“状态寄存器(SR)”,只要读取状态寄存器相关的寄存器位,就可以了解SPI 的工作状态了。除此之外,控制逻辑还根据要求,负责控制产生SPI 中断信号、DMA请求及控制NSS信号线。实际应用中,一般不使用STM32 SPI 外设的标准NSS 信号线,而是使用普通的GPIO,软件控制它的电平输出(推挽输出),从而产生通讯起始和停止信号
通讯过程
STM32使用SPI外设通讯时,在不同阶段会对“状态寄存器SR”的不同数据位写入参数,通过读取这些寄存器标志来了解通讯状态。图中的是“主模式”流程,即STM32 作为SPI通讯的主机端时的数据收发过程。只是接收数据时,也要向发送缓冲区写入某些数据,才能触发SCK引脚产生时钟,时钟才能开启
主模式收发流程及事件:
(1)控制NSS 信号线,产生起始信号(图中没有画出);
(2)把要发送的数据写入到“数据寄存器DR”中,该数据会被存储到发送缓冲区;
(3)通讯开始,SCK时钟开始运行。MOSI把发送缓冲区中的数据一位一位地传输出去;MISO 把数据一位一位地存储进接收缓冲区中
(4)当发送完一帧数据的时候,“状态寄存器SR”中的“TXE 标志位”会被置1,表示传输完一帧,发送缓冲区已空;当接收完一帧数据的时候,“RXNE 标志位”会被置1,表示传输完一帧,接收缓冲区非空
(5)等待到“TXE 标志位”为1时,若还要继续发送数据,则再次往“数据寄存器DR”写入数据即可;等待到“RXNE 标志位”为1时,通过读取“数据寄存器DR”可以获取接收缓冲区中的内容
SPI中断
假如使能了TXE或RXNE中断,TXE或RXNE置1时会产生SPI中断信号,进入同一个中断服务函数,到SPI中断服务程序后,可通过检查寄存器位来了解是哪一个事件,再分别进行处理。也可以使用DMA方式来收发“数据寄存器DR”中的数据
CAN
CAN(Controller Area Network, 控制器局域网络):由德国BOSCH公司开发,并且是国际标准(ISO11519),是国际上应用最广泛的现场总线之一。CAN总线协议已经成为汽车计算机控制系统和嵌入式工业控制局域网的标准总线,并且拥有以CAN 为底层协议专为大型货车和重工机械车辆设计的J1939 协议。近年来,它具有的高可靠性和良好的错误检测能力受到重视,被广泛应用于汽车计算机控制系统和环境温度恶劣、电磁辐射强及振动大的工业环境
物理层
物理层:CAN是一种异步半双工通讯,只有CAN_High和CAN_Low两条信号线,共同构成一组差分信号线,以差分信号的形式进行通讯
CAN物理层的形式主要有两种,CAN闭环总线通讯网络是一种遵循ISO11898标准的高速、短距离“闭环网络”,它的总线最大长度为40m,通信速度最高为1Mbps,总线的两端各要求有一个“120欧”的电阻
CAN开环总线通讯网络是遵循ISO11519-2标准的低速、远距离“开环网络”,它的最大传输距离为1km,最高通讯速率为125kbps,两根总线是独立的、不形成闭环,要求每根总线上各串联有一个“2.2千欧”的电阻
通讯节点:CA总线上可以挂载多个通讯节点,节点之间的信号经过总线传输,实现节点间通讯。由于CAN通讯协议不对节点进行地址编码,而是对数据内容进行编码的,所以网络中的节点个数理论上不受限制,只要总线的负载足够即可,可以通过中继器增强负载。CAN通讯节点由一个CAN控制器及CAN收发器组成,控制器与收发器之间通过CAN_Tx及CAN_Rx信号线相连,收发器与CAN总线之间使用CAN_High及CAN_Low信号线相连。其中CAN_Tx及CAN_Rx使用普通的类似TTL逻辑信号,CAN_High及CAN_Low是一对差分信号线,使用比较特别的差分信号。当CAN节点需要发送数据时,控制器把要发送的二进制编码通过CAN_Tx线发送到收发器,然后由收发器把这个普通的逻辑电平信号转化成差分信号,通过差分线CAN_High 和CAN_Low线输出到CAN总线网络。而通过收发器接收总线上的数据到控制器时,则是相反的过程,收发器把总线上收到的CAN_High 及CAN_Low 信号转化成普通的逻辑电平信号,通过CAN_Rx输出到控制器中。例如:STM32 的CAN片上外设就是通讯节点中的控制器,为了构成完整的节点,还要给它外接一个收发器,例如将型号为TJA1050的芯片作为CAN 收发器。CAN收发器的作用则是把CAN 控制器的TTL 电平信号转换成差分信号(或者相反)
差分信号:差分信号又称差模信号,与传统使用单根信号线电压表示逻辑的方式有区别,使用差分信号传输时,需要两根信号线,这两个信号线的振幅相等,相位相反,通过两根信号线的电压差值来表示逻辑0和逻辑1。使用了V+与V-信号的差值表达出信号。在USB协议、485协议、以太网协议及CAN协议的物理层中,都使用了差分信号传输
相对于单信号线传输的方式,使用差分信号传输具有如下优点:
• 抗干扰能力强,当外界存在噪声干扰时,几乎会同时耦合到两条信号线上,而接收端只关心两个信号的差值,所以外界的共模噪声(例如两根信号线上加了相同的电压)可以被完全抵消
• 能有效抑制它对外部的电磁干扰,同样的道理,由于两根信号的极性相反,他们对外辐射的电磁场可以相互抵消,耦合的越紧密,泄放到外界的电磁能量越少
• 时序定位精确,由于差分信号的开关变化是位于两个信号的交点,而不像普通单端信号依靠高低两个阈值电压判断,因而受工艺,温度的影响小,能降低时序上的误差,同时也更适合于低幅度信号的电路
CAN协议中的差分信号:CAN协议中对CAN_High及CAN_Low表示的差分信号做了规定。以高速CAN协议为例,当表示逻辑1时(隐性电平),CAN_High和CAN_Low线上的电压均为2.5v,即电压差0V;而表示逻辑0时(显性电平),CAN_High的电平为3.5V,CAN_Low线的电平为1.5V,即电压差为2V。例如:当CAN收发器从CAN_Tx线接收到来自CAN控制器的低电平信号时(逻辑0),它会使CAN_High输出3.5V,同时CAN_Low输出1.5V,从而输出显性电平表示逻辑0。在CAN总线中,必须使它处于隐性电平(逻辑1)或显性电平(逻辑0)中的其中一个状态。假如有两个CAN通讯节点,在同一时间,一个输出隐性电平,另一个输出显性电平,类似I2C总线的“线与”特性将使它处于显性电平状态,即可以认为显性具有优先的意味。由于CAN总线协议的物理层只有1对差分线,在一个时刻只能表示一个信号,所以对通讯节点来说,CAN通讯是半双工的,收发数据需要分时进行。在CAN的通讯网络中,因为共用总线,在整个网络中同一时刻只能有一个通讯节点发送信号,其余的节点在该时刻都只能接收
协议层
CAN的波特率及位同步:由于CAN 属于异步通讯,没有时钟信号线,连接在同一个总线网络中的各个节点会像串口异步通讯那样,节点间使用约定好的波特率进行通讯,特别地,CAN还会使用“位同步”的方式来抗干扰、吸收误差,实现对总线电平信号进行正确的采样,确保通讯正常
报文:CAN使用的是两条差分信号线,只能表达一个信号,物理层决定了CAN要配上一套更复杂的协议,CAN 协议对数据、操作命令(如读/写) 以及同步信号进行打包,打包后的这些内容称为报文
CAN的“数据帧”:在原始数据段的前面加上传输起始标签、片选(识别)标签和控制标签,在数据的尾段加上CRC校验标签、应答标签和传输结束标签,把这些内容按特定的格式打包好,就可以用一个通道表达各种信号,标签就起到了协同传输的作用。当整个数据包被传输到其它设备时,只要这些设备按格式去解读,就能还原出原始数据,这样的报文就被称为CAN的“数据帧”
CAN外设:STM32的芯片中具有bxCAN控制器(Basic Extended CAN),支持CAN协议2.0A(不支持扩展帧) 和2.0B(支持扩展帧)标准。支持最高的通讯速率为1Mb/s;可以自动地接收和发送CAN报文,支持使用标准ID和扩展ID的报文;外设中具有3个发送邮箱,发送报文的优先级可以使用软件控制,还可以记录发送的时间;具有2个3级深度的接收FIFO,可使用过滤功能只接收或不接收某些ID号的报文;可配置成自动重发;不支持使用DMA进行数据收发。STM32F105/107系列互联型芯片的CAN外设架构图,图里具有2组CAN控制器,其中CAN1是主设备,框图中的“存储访问控制器”是由CAN1控制的,CAN2无法直接访问存储区域,所以使用CAN2的时候必须使能CAN1外设的时钟。主要包含CAN控制内核、发送邮箱、接收FIFO以及验收筛选器。STM32F103系列芯片跟上述框图类似,但该系列只包含1组CAN控制器,即不包含图中标号的部分
RS485
RS-485:一种工业控制环境中常用的通讯协议,具有抗干扰能力强、传输距离远的特点。RS-485协议由RS-232协议改进而来,协议层不变,只是改进了物理层,因而保留了串口通讯协议应用简单的特点
物理层
物理层:RS-485协议把RS-232的信号改进成差分信号,从而大大提高了抗干扰特性。RS-485和CAN的网络结构组成类似,每个节点都是由一个通讯控制器和一个收发器组成,在RS-485通讯网络中,节点中的串口控制器使用RX与TX信号线连接到收发器上,而收发器通过差分线连接到网络总线,串口控制器与收发器之间一般使用TTL信号传输,收发器与总线则使用差分信号来传输。发送数据时,串口控制器的TX信号经过收发器转换成差分信号传输到总线上,而接收数据时,收发器把总线上的差分信号转化成TTL信号通过RX引脚传输到串口控制器中。RS-485 通讯网络的最大传输距离可达1200米,总线上可挂载128个通讯节点,RS-485网络有一对差分信号线,使用差分信号来表达逻辑,当AB两线间的电压差为-6V~-2V时表示逻辑1,当电压差为+2V-+6V表示逻辑0,在同一时刻只能表达一个信号,通讯是半双工形式的
协议层
RS-485与RS-232的协议层是相同的,使用串口数据包的形式传输数据。由于RS-485 具有强大的组网功能,在基础协议之上还制定了MODBUS协议,被广泛应用在工业控制网络中。基础协议是指前面串口章节中,仅封装了基本数据包格式的协议(基于数据位),MODBUS协议是使用基本数据包组合成通讯帧格式的高层应用协议(基于数据包或字节)。由于RS-485与RS-232的协议层没有区别,进行通讯时,使用STM32的USART外设作为通讯节点中的串口控制器,再外接一个RS-485收发器芯片把USART外设的TTL电平信号转化成RS-485 的差分信号即可
USART(通用同步异步收发器)、UART
一个串行通信设备,可以与外部设备进行全双工数据交换。USART只需两根信号线即可完成双向通信,很多模块都预留USART接口,比如GSM 模块,WIFI 模块、蓝牙模块等等。在硬件设计时,还需要一根“共地线”
应用:一般经常使用USART 来实现控制器与电脑之间的数据传输。这使得调试程序非常方便,比如可以把一些变量的值、函数的返回值、寄存器标志位等等通过USART 发送到串口调试助手,当正式发布程序时再把这些调试信息去除即可
CH340G、CH340、PL2303、CP2102、FT232:电平转接芯片,USB转TTL的IC,利用USART实现开发板与电脑通信
UART:UART在USART基础上裁剪掉了同步通信功能,只有异步通信
STM32F103VET6系统控制器有三个USART 和两个UART, USART1时钟来源于APB2总线时钟,最大频率为72MHz,其他四个的时钟来源于APB1总线时钟,最大频率为36MHz。UART只是异步传输功能,所以没有SCLK、nCTS和nRTS功能引脚
USART重映像
USART结构框图
引脚
TX:发送数据输出引脚
RX:接收数据输入引脚
SCLK:发送器时钟输出引脚。这个引脚仅适用于同步模式
SW_RX:数据接收引脚,只用于单线和智能卡模式,属于内部引脚,没有具体外部引脚
nRTS:请求以发送(Request To Send),n 表示低电平有效。如果使能RTS 流控制,当USART 接收器准备好接收新数据时就会将nRTS 变成低电平;当接收寄存器已满时,nRTS 将被设置为高电平。该引脚只适用于硬件流控制
nCTS:清除以发送(Clear To Send),n 表示低电平有效。如果使能CTS 流控制,发送器在发送下一帧数据之前会检测nCTS 引脚,如果为低电平,表示可以发送数据,如果为高电平则在发送完当前数据帧之后停止发送。该引脚只适用于硬件流控制
数据寄存器
USART数据寄存器(USART_DR) :只有低9位有效,并且第9位数据是否有效要取决于USART控制寄存器1(USART_CR1) 的M位设置,当M位为0时表示8位数据字长,当M 位为1 表示9位数据字长,一般使用8位数据字长USART_DR包含了已发送的数据或者接收到的数据
USART_DR包含了两个寄存器,专门用于发送的可写TDR,专门用于接收的可读RDR。当进行发送操作时,往USART_DR写入数据会自动存储在TDR 内;当进行读取操作时,向USART_DR 读取数据会自动提取RDR数据。TDR和RDR都是介于系统总线和移位寄存器之间。串行通信是一个位一个位传输的,发送时把TDR内容转移到发送移位寄存器,然后把移位寄存器数据每一位发送出去,接收时把接收到的每一位顺序保存在接收移位寄存器内然后才转移到RDR
USART 支持DMA 传输,可以实现高速数据传输
控制器
USART 有专门控制发送的发送器、控制接收的接收器,还有唤醒单元、中断控制等等。使用USART之前需要向USART_CR1寄存器的UE位置1使能USART,UE位用来开启供给给串口的时钟。发送或者接收数据字长可选8位或9位,由USART_CR1的M位控制
发送器
当USART_CR1寄存器的发送使能位TE置1时,启动数据发送,发送移位寄存器的数据会在TX引脚输出,低位在前,高位在后。如果是同步模式SCLK 也输出时钟信号。
一个字符帧发送需要三个部分:起始位+ 数据帧+ 停止位。起始位是一个位周期的低电平,位周期就是每一位占用的时间;数据帧就是要发送的8位或9位数据,数据是从最低位开始传输的;停止位是一定时间周期的高电平。停止位时间长短是可以通过USART控制寄存器2(USART_CR2)的STOP[1:0]位控制,可选0.5个、1个、1.5个和2个停止位。默认使用1个停止位。2个停止位适用于正常USART模式、单线模式和调制解调器模式。0.5个和1.5个停止位用于智能卡模式。
当发送使能位TE置1之后,发送器开始会先发送一个空闲帧(一个数据帧长度的高电平),接下来就可以往USART_DR寄存器写入要发送的数据。在写入最后一个数据后,需要等待USART状态寄存器(USART_SR)的TC位为1,表示数据传输完成,如果USART_CR1寄存器的TCIE位置1,将产生中断
接收器
如果将USART_CR1寄存器的RE位置1,使能USART接收,使得接收器在RX线开始搜索起始位。在确定到起始位后就根据RX线电平状态把数据存放在接收移位寄存器内。接收完成后就把接收移位寄存器数据移到RDR内,并把USART_SR寄存器的RXNE 位置1,同时如果USART_CR2寄存器的RXNEIE置1的话可以产生中断
小数波特率生成
USART波特率与比特率相等,USART的发送器和接收器使用相同的波特率。计算公式如下:
其中,fPLCK为USART时钟,USARTDIV是一个存放在波特率寄存器(USART_BRR)的一个无符号定点数
波特率的常用值有2400、9600、19200、115200
设定寄存器值得到波特率的值:
USART1 使用APB2总线时钟,最高可达72MHz,其他USART的最高频率为36MHz。选取USART1作为实例讲解,即fPLCK=72MHz。解得USARTDIV=39.0625,可算得DIV_Fraction=0.0625*16=1=0x01,DIV_Mantissa=39=0x27,即应该设置USART_BRR 的值为0x271
STM32F103系列控制器USART支持奇偶校验,使能了奇偶校验控制后,每个字符帧的格式将变成:起始位+数据帧+校验位+停止位
USART有多个中断请求事件
DMA(直接存储器存取)
DMA(Direct Memory Access,直接存储器存取):单片机的一个外设,在传输数据的时候,不需要占用CPU,CPU可以干其他的事情,数据传输支持从外设到存储器(如ADC采集),从存储器到外设(如串口向电脑端发送数据),从存储器到存储器(如内部FLASH向内部SRAM复制数据),这里的存储器可以是SRAM或者是FLASH。DMA控制器包含了DMA1和DMA2,其中DMA1有7个通道,DMA2有5个通道。DMA2只存在于大容量的单片机中
从哪里来到哪里去
外设到存储器:当使用从外设到存储器传输时,以ADC采集为例。DMA外设寄存器的地址对应的是ADC数据寄存器的地址,DMA存储器的地址是自定义的变量(用来接收存储AD采集的数据)的地址。方向设置外设为源地址
存储器到外设:当使用从存储器到外设传输时,以串口向电脑端发送数据为例。DMA外设寄存器的地址对应的是串口数据寄存器的地址,DMA存储器的地址是自定义的变量(相当于一个缓冲区,用来存储通过串口发送到电脑的数据)的地址。方向设置外设为目标地址
存储器到存储器:当使用从存储器到存储器传输时,以内部FLASH向内部SRAM复制数据为例。DMA外设寄存器的地址对应的是内部FLASH(这里把内部FALSH 当作一个外设来看)的地址,DMA存储器的地址是自定义的变量(相当于一个缓冲区,用来存储来自内部FLASH 的数据)的地址。方向设置外设(即内部FLASH)为源地址。跟上面两个不一样的是,这里需要把DMA_CCR 位14:MEM2MEM:存储器到存储器模式配置为1,启动M2M 模式
要传多少,单位是什么
以串口向电脑发送数据为例,可以一次性给电脑发送很多数据,具体多少由DMA_CNDTR配置,这是一个32位的寄存器,一次最多只能传输65535个数据
数据传输正确,源和目标地址存储的数据宽度必须一致,串口数据寄存器是8位的,所以要发送的数据也必须是8位。外设的数据宽度由DMA_CCRx 的PSIZE[1:0]配置,可以是8/16/32位,存储器的数据宽度由DMA_CCRx 的MSIZE[1:0] 配置,可以是8/16/32 位
在DMA控制器的控制下,数据从一个地方搬到另外一个地方,必须正确设置两边数据指针的增量模式。外设的地址指针由DMA_CCRx 的PINC配置,存储器的地址指针由MINC配置。以串口向电脑发送数据为例,要发送的数据很多,每发送完一个,那么存储器的地址指针就应该加1,而串口数据寄存器只有一个,那么外设的地址指针就固定不变。具体的数据指针的增量模式由实际情况决定
什么时候传输完成:
数据什么时候传输完成,可以通过查询标志位或者通过中断的方式来鉴别。每个DMA通道在DMA传输过半、传输完成和传输错误时都会有相应的标志位,如果使能了该类型的中断后,则会产生中断
传输完成分两种模式,是一次传输还是循环传输,即传输一次之后就停止,要想再传输的话,必须关断DMA使能后再重新配置后才能继续传输。循环传输是一次传输完成之后又恢复第一次传输时的配置循环传输,不断的重复。具体的由DMA_CCRx 寄存器的CIRC 循环模式位控制
DMA请求、通道、仲裁器
DMA请求:如果外设要想通过DMA来传输数据,必须先给DMA控制器发送DMA请求,DMA收到请求信号之后,控制器会给外设一个应答信号,当外设应答后且DMA控制器收到应答信号之后,就会启动DMA的传输,直到传输完
通道:不同的DMA控制器的通道对应着不同的外设请求,具体见DMA 请求映像表。虽然每个通道可以接收多个外设的请求,但是同一时间只能接收一个
仲裁器:当发生多个DMA通道请求时,由仲裁器也管理。如果两个或以上的DMA通道请求设置的优先级一样,则他们优先级取决于通道编号,编号越低优先权越高
存储器
RAM
RAM(Random Access Memory,随机存储器):随机存储器,可以随时进行读写操作,速度很快,掉电以后数据会丢失。比如内存条、SRAM、SDRAM、DDR等都是RAM。RAM一般用来保存程序数据、中间结果。可以随意的对RAM中任何地址的数据进行读写操作。RAM速度快,可以直接和CPU进行通信,但是掉电以后数据会丢失,容量不容易做大(和同价格的Flash相比)
DRAM
DRAM的存储单元以电容的电荷来表示数据,有电荷代表1,无电荷代表0。但时间一长,代表1的电容会放电,代表0的电容会吸收电荷,因此它需要定期刷新操作,刷新操作会对电容进行检查,若电量大于满电量的1/2,则认为其代表1,并把电容充满电;若电量小于1/2,则认为其代表0,并把电容放电,藉此来保证数据的正确性
SDRAM
SDRAM(Synchronous DRAM,同步DRAM):SDRAM只在上升沿表示有效数据。SDRAM全称是Synchronous Dynamic Random Access Memory,翻译过来就是同步动态随机存储器,“同步”的意思是SDRAM工作需要时钟线,“动态”的意思是SDRAM中的数据需要不断的刷新来保证数据不会丢失,“随机”的意思就是可以读写任意地址的数据。与SRAM相比,SDRAM集成度高、功耗低、成本低、适合做大容量存储,但是需要定时刷新来保证数据不会丢失。因此SDRAM适合用来做内存条,SRAM适合做高速缓存或MCU内部的RAM。STM32最常用的是华邦W9825G6KH
DDR SDRAM (Double Data Rate SDRAM)
DDRSDRAM在时钟的上升沿及下降沿各表示一个数据,在1个时钟周期内可以表示2位数据,在时钟频率同样的情况下提高了一倍的速度
SRAM
静态随机存储器SRAM:SRAM的存储单元以锁存器来存储数据。这种电路结构不需要定时刷新充电,就能保持状态(如果断电了,数据会丢失)。SRAM最大的缺点就是成本高!价格高。SDRAM比SRAM容量大,但是价格更低。SRAM突出的特点就是无需刷新(SDRAM需要刷新、速写速度块)。SRAM通常作为SOC的内部RAM使用或Cache使用,比如STM32内存的RAM
扩展外部SRAM
STM32控制器芯片内部有一定大小的SRAM及FLASH作为内存和程序存储空间,扩展内存时一般使用SRAM和SDRAM,STM32F1系列的芯片不支持扩展SDRAM(STM32F429系列支持),它仅支持使用FSMC外设扩展SRAM。由于引脚数量的限制,只有STM32F103ZE或以上型号的芯片才可以扩展外部SRAM。PC上一般以内存条的形式扩展,内存条是由多个内存颗粒(SDRAM) 组成的通用标准模块,STM32直接与SRAM连接。STM32,比如F103、F407等,基本都会外扩一个512KB或1MB的SRAM的,因为STM32F103/F407内部RAM比较小,在一些比较耗费内存的应用中会出现内存紧张的情况,比如emWin做UI界面。STM32F103/F407常用的IS62WV51216这颗SRAM芯片
一种SRAM 芯片的内部结构框图中左侧引出的是SRAM芯片的控制引脚,
只要控制信号线使能了访问,从地址线输入要访问的地址,即可从I/O数据线写入或读出数据
框图中标号处表示的是存储器矩阵,SRAM内部包含的存储阵列,可以把它理解成一张表格,数据就填在这张表格上。和表格查找一样,指定一个行地址和列地址,就可以精确地找到目标单元格,这是SRAM芯片寻址的基本原理。这样的每个单元格被称为存储单元,而这样的表则被称为存储矩阵
地址译码器把N根地址线转换成2N根信号线,每根信号线对应一行或一列存储单元,通过地址线找到具体的存储单元,实现寻址。如果存储阵列比较大,地址线会分成行和列地址,或者行、列分时复用同一地址总线,访问数据寻址时先用地址线传输行地址再传输列地址
控制电路:控制电路主要包含了片选、读写使能以及宽度控制信号UB#和LB#。利用CS2或CS1#片选信号,可以把多个SRAM芯片组成一个大容量的内存条。OE#和WE#可以控制读写使能,防止误操作
SRAM的读时序
SRAM的写时序
读写时序的流程:
(1)主机使用地址信号线发出要访问的存储器目标地址;
(2)控制片选信号CS1#及CS2#使能存储器芯片;
(3)若是要进行读操作,则控制读使能信号OE#表示要读数据,若进行写操作则控制写使能信号WE# 表示要写数据;
(4)使用掩码信号LB#与UB#指示要访问目标地址的高、低字节部分;
(5)若是读取过程,存储器会通过数据线向主机输出目标数据,若是写入过程,主要使用数据线
ROM
只读存储器,现在一般用于指代非易失性半导体存储器。Flash(EMMC、UFS、NAND Flash),都可以进行写操作,要先进行擦除,然后再发送要写的地址或扇区,最后才是要写入的数据。例如WM25QXX系列的SPI Flash
相比于RAM,向ROM或者Flash写入数据要复杂很多,因此意味着速度就会变慢(相比RAM),但是ROM和Flash可以将容量做的很大,而且掉电以后数据不会丢失,适合用来存储资料,比如音乐、图片、视频等信息
MASK(掩膜) ROM
存储在内部的数据是在出厂时使用特殊工艺固化的,生产后就不可修改
OTPROM(One Time Programable ROM)
一次可编程存储器。出厂时内部没有资料,用户可以使用专用的编程器将资料写入,但只能写入一次,被写入后,内容不可再修改
EPROM(Erasable Programmable ROM)
可重复擦写的存储器,使用紫外线照射芯片内部擦除数据,擦除和写入都要专用的设备
EEPROM(Electrically Erasable Programmable ROM)
电可擦除存储器。EEPROM 可以重复擦写,它的擦除和写入都是直接使用电路控制,不需要再使用外部设备来擦写。可以按字节为单位修改数据,无需整个芯片擦除
EEPROM——AT24C02原理图和手册分析**
8个引脚。EEPROM的SCL、SDA引脚和stm32的SCL、SDA连接在一起组成一个I2C通讯总线
A0、A1、A2是设备地址后三位,可以设置,原理图中是000
存储容量
EEPROM写数据,WORD ADDRESS要写入的地址也是个数据
ACL为0时可以接着写入数据,Page Write突发写入,可以不用每次都传设备地址,给一次地址,连续写入多个数据(连续的地址),8-byte,8个字节
当前地址读取,很少用,很难确认当前地址
顺序读取,可以从0,一直读到255-byte,没有限制,超出最高地址会“roll over”。重新从第0个地址开始传。一般会在代码上限制,指定规则
支持400kHz,I2C也能支持400kHz,波特率设置400kHz
FALSH(闪存)
可重复擦写的储器,容量一般比EEPROM大得多,在擦除时,一般以多个字节为单位
norflash可以存储程序原因:
norflash以扇区为单位擦除,可以一个字节一个字节的读写。nandflash擦除、写入、读取三个操作都是以块或扇区为单位,容量大,只能一块一块的读写出来,不能一个字节一个字节的读写
外部Nor FALSH(SPI Flash)——W25Q64手册分析
W25Q64芯片,Nor Flash(支持XIP),容量是64M-bit,8M-word(容量比EEPROM大很多) ,WP是写保护,“/”低电平有效。IO0、1、2、3,stm32f4同时支持四个引脚通讯,stm32f1不支持,最高支持80MHz
块(Block)分成扇区(Sector),64x128/1024=8M,4x16。FLASH存储特性:在写入之前必须先擦除,擦除时会把数据位重置为1,写入数据时只能把为1的数据位改成0,擦除时必须按最小单位(一般为扇区)擦除,擦除时以4096(扇区)为最小单位,写入数据时要地址对齐,一般以扇区基地址(如xxE00h)
norflash可以存储程序原因:
norflash以扇区为单位擦除,可以一个字节一个字节的读写。nandflash擦除、写入、读取三个操作都是以块或扇区为单位,容量大,只能一块一块的读写出来,不能一个字节一个字节的读写
FLASH的状态寄存器
FLASH命令表,BYTE1:控制器发送给FALSH
确认FLASH芯片是否连接正常,dummy可以是任意值
支持SPI的模式0和模式3
内部FLASH
内部FLASH:在STM32内部有一个FLASH存储器,它主要用于存储代码,在电脑上编写好应用程序后,使用下载器把编译后的代码文件烧录到该内部FLASH中,由于FLASH存储器的内容在掉电后不会丢失,芯片重新上电复位后,内核可从内部FLASH中加载代码并运行。除了使用外部的工具(如下载器)读写内部FLASH外,STM32在运行的时候,也能对自身的内部FLASH进行读写,因此,若内部FLASH存储了应用程序后还有剩余的空间,可以把它像外部SPI-FLASH那样利用起来,存储一些程序运行时产生的需要掉电保存的数据。由于访问内部FLASH的速度要比外部的SPI-FLASH快得多,所以在紧急状态下常常会使用内部FLASH存储关键记录;为了防止应用程序被抄袭,有的应用会禁止读写内部FLASH中的内容,或者在第一次运行时计算加密信息并记录到某些区域,然后删除自身的部分加密代码,这些应用都涉及到内部FLASH的操作
上表中的主存储器是本实验板使用的STM32VET6 型号芯片的参数,即STM32F1大容量产品。若使用超大容量、中容量或小容量产品,它们主存储器的页数量、页大小均有不同
内部FLASH的构成:STM32的内部FLASH包含主存储器、系统存储器以及选项字节区域,(在《STM32参考手册》中没有关于其内部FLASH的说明,需要了解这些内容时,要查阅《STM32F10x闪存编程参考手册》
主存储:一般说STM32内部FLASH的时候,都是指这个主存储器区域,它是存储用户应用程序的空间,芯片型号说明中的256K FLASH、512K FLASH都是指这个区域的大小。主存储器分为256页,每页大小为2KB,共512KB。这个分页的概念,实质就是FLASH存储器的扇区,与其它FLASH一样,在写入数据前,要先按页(扇区)擦除
系统存储区:系统存储区是用户不能访问的区域,它在芯片出厂时已经固化了启动代码,它负责实现串口、USB以及CAN等ISP烧录功能。
选项字节:选项字节用于配置FLASH的读写保护、待机/停机复位、软件/硬件看门狗等功能,这部分共16字节。可以通过修改FLASH的选项控制寄存器修改
对内部FLASH的写入过程:由于内部FLASH本身存储有程序数据,若不是有意删除某段程序代码,一般不应修改程序空间的内容,所以在使用内部FLASH 存储其它数据前需要了解哪一些空间已经写入了程序代码,存储了程序代码的扇区都不应作任何修改。通过查询应用程序编译时产生的“*.map”后缀文件,可以了解程序存储到了哪些区,查看工程的空间分布
解锁的操作步骤
(1)往FPEC键寄存器FLASH_KEYR中写入KEY1 = 0x45670123
(2)再往FPEC键寄存器FLASH_KEYR中写入KEY2 = 0xCDEF89AB
在写入新的数据前,需要先擦除存储区域,STM32提供了页(扇区)擦除指令和整个FLASH 擦除(批量擦除)的指令,批量擦除指令仅针对主存储区。
页擦除的过程:
(1)检查FLASH_SR寄存器中的“忙碌寄存器位BSY”,以确认当前未执行任何Flash操作
(2)在FLASH_CR寄存器中,将“激活页擦除寄存器位PER ”置1
(3)用FLASH_AR寄存器选择要擦除的页
(4)将FLASH_CR寄存器中的“开始擦除寄存器位STRT ”置1,开始擦除
(5)等待BSY位被清零时,表示擦除完成
写入数据:擦除完毕后即可写入数据,写入数据的过程并不是仅仅使用指针向地址赋值,赋值前还还需要配置一系列的寄存器
步骤:
(1)检查FLASH_SR中的BSY位,以确认当前未执行任何其它的内部Flash操作
(2)将FLASH_CR寄存器中的“激活编程寄存器位PG”置1
(3)向指定的FLASH存储器地址执行数据写入操作,每次只能以16位的方式写入
(4)等待BSY位被清零时,表示写入完成
FLASH的读写保护:在实际发布的产品中,STM32的内部FLASH存储了控制程序,如果不作任何保护措施的话,可以使用下载器直接把内部FLASH的内容读取回来,得到bin或hex 文件格式的代码拷贝,别有用心的厂商会利用该方法山寨产品。为此,STM32提供了多种方式保护内部FLASH的程序不被非法读取,但在默认情况下该保护功能是不开启的,若要开启该功能,需要改写内部FLASH选项字节(Option Bytes)中的配置
RDP读保护:修改选项字节的RDP 位的值可设置内部FLASH 为以下保护级别
WRP写保护:使用选项字节的WRP0/1/2/3可以设置主FLASH的写保护,防止它存储的程序内容被修改
修改选项字节的过程:
1.解除FLASH_CR寄存器的访问限制
• 往FPEC 键寄存器FLASH_KEYR 中写入KEY1 = 0x45670123
• 再往FPEC 键寄存器FLASH_KEYR 中写入KEY2 = 0xCDEF89AB
2.解除对选项字节的访问限制
• 往FLASH_OPTKEYR 中写入KEY1 = 0x45670123
• 再往FLASH_OPTKEYR 中写入KEY2 = 0xCDEF89AB
3.配置FLASH_CR 的OPTPG 位,准备修改选项字节
4.直接使用指针操作修改选项字节的内容,根据需要修改RDP、WRP 等内容
5.对于读保护的解除,由于它会擦除FLASH的内容,所以需要检测状态寄存器标志位以确认FLASH擦除操作完成
6.若是设置读保护及其解除,需要给芯片重新上电复位,以使新配置的选项字节生效;对于设置写保护及其解除,需要给芯片进行系统复位,以使新配置的选项字节生效
SD卡
SD卡(Secure Digital Memory Card):SD卡一般支持SDIO和SPI接口。一张SD卡包括存储单元、存储单元接口、电源检测、卡及接口控制器和接口驱动器5个部分,SD卡总共有8个寄存器,用于设定或表示SD卡信息
多媒体卡协会网站www.mmca.org中提供有MMCA 技术委员会发布的多媒体卡系统规范。
SD卡协会网站www.sdcard.org中提供SD 存储卡和SDIO卡系统规范。
CE-ATA工作组网站www.ce-ata.org中提供CE_ATA 系统规范
STM32F10x系列控制器只支持SD卡规范版本2.0,即只支持标准容量SD和高容量SDHC 标准卡,不支持超大容量SDXC标准卡,可以支持的最高卡容量是32GB
SD卡寄存器用于设定或表示SD卡信息。这些寄存器只能通过对应的命令访问,对SD卡进行控制操作并不是像操作控制器GPIO相关寄存器那样一次读写一个寄存器的,它是通过命令来控制,SDIO命令可以实现某一特定功能,SD卡接收到命令后,根据命令要求对SD卡内部寄存器进行修改,程序控制中只需要发送组合命令就可以实现SD卡的控制以及读写操作。每个寄存器位的含义可以参考SD 简易规格文件《Physical Layer Simplified Specification V2.0》第5章内容
SD卡一般都支持SDIO 和SPI这两种接口。STM32F10x系列控制器的SDIO不支持SPI通信模式,如需用到SPI通信只能使用SPI外设
SD卡总线拓扑。虽然可以共用总线,但不推荐多卡槽共用总线信号,一般一个单独SD总线应该连接一个单独的SD卡
SD卡使用9-pin接口通信,3根电源线、1根时钟线、1根命令线和4根数据线:
• CLK时钟线:由SDIO主机(STM32控制器)输出
• CMD命令控制线:SDIO主机通过该线发送命令控制SD卡,如果命令要求SD卡提供应答(响应),SD卡也是通过该线传输应答信息
• D0-3数据线:传输读写数据;SD卡可将D0拉低表示忙状态
• VDD、VSS1、VSS2:电源和地信号
SD总线通信协议:SD总线通信是基于命令和数据传输的。通讯由一个起始位(“0”),由一个停止位(“1”) 终止。SD通信一般是主机发送一个命令(Command),从设备在接收到命令后作出响应(Response),如有需要会有数据(Data)传输参与。SD总线的基本交互是命令与响应交互,SD数据以块(Black)形式传输,SDHC卡数据块长度一般为512字节,数据可以从主机到卡,也可以是从卡到主机。数据块需要CRC位来保证数据传输成功。CRC位由SD卡系统硬件生成。STM32可以控制使用单线或4线传输,SD数据传输支持单块和多块读写,它们分别对应不同的操作命令,多块写入还需要使用命令来停止整个写入操作。数据写入前需要检测SD卡忙状态,因为SD卡在接收到数据后编程到存储区过程需要一定操作时间。SD卡忙状态通过把D0线拉低表示。数据块读操作与之类似,只是无需忙状态检测。使用4数据线传输时,每次传输4bit数据,每根数据线都必须有起始位、终止位以及CRC位,CRC 位每根数据线都要分别检查,并把检查结果汇总然后在数据传输完后通过D0线反馈给主机。
SD卡数据包有两种发送格式,常规数据(8bit宽)、宽位数据包格式。它先发低字节再发高字节,而每个字节则是先发高位再发低位
4 线同步发送:每根线发送一个字节的其中两个位,数据位在四线顺序排列发送,DAT3 数据线发较高位,DAT0 数据线发较低位
宽位数据包格式:对SD卡而言宽位数据包发送方式是针对SD卡SSR(SD状态)寄存器内容发送的,SSR寄存器总共有512bit,在主机发出ACMD13 命令后SD卡将SSR寄存器内容通过DAT线发送给主机
SD 命令由主机发出,以广播命令和寻址命令为例,广播命令是针对与SD主机总线连接的所有从设备发送的,寻址命令是指定某个地址设备进行命令传输。SD命令格式固定为48bit,通过CMD线连续传输的数据线不参与)
SD命令组成:
• 起始位和终止位:命令的主体包含在起始位与终止位之间,只包含一个数据位,起始位为0,终止位为1。
• 传输标志:用于区分传输方向,为1时表示命令,方向为主机传输到SD卡,为0时表示响应,方向为SD卡传输到主机。
命令主体内容包括命令、地址信息/参数和CRC校验三个部分
• 命令号:它固定占用6bit,所以总共有64个命令(代号:CMD0~CMD63),每个命令都有特定的用途,部分命令不适用于SD卡操作,只是专门用于MMC卡或者SD I/O卡。
• 地址/参数:每个命令有32bit地址信息/参数用于命令附加内容,例如,广播命令没有地址信息,这32bit用于指定参数,而寻址命令这32bit用于指定目标SD卡的地址。
• CRC7校验:长度为7bit的校验位用于验证命令传输内容正确性,如果发生外部干扰导致
传输数据个别位状态改变将导致校准失败,也意味着命令传输失败,SD卡不执行命令。
SD命令类型:
• 无响应广播命令(bc),发送到所有卡,不返回任务响应
• 带响应广播命令(bcr),发送到所有卡,同时接收来自所有卡响应
• 寻址命令(ac),发送到选定卡,DAT 线无数据传输
• 寻址数据传输命令(adtc),发送到选定卡,DAT 线有数据传输
响应:由SD卡向主机发出,部分命令要求SD卡作出响应,响应多用于反馈SD卡的状态。SDIO总共有7个响应类型(代号:R1~R7),其中SD卡没有R4、R5类型响应。特定的命令对应有特定的响应类型,比如当主机发送CMD3命令时,可以得到响应R6。SD卡的响应通过CMD线连续传输的。根据响应内容大小可以分为短响应和长响应。短响应是48bit长度,只有R2类型是长响应,其长度为136bit除了R3类型之外,其他响应都使用CRC7校验来校验,对于R2类型是使用CID和CSD寄存器内部CRC7
SD卡系统(包括主机和SD卡)操作模式:卡识别模式和数据传输模式。在系统复位后,主机处于卡识别模式,寻找总线上可用的SDIO设备;同时,SD卡也处于卡识别模式,直到被主机识别到,即当SD卡接收到SEND_RCA(CMD3)命令后,SD卡就会进入数据传输模式,而主机在总线上所有卡被识别后也进入数据传输模式
SDIO
SDIO(安全数字输入/输出接口):多媒体卡(MMC)、SD卡、SD I/O卡有SDIO接口。STM32F10x 系列控制器有一个SDIO主机接口,可以与MMC卡、SD卡、SD I/O卡、CE-ATA设备进行数据传输。
MMC卡:SD 卡的前身,现阶段已经用得很少
SD I/O:不是指用于存储的卡,指利用SDIO传输协议的一种外设。比如Wi-Fi Card,主要是提供Wi-Fi功能,有些Wi-Fi模块是使用串口或者SPI接口进行通信的,但Wi-Fi SDIO Card是使用SDIO接口进行通信的。并且一般设计SD I/O卡是可以插入到SD的插槽
CE-ATA:专为轻薄笔记本硬盘设计的硬盘高速通讯接口
SDIO的通信时序:同步通信。SDIO从主机控制器向SD卡传输、SD卡向主机控制器传输都以CLK时钟线的上升沿为有效。SD卡操作过程会使用两种不同频率的时钟同步数据,一个是识别卡阶段时钟频率FOD,最高为400kHz,另外一个是数据传输模式下时钟频率FPP,默认最高为25MHz,如果通过相关寄存器配置使SDIO工作在高速模式,此时数据传输模式最高频率为50MHz
STM32的SDIO主机
STM32只有一个SDIO主机,所以只能连接一个SDIO设备
SDIO:由两部分组成,SDIO适配器和AHB接口。SDIO适配器提供SDIO主机功能,可以提供SD时钟、发送命令和进行数据传输。AHB接口用于控制器访问SDIO适配器寄存器并且可以产生中断和DMA请求信号。SDIO使用两个时钟信号,一个是SDIO适配器时钟(SDIOCLK=HCLK=72MHz),另外一个是AHB总线时钟的二分频(HCLK/2,一般为36MHz)。适配器寄存器和FIFO 使用AHB 总线一侧的时钟(HCLK/2),控制单元、命令通道和数据通道使用SDIO适配器一侧的时钟(SDIOCLK)。。配置时钟时要注意,SD 卡普遍要求SDIO_CK 时钟频率不能超过25MHzSTM32的SDIO是MMC卡和SD卡的主设备,所以预留有8根数据线,SD卡最多用四根数据线
SDIO适配器:SD卡系统的主机部分,是STM32与SD卡数据通信中间设备。SDIO适配器由五个单元组成,分别是控制单元、命令路径单元、数据路径单元、寄存器单元以及FIFO
控制单元:包含电源管理和时钟管理功能。电源管理部件会在系统断电和上电阶段禁止SD卡总线输出信号。时钟管理部件控制CLK线时钟信号生成。一般使用SDIOCLK分频得到
命令路径:控制命令发送,并接收卡的响应。当SD 卡处于某一状态时,SDIO适配器必然处于特定状态与之对应。STM32以命令路径状态机(CPSM) 来描述SDIO适配器的状态变化,并加入了等待超时检测功能,以便退出永久等待的情况
数据路径:负责与SD卡相互数据传输。SDIO适配器以数据路径状态机(DPSM)来描述SDIO 适配器状态变化情况。并加入了等待超时检测功能,以便退出永久等待情况。发送数据时,DPSM处于等待发送(Wait_S)状态,如果数据FIFO不为空,DPSM变成发送状态并且数据路径部件启动向卡发送数据。接收数据时,DPSM 处于等待接收状态,当DPSM 收到起始位时变成接收状态,并且数据路径部件开始从卡接收数据
数据FIFO(先进先出):数据缓冲器,带发送和接收单元。控制器的FIFO包含宽度为32bit、深度为32字的数据缓冲器和发送/接收逻辑。其中SDIO状态寄存器(SDIO_STA)的TXACT位用于指示当前正在发送数据,RXACT位指示当前正在接收数据,这两个位不可能同时为1,根据FIFO空或满状态会把SDIO_STA寄存器位值1,并可以产生中断和DMA请求。当TXACT为1时,可以通过AHB接口将数据写入到传输FIFO。当RXACT为1时,接收FIFO存放从数据路径部件接收到的数据
适配器寄存器:包含了控制SDIO 外设的各种控制寄存器及状态寄存器,可以通过SDIO提供的结构体来了解
文件系统
文件:数据在PC上是以文件的形式储存在磁盘中的,数据的形式一般为ASCII码或二进制形式直接存储数据会难以记录有效数据的位置,难以确定存储介质的剩余空间,以及应以何种格式来解读数据
文件系统:为了存储和管理数据,而在存储介质建立的一种组织结构,这些结构包括操作系统引导区、目录和文件。常见的windows下的文件系统格式包括FAT32、NTFS、exFAT。文件系统可以记录数据存放的物理地址,剩余空间。在使用文件系统前,要先对存储介质进行格式化。格式化先擦除原来内容,在存储介质上新建一个文件分配表和目录。使用文件系统时,数据都以文件的形式存储。写入新文件时,先在目录中创建一个文件索引,它指示了文件存放的物理地址,再把数据存储到该地址中。当需要读取数据时,可以从目录中找到该文件的索引,进而在相应的地址中读取出数据。具体还涉及到逻辑地址、簇大小、不连续存储等一系列辅助结构或处理过程。文件系统在存取数据时,不是向某物理地址直接读写,而是要遵循它的读写格式。如经过逻辑转换,一个完整的文件可能被分开成多段存储到不连续的物理地址,使用目录或链表的方式来获知下一段的位置
文件系统:根据文件系统格式的逻辑转换部分则需要的代码习惯称之为文件系统。为当我们需要写入一段数据时,由这个逻辑转换部分来求解向什么物理地址写入数据、以什么格式写入及写入一些原始数据以外的信息(如目录)。文件系统庞大而复杂,它需要根据应用的文件系统格式而编写,而且一般与驱动层分离开来,很方便移植,所以工程应用中一般是移植现成的文件系统源码
FatFs
FatFs是面向小型嵌入式系统的一种通用的FAT文件系统。完全由ANSIC语言编写并且完全独立于底层的I/O 介质。因此可以不加修改地移植到其他的处理器当中,如8051、PIC、AVR、SH、Z80、H8、ARM等。FatFs支持FAT12、FAT16、FAT32(单个文件大小最大4G)等格式
option:一些可选的外部c文件,包含了多语言支持需要用到的文件和转换函数
integer.h:文件中包含了一些数值类型定义
diskio.c:FatFs移植最关键的文件,为文件系统提供了最底层的访问SPI Flash芯片的方法,包含底层存储介质的操作函数,函数需要用户自己实现,主要添加底层驱动函数
diskio.h:定义了FatFs用到的宏,以及diskio.c文件内与底层硬件接口相关的函数声明
ff.c:FatFs核心文件,文件管理的实现方法。独立于底层介质操作文件的函数,利用这些函数实现文件的读写
cc936.c:在option目录下,是简体中文支持所需要添加的文件,包含了简体中文的GBK 和Unicode相互转换功能函数。文件比较大,不方便调试,一般是调试完了再添加中文的支持
ffconf.h:包含了对FatFs 功能配置的宏定义,通过修改这些宏定义就可以裁剪FatFs的功能。如需要支持简体中文,需要把ffconf.h中的_CODE_PAGE 的宏改成936 并把上面的cc936.c 文件加入到工程之中
00history.txt:FatFs 的版本更新情况
00readme.txt:说明当前目录下diskio.c 、diskio.h、ff.c、ff.h、integer.h 的功能
用户应用程序需要由用户编写,一般用f_mount()、f_open()、f_write()、f_read() 就可以实现文件的读写操作
FatFs组件是FatFs的主体,在源码src文件夹中,其中ff.c、ff.h、integer.h以及diskio.h四个文件不需要改动,只需修改ffconf.h和diskio.c两个文件
底层设备输入输出要求实现存储设备的读写操作函数、存储设备信息获取函数等等。例如使用SPI Flash芯片作为物理设备
STM32的启动方式:
STM32的启动方式:
自举过程:过程由内核自动设置运行环境并执行主体程序,它被称为自举过程。一般以存储器的类型来区分自举过程,例如内部FLASH启动方式、内部SRAM启动方式以及系统存储器启动方式
(1)内部FLASH启动方式:当芯片上电后采样到BOOT0引脚为低电平时,0x00000000和0x00000004地址被映射到内部FLASH的首地址0x08000000和0x08000004。因此,内核离开复位状态后,读取内部FLASH的0x08000000地址空间存储的内容,赋值给栈指针MSP,作为栈顶地址,再读取内部FLASH的0x08000004地址空间存储的内容,赋值给程序指针PC,作为将要执行的第一条指令所在的地址。具备这两个条件后,内核就可以开始从PC 指向的地址中读取指令执行了
(2)内部SRAM启动方式:当芯片上电后采样到BOOT0和BOOT1引脚均为高电平时,0x00000000和0x00000004地址被映射到内部SRAM的首地址0x20000000和0x20000004,内核从SRAM空间获取内容进行自举。在实际应用中,由启动文件starttup_stm32f10x.s决定了0x00000000和0x00000004地址存储什么内容,链接时,由分散加载文件(sct)决定这些内容的绝对地址,即分配到内部FLASH还是内部SRAM。到若希望在内部SRAM中调试代码,需要设置启动方式为从内部SRAM启动,修改分散加载文件控制代码空间到内部SRAM地址以及把生成程序下载到芯片的内部SRAM中
(3)系统存储器启动方式(ISP启动方式):当芯片上电后采样到BOOT0引脚为高电平,BOOT1为低电平时,内核将从系统存储器的0x1FFFF000及0x1FFFF004获取MSP及PC值进行自举。系统存储器是一段特殊的空间,用户不能访问,ST公司在芯片出厂前就在系统存储器中固化了一段代码。因而使用系统存储器启动方式时,内核会执行该代码,该代码运行时,会为ISP提供支持(In System Program),如检测USART1/2、CAN2 及USB通讯接口传输过来的信息,并根据这些信息更新自己内部FLASH的内容,达到升级产品应用程序的目的,因此这种启动方式也称为ISP启动方式
在SRAM中调试代码
RAM调试功能:把原来存储在内部FLASH的代码(CODE及RW-data的内容) 改为存储到SRAM中(内部SRAM或外部SDRAM),芯片复位后从SRAM中加载代码并运行。一般情况下,在MDK中编写工程应用后,调试时都是把程序下载到芯片的内部FLASH运行测试的,代码的CODE及RW-data的内容被写入到内部FLASH中存储。但在某些应用场合下却不希望或不能修改内部FLASH的内容,这时就可以使用RAM调试功能了
把代码下载到RAM中调试优点:
(1)下载程序非常快。RAM存储器的写入速度比在内部FLASH中要快得多,且没有擦除过程,因此在RAM上调试程序时程序几乎是秒下的,对于需要频繁改动代码的调试过程,能节约很多时间,省去了擦除与写入FLASH过程。另外STM32的内部FLASH可擦除次数为1万次
(2)不改写内部FLASH的原有程序
(3)对于内部FLASH被锁定的芯片,可以把解锁程序下载到RAM上,进行解锁
把代码下载到RAM中调试缺点:
(1)存储在RAM上的程序掉电后会丢失,不能像FLASH那样保存
(2)若使用STM32的内部SRAM存储程序,程序的执行速度与在FLASH上执行速度无异,但SRAM空间较小
(3)若使用外部扩展的SRAM存储程序,程序空间非常大,但STM32读取外部SRAM的速度比读取内部FLASH慢,这会导致程序总执行时间增加,因此在外部SRAM中调试的程序无法完美仿真在内部FLASH运行时的环境。另外,由于STM32无法直接从外部SRAM中启动且应用程序复制到外部SRAM的过程比较复杂(下载程序前需要使STM32能正常控制外部SRAM),所以在很少会在STM32的外部SRAM中调试程序
FSMC
FSMC(Flexible Static Memory Controller,灵活的静态存储控制器):STM32F1系列芯片使用FSMC外设来管理扩展的存储器。可以用于驱动包括SRAM、NOR FLASH 、NANDFLSAH 类型的存储器,但不能驱动如SDRAM这种动态的存储器。在STM32F429系列的控制器中, FMC外设支持控制SDRAM存储器
控制引脚
FSMC控制不同类型存储器的时候会有一些不同的引脚,其中地址线FSMC_A和数据线FSMC_D是所有控制器都共用的
存储控制器
控制引脚连接到FSMC内部对应的存储控制器中。NOR/PSRAM/SRAM设备使用相同的控制器,NAND/PC卡设备使用相同的控制器,不同的控制器有专用的寄存器用于配置其工作模式
时钟控制逻辑
FSMC外设挂载在AHB总线上,时钟信号来自于HCLK(默认72MHz),控制器的同步时钟输出由HCLK分频得到。例如,NOR控制器的FSMC_CLK 引脚输出的时钟,可用于与同步类型的SRAM芯片进行同步通讯,时钟频率可以配置为HCLK 的1/2 或1/3,若FSMC与同步类型的SRAM通讯,同步时钟最高频率为36MHz。异步类型的存储器,不使用同步时钟信号,时钟分频配置不起作用
控制LCD时,适合使用FSMC的NOR\PSRAM模式,控制SRAM时使用的是模式A,控制LCD时使用的是与NOR FLASH一样的模式B
在控制LCD时,使用的是类似异步、地址与数据线独立的NOR FLASH控制方式,CLK、NWAIT、NADV引脚并没有使用到
FSMC NOR/PSRAM中的模式B的写时序:
根据STM32对寻址空间的地址映射,地址0x6000 0000 ~0x9FFF FFFF是映射到外部存储器的,而其中的0x6000 0000 ~0x6FFF FFFF则是分配给NOR FLASH、PSRAM这类可直接寻址的器件
当FSMC外设被配置成正常工作,并且外部接了NOR FLASH时,若向0x60000000地址写入数据如0xABCD,FSMC会自动在各信号线上产生相应的电平信号,写入数据。FSMC会控制片选信号NE1选择相应的NOR芯片,然后使用地址线A[25:0]输出0x60000000,在NWE写使能信号线上发出低电平的写使能信号,而要写入的数据信号0xABCD则从数据线D[15:0]输出,然后数据就被保存到NOR FLASH中
用FSMC模拟8080时序:
对于FSMC和8080接口,前四种信号线都是完全一样的,FSMC的地址信号线A[25:0]与8080的数据/命令选择线D/CX有区别。对于D/CX线,它为高电平的时候表示数值,为低电平的时候表示命令,如果能使用FSMC的A地址线根据不同的情况产生对应的电平,那就可以使用FSMC来产生8080接口需要的时序
为了模拟出8080时序,可以把FSMC的A0地址线(也可以使用其它A1/A2等地址线)与ILI9341芯片8080接口的D/CX信号线连接,当A0为高电平时(即D/CX为高电平),数据线D[15:0]的信号会被ILI9341理解为数值,当A0为低电平时(即D/CX为低电平),传输的信号则会被理解为命令
FSMC会自动产生地址信号,当使用FSMC向0x6xxx xxx1、0x6xxx xxx3、0x6xxx xxx5…这些奇数地址写入数据时,地址最低位的值均为1,所以它会控制地址线A0(D/CX)输出高电平,那么这时通过数据线传输的信号会被理解为数值;若向0x6xxx xxx0 、0x6xxx xxx2、0x6xxx xxx4…这些偶数地址写入数据时,地址最低位的值均为0,所以它会控制地址线A0(D/CX)输出低电平,因此这时通过数据线传输的信号会被理解为命令。在实际控制时,还需要注意HADDR内部地址与FSMC地址信号线的转换
显示器
显示器:显示器属于计算机的I/O 设备(输入输出设备)。如CRT显示器、液晶显示器、LED 点阵显示器、OLED显示器
(1)像素
像素是组成图像的最基本单元要素,显示器的像素指它成像最小的点
(2)分辨率
一些嵌入式设备的显示器常常以“行像素值x 列像素值”表示屏幕的分辨率。如分辨率800x480表示该显示器的每一行有800个像素点,每一列有480个像素点
(3)色彩深度
色彩深度指显示器的每个像素点能表示多少种颜色,一般用“位”(bit) 来表示。如单色屏的每个像素点能表示亮或灭两种状态(即实际上能显示2种颜色),用1个数据位就可以表示像素点的所有状态,所以它的色彩深度为1bit,其它常见的显示屏色深为16bit、24bit
RGB888:R0-255 G0-255 B0-255,24bit彩深
RGB565:16bit彩深
(4)显示器尺寸
显示器的大小一般以英寸表示,如5英寸、21英寸、24英寸等,指屏幕对角线的长度,通过显示器的对角线长度及长宽比可确定显示器的实际长宽尺寸
(5)点距
指两个相邻像素点之间的距离,它会影响画质的细腻度及观看距离,相同尺寸的屏幕,若分辨率越高,则点距越小,画质越细腻。如现在有些手机的屏幕分辨率比电脑显示器的还大,这是手机屏幕点距小的原因;LED点阵显示屏的点距一般都比较大,所以适合远距离观看
LCD(Liquid Crystal Display,液晶显示器):相对于上一代CRT显示器(阴极射线管显示器),LCD 显示器具有功耗低、体积小、承载的信息量大及不伤眼的优点,是现在的主流电子显示设备,其中包括电视、电脑、手机屏幕及各种嵌入式设备
LED点阵显示器:L单个像素点内包含红绿蓝三色LED灯,通过控制红绿蓝颜色的强度进行混色,实现全彩颜色输出,多个像素点构成一个屏幕。由于每个像素点都是LED灯自发光的,所以在户外白天也显示得非常清晰,但由于LED灯体积较大,导致屏幕的像素密度低,所以它一般只适合用于广场上的巨型显示器。相对来说,单色的LED 点阵显示器应用得更广泛,如公交车上的信息展示牌、店招等
OLED显示器:与LED点阵彩色显示器的原理类似,由于采用的像素单元是“有机发光二极管”(Organic Light Emitting Diode),所以像素密度比普通LED点阵显示器高
电阻触摸液晶屏
液晶显示面板、电容触摸面板、PCB底板:完整的显示屏由液晶显示面板、电容触摸面板、PCB底板构成。触摸面板带有触摸控制芯片,处理触摸信号并通过引出的信号线与外部器件通讯,触摸面板中间是透明的,贴在液晶面板上面,一起构成屏幕的主体,触摸面板与液晶面板引出的排线连接到PCB底板上,根据实际需要,PCB 底板上可能会带有液晶控制器芯片例如RA8875液晶控制器。因为控制液晶面板需要比较多的资源,所以大部分低级微控制器都不能直接控制液晶面板,需要额外配套一个专用液晶控制器来处理显示过程。而不带液晶控制器的PCB底板,只有小部分的电源管理电路,液晶面板的信号线与外部微控制器相连,直接控制
触摸屏(触控面板):一种把触摸位置转化成坐标数据的输入设备,根据触摸屏的检测原理,主要分为电阻式触摸屏和电容式触摸屏
电阻屏:造价便宜,能适应较恶劣的环境,但它只支持单点触控(一次只能检测面板上的一个触摸位置),触摸时需要一定的压力,使用久了容易造成表面磨损,影响寿命
电容屏:具有支持多点触控、检测精度高的特点,电容屏通过与导电物体产生的电容效应来检测触摸动作,只能感应导电物体的触摸,湿度较大或屏幕表面有水珠时会影响电容屏的检测效果
STM32F429系列的芯片把专用液晶控制器的功能集成到STM32F429芯片内部,可以理解为电脑的CPU集成显卡,它节约了额外的控制器成本。而STM32F1系列的芯片由于没有集成液晶控制器到芯片内部,所以它只能驱动自带控制器的屏幕,可以理解为电脑的外置显卡
适合STM32控制的显示屏,液晶面板的控制信号线是液晶面板引出的FPC排线,液晶面板通过这些FPC排线与液晶控制器通讯
RGB接口(RGB Interface)
(1)RGB信号线:RGB信号线分别用于表示液晶屏一个像素点的红、绿、蓝颜色分量。常见的颜色表示会在“RGB”后面附带各个颜色分量值的数据位数,如RGB565格式表示红绿蓝的数据线数分别为5、6、5根,一共为16个数据位,可表示216种颜色;RGB888表示颜色分量的数据线分别有8根,一共24位数据线
(2)同步时钟信号CLK:液晶屏与外部使用同步通讯方式,以CLK信号作为同步时钟,在同步时钟的驱动下,每个时钟传输一个像素点数据
(3)水平同步信号HSYNC (Horizontal Sync) :表示液晶屏一行像素数据的传输结束,每传输完成液晶屏的一行像素数据时,HSYNC会发生电平跳变,如分辨率为800x480的显示屏(800列,480行),传输一帧的图像HSYNC的电平会跳变480次
(4)垂直同步信号VSYNC (Vertical Sync) :表示液晶屏一帧(在液晶屏中,一帧指一个完整屏液晶像素点)像素数据的传输结束,每传输完成一帧像素数据时,VSYNC 会发生电平跳变。常用“帧/秒”来表示液晶屏的刷新特性,即液晶屏每秒可以显示多少帧图像,如60帧/秒速率运行时,VSYNC每秒钟电平会跳变60次
液晶显示指针在行与行之间,帧与帧之间切换时需要延时, HSYNC及VSYNC信号本身也有宽度。在这些时间参数控制的区域,数据使能信号线“DE”都为低电平,RGB数据线的信号无效,当“DE”为高电平时,表示的数据有效,传输的数据会直接影响液晶屏的显示区域
(5)数据使能信号DE (Data Enable):表示数据的有效性,当DE信号线为高电平时,RGB 信号线表示的数据有效
显存:专门用于存储显示数据的存储器称为显存。至少要能存储液晶屏的一帧显示数据,液晶屏中每个像素点都是数据,在应用中需要把每个像素点的数据缓存起来,再传输给液晶屏,一般使用SRAM或SDRAM。如分辨率为800x480的液晶屏,使用RGB888格式显示,一帧显示数据大小为:3x800x480=1152000字节。外置的液晶控制器一般会自带显存,STM32F429等集成液晶控制器的芯片可使用内部SRAM或外扩SDRAM用于显存空间
一种分辨率为320*240的3.2寸电阻触摸液晶屏
液晶触摸面板由液晶屏和触摸屏组成,屏幕表面的灰色线框为电阻触摸屏的信号线
ILI934:液晶面板内部包含了一个型号为ILI934的液晶控制器芯片(图中无法看见)。ILI9341 控制器根据自身的IM[3:0] 信号线电平决定它与MCU的通讯方式,本身支持SPI及8080通讯方式,使用16根数据线的RGB565格式。剩下的其它信号线被引出到FPC排线,最后该排线由PCB 底板引出到排针,排针再与实验板上的STM32 芯片连接,这些信号线即8080通讯接口,带X的表示低电平有效,STM32通过该接口与ILI9341 芯片进行通讯,实现对液晶屏的控制。通讯的内容主要包括命令和显存数据,显存数据即各个像素点的RGB565内容;命令是指对ILI9341的控制指令,MCU可通过8080接口发送命令编码控制ILI9341的工作方式,例如复位指令、设置光标指令、睡眠模式指令等等
使用18条数据线的8080 接口写命令时序:
写命令时序由片选信号CSX拉低开始,对数据/命令选择信号线D/CX也置低电平表示写入的是命令地址(如软件复位命令:0x01),以写信号WRX为低,读信号RDX为高表示数据传输方向为写入,同时,在数据线D17:0 输出命令地址,在第二个传输阶段传送的是命令的参数,所以D/CX要置高电平,表示写入的是命令数据,命令数据是某些指令带有的参数
当需要把像素数据写入GRAM 时把片选信号CSX拉低后,再把数据/命令选择信号线D/CX 置为高电平,这时由D[17:0]传输的数据则会被ILI9341保存至它的GRAM中
PCB底板:主要包含了一个电阻触摸屏的控制器XPT2046,电阻触摸屏控制器是一个ADC芯片,通过检测电压值来计算触摸坐标。PCB底板与液晶触摸面板通过FPC排线座连接,然后引出到排针,方便与排母连接
编码、字模
编码
字符编码:编码的过程就是规定特定的01数字符串来表示特定的文字,比如ASCII码
GB2312标准:标准的ASCII 码表中127号以下的就被称为“半角”字符
GBK编码:兼容ASCII 和GB2312 标准,在GB2312 标准的基础上又增加了14240 个新汉字,目前比较流行的是GBK 编码
GB18030:兼容GBK、GB2312及ASCII标准,国家要求一些产品必须支持GB18030 标准
Big5:在台湾、香港等地区,使用较多的是Big5编码,收录了繁体字。从GBK 编码开始, Big5中的所有汉字收录进编码了
Unicode字符集(Universal Multiple-Octet Coded CharacterSet): 全球上所有文化使用的字母和符号进行编号,对每个字符指定一个唯一的编号
UTF-8:目前Unicode字符集中使用得最广的编码方式,目前大部分网页文件已使用UTF-8编码。UTF-8的优点是兼容了ASCII码,节约空间,且没有字节顺序的问题。不过使用UTF-8编码汉字平均需要3个字节,比GBK编码要多一个字节
UTF-32: 由于UTF-32把每个字符都用要4字节来存储,因此UTF-32不兼容ASCII编码,如果ASCII编码的文件用UTF-32标准来打开会成为乱码。UTF-32的优点是编码简单,解码也很方便,读取编码的时候每次都直接读4个字节,不需要加其它的判断。缺点是浪费存储空间
UTF-16: UTF-16编码的优点是相对UTF-32 节约了存储空间,缺点是不兼容ASCII 码,仍有大小端格式问题
BOM(Byte Order Mark):位于文本文件的开头,BOM是对Unicode 的几种编码而言的,ANSI 编码没有BOM。由于带BOM的设计很多规范不兼容,不能跨平台,所以这种带BOM 的设计没有流行起来。Linux系统下默认不带BOM
字模
字模:计算机必须把字符编码转化成对应的字符图形人类才能正常识别,字符的图形数据数据就是字模
字库:多个字模数据组成的文件
ADC
ADC(Analog to Digital,模拟数字转换器):STM32f103有3个ADC,精度(分辨率)为12位,每个ADC最多有16个外部通道。ADC1 、ADC2有16个外部通道,ADC3根据CPU引脚的不同通道数不同
ADC采集数据,转换数据,传输数据
ADC采集数据
电压输入范围:ADC输入范围为:VREF-≤ VIN≤ VREF+。由VREF-、VREF+、VDDA、VSSA、四个外部引脚决定。在设计原理图的时候一般把VSSA和VREF-接地,把VREF+和VDDA接3V3,得到ADC的输入电压范围为:0-3.3V。如果想让输入的电压范围变宽,去到可以测试负电压或者更高的正电压,可以在外部加一个电压调理电路,把需要转换的电压(低电压)抬升或者(高电压)降压到0-3.3V,这样ADC就可以测量
输入通道:STM32的ADC有18个通道,其中外部的16个通道是ADCx_IN0、ADCx_IN1⋯ADCx_IN5。16个通道对应着不同的IO口,可以从手册查询到。其中ADC1/2/3和内部通道:ADC1的通道16连接芯片内部的温度传感器,Vrefint连接通道17。ADC2 的模拟通道16和17连接内部的VSS。ADC3的模拟通道9、14、15、16 和17连接内部的VSS
外部的16个通道在转换的时候分为规则通道和注入通道
规则通道:平时一般使用的是这个通道,最多有16路
注入通道:在规则通道转换的时候强行插入要转换的一种通道。如果在规则通道转换过程中,有注入通道插队,那么就要先转换完注入通道,等注入通道转换完成后,再回到规则通道的转换流程,跟中断程序很像。注入通道只有在规则通道存在时才会出现,最多有4路
通道转换顺序设置:
规则序列:规则序列寄存器有3个,分别为SQR3、SQR2、SQR1。SQR3控制着规则序列中的第一个到第六个转换,对应的位为:SQ1[4:0]-SQ6[4:0],第一次转换的是位4:0 SQ1[4:0],如果通道16想第一次转换,那么在SQ1[4:0] 写16即可。SQR2控制着规则序列中的第7到第12个转换,对应的位为:SQ7[4:0]-SQ12[4:0],如果通道1想第8个转换,则SQ8[4:0] 写1即可。SQR1控制着规则序列中的第13到第16个转换,对应位为:SQ13[4:0]-SQ16[4:0],如果通道6想第10个转换,则SQ10[4:0]写6即可。具体使用多少个通道,由SQR1的位L[3:0] 决定,最多16个通道
注入序列:注入序列寄存器JSQR只有一个,最多支持4个通道,由JSQR 的JL[2:0]决定。当JL<4,则JSQR跟SQR决定转换顺序的设置不一样,第一次转换的不是JSQR1[4:0],而是JCQRx[4:0] ,x = 4-JL),跟SQR相反。当JL=00(1个转换),转换的顺序是从JSQR4[4:0]开始,而不是从JSQR1[4:0]开始。当JL =4,跟SQR 一样
触发源:ADC转换可以由ADC控制寄存器2: ADC_CR2的ADON这个位来控制,写1的时候开始转换,写0的时候停止转换。除了这种控制方法,ADC还支持触发转换,包括内部定时器触发和外部IO触发。触发源是否要激活,由ADC控制寄存器2:ADC_CR2的EXTTRIG和JEXTTRIG激活
转换时间
ADC时钟:ADC输入时钟ADC_CLK 由PCLK2 经过分频产生,最大是14M,分频因子可以是2/4/6/8分频,没有1分频。一般设置PCLK2=HCLK=72M,经过ADC预分频器能分频到最大的时钟只能是12M
采样时间:ADC使用若干个ADC_CLK周期对输入的电压进行采样,采样的周期数可通过ADC采样时间寄存器ADC_SMPR1和ADC_SMPR2中的SMP[2:0]位设置,ADC_SMPR2控制的是通道0-9,ADC_SMPR1控制的是通道10-17。每个通道可以分别用不同的时间采样。其中采样周期(1/ADC_CLK)最小是1.5个,如果要达到最快的采样,应该设置采样周期为1.5个周期。ADC的转换时间跟ADC的输入时钟和采样时间有关,公式:Tconv =采样时间+ 12.5个周期。当ADCLK= 14MHZ(最高),采样时间设置为1.5周期(最快),总的转换时间(最短)Tconv = 14周期= 1us。一般设置PCLK2=72M,经过ADC预分频器能分频到最大的时钟只能是12M,采样周期设置为1.5 个周期,最短的转换时间为1.17us
采样后
ADC 转换后的数据,规则组的数据放在ADC_DR 寄存器,注入组的数据放在JDRx
中断:数据转换结束后,可以产生中断,中断分为规则通道转换结束中断、注入转换通道转换结束中断、模拟看门狗中断。
转换结束中断:转换结束中断跟平时接触的中断一样,有相应的中断标志位和中断使能位,还可以根据中断类型写相应配套的中断服务程序。中断读取适用于采集数据少,读取时比较慢
模拟看门狗中断:当被ADC转换的模拟电压低于低阈值或者高于高阈值时,就会产生中断,前提是我们开启了模拟看门狗中断,其中低阈值和高阈值由ADC_LTR和ADC_HTR设置。例如设置高阈值是2.5V,那么模拟电压超过2.5V的时候,就会产生模拟看门狗中断,低阈值也一样
DMA请求:规则和注入通道转换结束后,除了产生中断外,还可以产生DMA请求,把转换好的数据直接存储在内存里面。只有ADC1和ADC3可以产生DMA请求。一般在使用ADC的时候都会开启DMA传输。DMA读取,快,不需要写中断服务函数
电压转换:模拟电压经过ADC转换后,是一个12位的数字值,如果通过串口以16进制打印出来的话,可读性比较差,有时候需要把数字电压转换成模拟电压,也可以跟实际的模拟电压(用万用表测)对比,看看转换是否准确
根据数据量算出模拟量:
1-电压输入范围为:0~3.3V
2-分辨率为12位
3-最小精度为:3.3/2^12
4-设数字量为X,则有模拟量 Y = (3.3 / 2^12)*X
悬空一般是1.6V,接3.3V和0V来测试ADC
DAC
在常见的数字信号系统中,大部分传感器信号被化成电压信号,ADC把电压模拟信号转换成易于计算机存储、处理的数字编码,由计算机处理完成后,再由DAC输出电压模拟信号,该电压模拟信号常常用来驱动某些执行器件,使人类易于感知。如音频信号的采集及还原过程
DAC(数字/模拟转换模块):把输入的数字编码,转换成对应的模拟电压输出,功能与ADC相反。STM32有片上DAC外设,分辨率可配置为8位或12位的数字输入信号,具有两个DAC输出通道,这两个通道互不影响,每个通道都可以使用DMA功能,都具有出错检测能力,可外部触发
参考电源的引脚:VDDA、VSSA 、Vref+,STM32的DAC规定了参考电压:math:V_{ref +} 输入范围为2.4-3.3V
“数字至模拟转换器x”的输入为DAC的数据寄存器“DORx”的数字编码,经过它转换得的模拟信号由右侧的“DAC_OUTx”输出。数据寄存器“DORx”受“控制逻辑”支配,可以控制数据寄存器加入一些伪噪声信号或配置产生三角波信号
左上角为DAC的触发源,DAC根据触发源的信号来进行DAC转换,相当于DAC转换器的开关,可以配置的触发源为外部中断源触发、定时器触发或软件控制触发。如:控制正弦波的频率,需要定时器定时触发DAC进行数据转换
参考电压:DAC使用VREF+引脚作为参考电压。在设计原理图时,一般VSSA接地,VREF+和VDDA接3.3V,可得到DAC 的输出电压范围为:03.3V。如果想让输出的电压范围变宽,可以在外部加一个电压调理电路,把03.3V的DAC输出抬升到特定的范围
数模转换及输出通道: “数字至模拟转换器x”是核心部件,整个DAC外设都围绕它而展开。它以左边的VREF+作为参考电源,以DAC 的数据寄存器“DORx”的数字编码作为输入,经过它转换得的模拟信号由右侧的“DAC_OUTx”通道输出。其中各个部件中的“x”是指设备的标号,STM32中有2个DAC,每个DAC有1个对应的输出通道连接到特定的引脚,即:PA4-通道1,PA5-通道2,为避免干扰,使用DAC功能时,DAC 通道引脚需要被配置成模拟输入功能(AIN)
触发源及DHRx寄存器:在使用DAC时,不能直接对上述DORx寄存器写入数据,任何输出到DAC通道x 的数据都必须写入到DHRx寄存器中(其中包含DHR8Rx、DHR12Lx 等,根据数据对齐方向和分辨率的情况写入到对应的寄存器中)。数据被写入到DHRx 寄存器后,DAC会根据触发配置进行处理,若使用硬件触发,则DHRx中的数据会在3个APB1时钟周期后传输至DORx,DORx随之输出相应的模拟电压到输出通道;若DAC 设置为外部事件触发,可以使用定时器(TIMx_TRGO)、EXTI_9信号或软件触发(SWTRIGx)这几种方式控制数据DAC转换的时机,如:使用定时器触发,配合不同时刻的DHRx 数据,可实现DAC输出正弦波的功能
TIM—基本定时器
STM32F1系列中,除了互联型的产品,共有8个定时器,分为基本定时器,通用定时器和高级定时器
基本定时器:基本定时器TIM6和TIM7是一个16位的只能向上计数的定时器,没有外部的GPIO,是内部资源,只能定时
通用定时器:通用定时器TIM2/3/4/5是一个16位的可以向上/下计数的定时器,可以定时,输出比较(通过外部GPIO输出PWM信号),输入捕捉(测量一个信号的脉冲宽度、频率),每个定时器有四个外部IO
高级定时器:高级定时器TIM1/8 是一个16位的可以向上/下计数的定时器,可以定时,输出比较,输入捕捉,三相电机互补输出信号,每个定时器有8个外部IO
时钟源:定时器时钟TIMx_CLK(属于内部时钟CK_INT),经APB1预分频器后分频提供,如果APB1预分频系数等于1,则频率不变,否则频率乘以2,库函数中APB1预分频的系数是2,即PCLK1=36M,所以定时器时钟TIMxCLK=36*2=72M
控制器:控制器用于控制定时器的:复位、使能、计数、触发DAC,涉及到的寄存器为:CR1/2、DIER、EGR、SR
时基:定时器的核心是时基,基本定时器、通用定时器、高级定时器都有。包括:预分频器PSC、计数器CNT、自动重装载寄存器ARR
计数器时钟:定时器时钟经过PSC预分频器之后,即CK_CNT,用来驱动计数器计数。PSC 是一个16位的预分频器,可以对定时器时钟TIMxCLK进行1~65536之间的任何一个数进行分频。计算方式为:CK_CNT=TIMxCLK/(PSC+1)
计数器CNT:计数器CNT是一个16位的计数器,只能往上计数,最大计数值为65535。计数器在计数器时钟的驱动下开始计数,计数一次的时间为1/CK_CNT。当计数达到自动重装载寄存器的时候产生更新事件,并清零从头开始计数
自动重装载寄存器ARR:自动重装载寄存器ARR是一个16位的寄存器,这里面装着计数器能计数的最大数值。当计数到这个值的时候,如果使能了中断的话,定时器就产生溢出中断
定时时间的计算:定时器的定时时间等于计数器的中断周期乘以中断的次数。计数器在CK_CNT的驱动下,计一个数的时间是CK_CLK的倒数,等于:1/(TIMxCLK/(PSC+1)),产生一次中断的时间等于:1/(CK_CLK * ARR)。如果在中断服务程序里面设置一个变量time,用来记录中断的次数,定时时间等于:1/CK_CLK* (ARR+1)*time
影子寄存器
PSC和ARR都有影子寄存器,功能框图上有个影子
影子寄存器的存在起到一个缓冲的作用,用户值->寄存器->影子寄存器->起作用,如果不使用影子寄存器则用户值在写到寄存器之后立即起作用
ARR影子,TIMx_CR1:APRE位控制
定时时间计算(修改PSC、ARR的值)
1、PSC = 72-1,定时器频率=72M/(PSC+1)=1MHZ,计数器计数一次1us
2、ARR = 1000-1,从0计数到999,则计了1000次,1usx1000,最大能计数65.536ms
3、中断周期T = 1000 *1/1000000 = 1ms
TIM—高级定时器
高级定时器(TIM1和TIM8):计数器16bit,上/下/两边计数,TIM1和TIM8,通道1~3有互补输出GPIO。高级定时器和通用定时器在基本定时器的基础上引入了外部引脚,可以实现输入捕获和输出比较功能。高级控制定时器比通用定时器增加了工业电机控制方面:可编程死区互补输出、重复计数器、带刹车(断路)功能
时钟源:高级控制定时器有四个时钟源可选,时钟来自PCLK2,为72M,可实现1~65536分频
• 内部时钟源CK_INT:内部时钟CK_INT来自芯片内部,等于72M,一般情况下使用内部时钟
• 外部时钟模式1:外部输入引脚TIx(x=1,2,3,4),当使用外部时钟模式1的时候,时钟信号来自定时器的输入通道,分别为TI1/2/3/(TIMx_CH1/2/3/4)。如果来自外部的时钟信号的频率过高或者混杂有高频干扰信号的话,需要使用滤波器对信号重新采样,达到降频或者去除高频干扰的目的。边沿检测的信号来自于滤波器的输出,在成为触发信号之前,需要进行边沿检测,决定是上升沿有效还是下降沿有效。当使用外部时钟模式1时,触发源有两个,滤波后的定时器输入1(TI1FP1)和滤波后的定时器输入2(TI2FP2)。选定了触发源信号后,需把信号连接到TRGI引脚,让触发信号成为外部时钟模式1的输入,最终等于CK_PSC,然后驱动计数器CNT计数。最后只需使能计数器开始计数,外部时钟模式1的配置完成
• 外部时钟模式2:外部触发输入ETR,当使用外部时钟模式2的时候,时钟信号来自于定时器的特定输入通道TIMx_ETR,来自ETR引脚输入的信号可以选择为上升沿或者下降沿有效。ETRP的信号的频率不能超过TIMx_CLK(72M)的1/4,当触发信号的频率很高,使用分频器来降频。如果ETRP 的信号的频率过高或者混杂有高频干扰信号的话,使用滤波器对ETRP信号重新采样,达到降频或者去除高频干扰的目的。经过滤波器滤波的信号连接到ETRF 引脚后,触发信号成为外部时钟模式2的输入,最终等于CK_PSC,然后驱动计数器CNT计数。最后使能计数器开始计数,外部时钟模式2的配置完成
• 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器。硬件上高级控制定时器和通用定时器在内部连接在一起,可以实现定时器同步或级联。主模式的定时器可以对从模式定时器执行复位、启动、停止或提供时钟
控制器:高级控制定时器控制器部分包括触发控制器、从模式控制器以及编码器接口。触发控制器用来针对片内外设输出触发信号,比如为其它定时器提供时钟和触发DAC/ADC转换。编码器接口专门针对编码器计数而设计。从模式控制器可以控制计数器复位、启动、递增/递减、计数。CR1、CR2、SMCR、CCER,主要是这几个寄存器
时基单元:高级控制定时器时基单元功能包括四个寄存器,分别是计数器寄存器(CNT)、预分频器寄存器(PSC)、自动重载寄存器(ARR) 和重复计数器寄存器(RCR)。其中重复计数器RCR 是高级定时器独有,通用和基本定时器没有
输入捕获
输入捕获:可以对输入的信号的上升沿、下降沿或者双边沿进行捕获,常用有测量输入信号的脉宽、测量PWM 输入信号的频率和占空比。输入捕获的大概的原理就是,当捕获到信号的跳变沿的时候,把计数器CNT的值锁存到捕获寄存器CCR中,把前后两次捕获到的CCR寄存器中的值相减,就可以算出脉宽或者频率。如果捕获的脉宽的时间长度超过你的捕获定时器的周期,就会发生溢出,需要做额外的处理
输入通道:需要被测量的信号从定时器的外部引脚TIMx_CH1/2/3/4进入,通常叫TI1/2/3/4
输入滤波器:当输入的信号存在高频干扰的时候,需要对输入信号进行滤波,即进行重新采样,根据采样定律,采样的频率必须大于等于两倍的输入信号。比如输入的信号为1M,又存在高频的信号干扰,那么此时就很有必要进行滤波,可以设置采样频率为2M,在保证采样到有效信号的基础上把高于2M的高频干扰信号过滤掉
边沿检测器:边沿检测器用来设置信号在捕获的时候是什么边沿有效,可以是上升沿,下降沿,或者是双边沿
捕获通道:捕获通道是IC1/2/3/4,每个捕获通道都有相应的捕获寄存器CCR1/2/3/4,当发生捕获的时候,计数器CNT的值就会被锁存到捕获寄存器中。捕获通道用来捕获输入信号的通道,一个输入通道的信号可以同时输入给两个捕获通道。比如输入通道TI1的信号经过滤波边沿检测器之后的TI1FP1和TI1FP2可以进入到捕获通道IC1和IC2,这就是PWM输入捕获(只能使用通道1TIMx_CH1和通道2 TIMx_CH2),只有一路输入信号(TI1)却占用了两个捕获通道(IC1和IC2)。当只需要测量输入信号的脉宽时候,用一个捕获通道即可
预分频器:捕获通道ICx 的输出信号会经过一个预分频器,用于决定发生多少个事件时进行一次捕获
捕获寄存器:经过预分频器的信号ICxPS是最终被捕获的信号,当第一次发生捕获时,计数器CNT的值会被锁存到捕获寄存器CCR中,还会产生CCxI 中断
输入捕获应用:输入捕获一般用在脉冲跳变沿时间测量、PWM输入测量
PWM输入模式
直连与非直连,非直连捕获对应的是周期,直连捕获对应的是占空比
PWM输入模式:IC1、IC2同时捕获,进入中断。IC2捕获的是占空比。第二次IC1捕获的值-第一次IC1捕获的值是周期。计算占空比和脉宽的值的时候,捕获的值要+1,因为Counter从0开始计数
断路功能、死区时间
半桥驱动电路:用来驱动电机的。一般从单片机输出的PWM信号因为功率不够,不能够直接驱动电机,首先需要经过电机驱动电路把信号(电流)放大,然后才能驱动电机,电机如果有两个的话,一路是正转(+),一路是反转(-)
断路功能:电机控制的刹车功能,使能断路功能时,根据相关控制位状态修改输出信号电平。在任何情况下,OCx和OCxN输出都不能同时为有效电平,这关系到电机控制常用的H桥电路结构原因。断路源可以是时钟故障事件,由内部复位时钟控制器中的时钟安全系统(CSS)生成,也可以是外部断路输入IO,两者是或运算关系。系统复位启动默认关闭断路功能
加入死去时间原因:上面MOS管导通的时候驱动电机正转,上面MOS管截至的时候,控制Q2反转,因为控制器发送命令后,Q1不能马上关掉,这个时候如果Q2马上打开,DC和GND(电源和地)连在一起。
死区时间:Q2需要在输出一段低电平,等待Q1完全关闭的这段时间,由元器件工艺特性决定,一般都是在ns级别,元器件参考手册里面一般有死区时间
输出比较
输出比较:通过定时器的外部引脚对外输出控制信号,有冻结、将通道X(x=1,2,3,4)设置为匹配时输出有效电平、将通道X设置为匹配时输出无效电平、翻转、强制变为无效电平、强制变为有效电平、PWM1和PWM2这八种模式。其中PWM模式在输出比较中使用最多。输出控制在编程的时候只需要配置一个成员就可以。同一个定时器不能同时用捕获和输出比较
输出比较应用:输出比较模式总共有8种,最常用PWM模式,其他几种模式可看数据手册。PWM 信号主要都是用来控制电机,一般的电机控制用的都是边沿对齐模式,FOC 电机一般用中心对齐模式
PWM输出:对外输出脉宽(即占空比)可调的方波信号,信号频率由自动重装寄存器 ARR 的值决定,占空比由比较寄存器 CCR 的值决定。
IWDG独立看门狗
看门狗:STM32有两个看门狗,一个是独立看门狗,另外一个是窗口看门狗。看门狗功能由VDD电压域供电,在停止模式和待机模式下仍能工作
独立看门狗IWDG: 12 位的递减计数器,当计数器的值从某个值一直减到0时,系统会产生一个复位信号(IWDG_RESET)。如果在计数没减到0之前,刷新了计数器的值的话,那么就不会产生复位信号,这个动作就是喂狗
独立看门狗应用:独立看门狗一般用来检测和解决由程序引起的故障,比如一个程序正常运行的时间是50ms,在运行完这个段程序之后紧接着进行喂狗,设置独立看门狗的定时溢出时间为60ms,比需要监控的程序50ms多一点,如果超过60ms还没有喂狗,那就说明监控的程序出故障了,跑飞了,那么就会产生系统复位,让程序重新运行
独立看门狗时钟:由独立的RC振荡器LSI提供,即使主时钟发生故障它仍然有效,非常独立。LSI 的频率一般在30~60KHZ 之间,根据温度和工作场合会有一定的漂移,一般取40KHZ,所以独立看门狗只适用于对时间精度要求比较低的场合
计数器时钟:递减计数器的时钟由LSI经过一个8位的预分频器得到,分频因子:[4,8,16,32,64,128,256,256],计数器时钟CK_CNT=40/ 4*2^PRV,一个计数器时钟,计数器减一
计数器:一个12 位的递减计数器,最大值为0XFFF,当计数器减到0时,会产生一个复位信号:IWDG_RESET,让程序重新启动运行,如果在计数器减到0 之前刷新了计数器的值的话,就不会产生复位信号,重新刷新计数器值(喂狗)
重装载寄存器:一个12 位的寄存器,里面装着要刷新到计数器的值,这个值的大小决定着独立看门狗的溢出时间。超时时间Tout = (4*2^prv) / 40 * rlv (s) ,prv是预分频器寄存器的值,rlv是重装载寄存器的值
键寄存器IWDG_KR:独立看门狗的一个控制寄存器,主要有三种控制方式,往这个寄存器写入下面三个不同的值有不同的效果。通过写往键寄存器写0XCCC来启动看门狗属于软件启动的方式,一旦独立看门狗启动,只有复位才能关掉
状态寄存器SR:状态寄存器SR只有位0:PVU和位1:RVU有效,这两位只能由硬件操作,当RVU/PVU等于0的时候才可以更新重装载寄存器/预分频寄存器
窗口看门狗WWDG
窗口看门狗WWDG:一个递减计数器不断的往下递减计数,当减到一个固定值0X40时还不喂狗的话,产生复位,这个值叫窗口的下限,固定的值不能改变。窗口看门狗的计数器的值在减到窗口的上限之前喂狗的话也会产生复位,上限值由用户独立设置。窗口看门狗计数器的值必须在上窗口和下窗口之间才可以喂狗
窗口看门狗应用:WWDG一般被用来监测,由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。比如一个程序段正常运行的时间是50ms,在运行完这个段程序之后紧接着进行喂狗,如果在规定的时间窗口内还没有喂狗,那就说明我们监控的程序出故障了,跑飞了,那么就会产生系统复位,让程序重新运行
RLR是重装载寄存器,用来设置独立看门狗的计数器的值。TR是窗口看门狗的计数器的值,由用户独立设置,WR是窗口看门狗的上窗口值,由用户独立设置
窗口看门狗时钟:来自PCLK1,PCLK1最大是36M,由RCC时钟控制器开启。
计数器时钟:由CK计时器时钟经过预分频器分频得到,分频系数可以是[0,1,2,3],其中CK 计时器时钟=PCLK1/4096。计数器的时钟CNT_CK=PCLK1/4096/(2^WDGTB),计数器减一个数的时间T= 1/CNT_CK = Tpclk1 * 4096 * (2^WDGTB)
窗口值:窗口看门狗必须在计数器的值在一个范围内才可以喂狗,其中下窗口的值是固定的0X40,上窗口的值可以改变,具体的由配置寄存器CFR 的位6:0 W[6:0]设置。其值必须大于0X40,如果小于或者等于0X40就是失去了窗口的价值,而且也不能大于计数器的值,所以必须得小于0X7F。窗口值设置成多大,根据需要监控的程序的运行时间来决定。如果要监控的程序段A运行的时间为Ta,当执行完这段程序之后就要进行喂狗,如果在窗口时间内没有喂狗的话,那程序就肯定是出问题了。一般计数器的值TR设置成最大0X7F,窗口值为WR,计数器减一个数的时间为T,那么时间:(TR-WR)*T应该稍微小于Ta即可,这样就能做到刚执行完程序段A之后喂狗,起到监控的作用,也就可以算出WR的值是多少
看门狗超时时间:Twwdg = Tpclk1 x 4096 x 2^wdgtb x (T[5:0]+1) ms,当PCLK1 = 36MHZ 时,WDGTB取不同的值时有最小和最大的超时时间
RTC
STM32的RTC外设(Real Time Clock):实质是一个掉电后还继续运行的定时器。从定时器的角度来说,相对于通用定时器TIM外设,它只有很纯粹的计时和触发中断的功能,它是一个32位的计数器,只能向上计数。使用的时钟源有三种,分别为高速外部时钟的128 分频(HSE/128)、低速内部时钟LSI以及低速外部时钟LSE;使HSE分频时钟或LSI的话,在主电源VDD掉电的情况下,这两个时钟来源都会受到影响,因此没法保证RTC正常工作。因此RTC一般使用低速外部时钟LSE,在设计中,频率通常为实时时钟模块中常用的32.768KHz,这是因为32768 = 215,分频容易实现。在主电源VDD有效的情况下(待机),RTC还可以配置闹钟事件使STM32退出待机模式;从掉电还继续运行的角度来说,它是STM32中唯一一个具有如此强大功能的外设。掉电,是指主电源VDD断开的情况,为了RTC外设掉电继续运行,必须接上锂电池给STM32的RTC、备份发卡通过VBAT引脚供电。当主电源VDD有效时,由VDD给RTC外设供电;而当V:sub:DD掉电后,由VBAT给RTC外设供电。无论由什么电源供电,RTC中的数据都保存在属于RTC的备份域中,若主电源VDD和VBAT都掉电,那么备份域中保存的所有数据将丢失。备份域除了RTC 模块的寄存器,还有42个16位的寄存器可以在VDD掉电的情况下保存用户程序的数据,系统复位或电源复位时,这些数据也不会被复位
框图中浅灰色的部分都是属于备份域,在VDD掉电时可在VBAT的驱动下继续运行,包括RTC的分频器,计数器,闹钟控制器。若VDD电源有效,RTC可以触发RTC_Second(秒中断)、RTC_Overflow(溢出事件)和RTC_Alarm(闹钟中断)。其中的定时器溢出事件无法被配置为中断。若STM32原本处于待机状态,可由闹钟事件或WKUP事件(外部唤醒事件,属于EXTI 模块,不属于RTC)使STM32退出待机模式。闹钟事件在计数器RTC_CNT的值等于闹钟寄存器RTC_ALR的值时触发。在备份域中所有寄存器都是16位。RTC控制相关的寄存器,计数器RTC_CN的32位由RTC_CNTL和RTC_CNTH两个寄存器组成,分别保存定时计数值的低16位和高16位。在配置RTC 模块的时钟时,通常把输入的32768Hz的RTCCLK 进行32768分频得到实际驱动计数器的时钟TR_CLK =RTCCLK/32768=1 Hz,计时周期为1 秒,计时器在TR_CLK的驱动下计数,即每秒计数器RTC_CNT的值加1。
由于备份域的存在,使RTC核具有了完全独立于APB1接口的特性,因此对RTC寄存器的访问要遵守一定的规则。系统复位后,默认禁止访问后备寄存器和RTC,防止对后备区域(BKP)的意外写操作。执行以下操作使能对后备寄存器和RTC的访问:
设置RCC_APB1ENR寄存器的PWREN和BKPEN位来使能电源和后备接口时钟
设置PWR_CR寄存器的DBP位使能对后备寄存器和RTC的访问
设置后备寄存器为可访问后,在第一次通过APB1接口访问RTC时,因为时钟频率的差异,必须等待APB1与RTC外设同步,确保被读取出来的RTC寄存器值是正确的。若在同步之后,一直没有关闭APB1的RTC外设接口,就不需要再次同步了。如果内核要对RTC寄存器进行任何的写操作,在内核发出写指令后,RTC模块在3个RTCCLK时钟之后,才开始正式的写RTC寄存器操作。由于RTCCLK的频率比内核主频低得多,所以每次操作后必须要检查RTC关闭操作标志位RTOFF,当这个标志被置1时,写操作才正式完成。以上的操作都具有库函数
UNIX 时间戳
计数器RTC_CNT 的计数值置0,然后每秒加1,RTC_CNT在136年时溢出
计时元年、时间戳:假如某个时刻读取到计数器的数值为X = 606024*2,即两天时间的秒数,而假设又知道计数器是在2011年1月1日的0时0分0秒置0的,那么就可以根据计数器的这个相对时间数值,计算得这个X时刻是2011年1月3日的0时0分0秒。而计数器则会在(2011+136) 年左右溢出,也就是说到了(2011+136)年时,如果还在使用这个计数器提供时间的话就会出现问题。在这个例子中,定时器被置0的这个时间被称为计时元年,相对计时元年经过的秒数称为时间戳(计数器中的值)
UNIX时间戳、UNIX计时元年:大多数操作系统都是利用时间戳和计时元年来计算当前时间的,而这个时间戳和计时元年都取了同一个标准——UNIX时间戳和UNIX计时元年。UNIX计时元年被设置为格林威治时间1970年1月1日0时0分0秒,UNIX时间戳即为当前时间相对于UNIX计时元年经过的秒数
STM32的电源管理
在很多应用场合,电子设备的功耗要求非常苛刻,如某些传感器信息采集设备,仅靠小型的电池提供电源,要求工作长达数年之久,且期间不需要任何维护;由于智慧穿戴设备的小型化要求,电池体积不能太大导致容量也比较小(不用经常充电),所以也很有必要从控制功耗入手,提高设备的续行时间。STM32有电源管理外设监控电源并管理设备的运行模式,确保系统正常运行,并尽量降低器件的功耗
电源管理器、可编程电压检测器
电源监控器:STM32通过引脚VDD从外部获取电源,STM32内部电源监控器用于检测VDD的电压,以实现复位功能及掉电紧急处理功能,保证系统可靠地运行
上电复位与掉电复位(POR与PDR):当检测到VDD的电压低于阈值VPOR及VPDR时,无需外部电路辅助,STM32芯片会自动保持在复位状态,防止因电压不足强行工作而带来严重的后果。在刚开始电压低于VPOR时(约1.92V),STM32保持在上电复位状态(POR,Power On Reset),当VDD电压持续上升至大于VPOR时,芯片开始正常运行,在芯片正常运行的时候,当检测到VDD电压下降至低于VPDR 阈值(约1.88V),会进入掉电复位状态(PDR,Power Down Reset)
可编程电压检测器PVD:STM32还提供了可编程电压检测器PVD,它也是实时检测VDD 的电压,当检测到电压低于编程的VPVD阈值时,会向内核产生一个PVD中断(EXTI16线中断) 以使内核在复位前进行紧急处理。该电压阈值可通过电源控制寄存器PWR_CSR设置。使用PVD可配置8个等级。其中的上升沿和下降沿分别表示类似POR与PDR中VDD 电压上升过程及下降过程的阈值
STM32的电源系统
STM32的电源系统:为了方便进行电源管理,STM32把它的外设、内核等模块跟据功能划分了供电区域。STM32的电源系统分为备份域电路、内核电路以及ADC电路三部分:
ADC电源及参考电压(VDDA供电区域):为了提高转换精度,STM32的ADC配有独立的电源接口,方便进行单独的滤波。ADC的工作电源使用VDDA引脚输入,使用VSSA作为独立的地连接,VREF引脚则为ADC提供测量使用的参考电压
调压器供电电路(VDD/1.8V供电区域):在STM32的电源系统中调压器供电的电路是最主要的部分,调压器为备份域及待机电路以外的所有数字电路供电,其中包括内核、数字外设以及RAM,调压器的输出电压约为1.8V,使用调压器供电的电路区域被称为1.8V域。调压器可以运行在“运行模式”、“停止模式”以及“待机模式”。在运行模式下,1.8V域全功率运行;在停止模式下1.8V域运行在低功耗状态,1.8V区域的所有时钟都被关闭,相应的外设都停止了工作,但它会保留内核寄存器以及SRAM的内容;在待机模式下,整个1.8V域都断电,该区域的内核寄存器及SRAM内容都会丢失(备份区域的寄存器不受影响)
备份域电路(后备供电区域):STM32的LSE振荡器、RTC及备份寄存器这些器件被包含进备份域电路中,这部分的电路可以通过STM32的VBAT引脚获取供电电源,在实际应用中一般会使用3V的钮扣电池对该引脚供电
备份域电路的左侧有一个电源开关结构,它的功能类似双二极管,在它的“1”处连接了VBAT电源,“2”处连接了VDD主电源(一般为3.3V),右侧“3”处引出到备份域电路中。当VDD主电源存在时,由于V:sub:DD电压较高,备份域电路通过VDD供电,节省钮扣电池的电源,仅当VDD掉电时,备份域电路由钮扣电池通过VBAT供电,保证电路能持续运行,从而可利用它保留关键数据文章来源:https://www.toymoban.com/news/detail-772556.html
STM32的功耗模式
STM32的功耗模式:按功耗由高到低排列,三种低功耗模式层层递进,运行的时钟或芯片功能越来越少,因而功耗越来越低。STM32有运行、睡眠、停止和待机四种工作模式。上电复位后STM32处于运行状态时,当内核不需要继续运行,就可以选择进入后面的三种低功耗模式降低功耗,这三种模式中,电源消耗不同、唤醒时间不同、唤醒源不同,用户需要根据应用需求,选择最佳的低功耗模式。在睡眠模式、停止模式及待机模式中,若备份域电源正常供电,备份域内的RTC都可以正常运行,备份域内的寄存器的数据会被保存,不受功耗模式影响
睡眠模式:在睡眠模式中,仅关闭了内核时钟,内核停止运行,但其片上外设,CM3核心的外设全都还照常运行。有两种方式进入睡眠模式,它的进入方式决定了从睡眠唤醒的方式,分别是WFI(wait forinterrupt) 和WFE(wait for event),即由等待“中断”唤醒和由“事件”唤醒
停止模式:在停止模式中,进一步关闭了其它所有的时钟,于是所有的外设都停止了工作,但由于其1.2V区域的部分电源没有关闭,还保留了内核的寄存器、内存的信息,所以从停止模式唤醒,并重新开启时钟后,还可以从上次停止处继续执行代码。停止模式可以由任意一个外部中断(EXTI)唤醒,在停止模式中可以选择电压调节器为开模式或低功耗模式
待机模式:除了关闭所有的时钟, 1.8V区域的电源也完全关闭了。从待机模式唤醒后,由于没有之前代码的运行记录,只能对芯片复位,重新检测boot条件,从头开始执行程序。它有四种唤醒方式,分别是WKUP(PA0)引脚的上升沿,RTC闹钟事件,NRST引脚的复位和IWDG(独立看门狗)复位文章来源地址https://www.toymoban.com/news/detail-772556.html
总结
到了这里,关于STM32的入门——CM3芯片STM32F103VET6的使用和相关外设的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!