STM32学习笔记(11)——定时器初步应用(1)
前排提示一下:这些代码都是本人跟着野火的教程视频写的(与野火的例程会有出入),编程思路则由本人编写。 之前我们已经详细过了一遍高级定时器的功能框图,现在来简要说一下其他定时器。STM32 有三种定时器,定时器分类如下: 其中,高级定时器(定时、输出比较、输入捕获、互补输出) 的功能最齐全,其次是通用定时器(定时、输出比较、输入捕获),最后是基本定时器 (定时,只能向上计数)。 一、基本定时器——LED循环亮灭 【实现功能】通过基本定时器(TIM6、TIM7),使 LED 每隔 1000ms 反转一次工作模式,即实现循环亮灭的效果。 【基本思路】要产生 1000ms 的时间间隔,首先要想办法产生 1ms 的时间。时钟源的频率为 72MHz,想要得到 1MHz 的定时器频率,就必须使分频因子 PSC = 72 - 1,这样定时器频率就为 72 / (PSC+1) = 1MHz,定时器周期为 1/10^6 秒,那么只要重复1000次这样的周期就是 1ms,所以 Period(ARR) = 1000 - 1。因此,1ms 时间后将会产生一次更新事件。 通过更新事件产生一次中断,进而运行...
STM32学习笔记(10)——高级定时器TIM
前排提示:本笔记参考了野火PPT的大部分内容。 STM32F103系列有8个定时器,其中分为2个高级定时器,4个通用定时器、2个基本定时器。 下面为高级定时器TIM功能框图(来自野火PPT),由于高级定时器功能相当复杂,因此本文将大篇幅介绍每种功能(定时、输入捕获、输出比较、刹车输入)。我们将功能框图分为6个部分进行讲解: 一、时钟源 本部分内容可见STM32中文参考手册13.3.4时钟选择。 计数器时钟可由内部时钟源(CK_INT)、外部时钟模式1(外部的GPIO TIx(x = 1、2、3、4))、外部时钟模式2(外部的GPIO ETR)、内部触发模式(ITRx)提供。无论是由什么时钟源提供,最终都会成为CK_PSC,经过预分频器,成为计数器时钟。 1. 内部时钟源 我们最常用的是内部时钟源,通常的频率为72MHz。这个数字是怎么来的呢? 内部时钟源来自 RCC 时钟的 TIMx_CLK,可以查看 STM32 的时钟树,它是经过 APB2 预分频器后得到的,如果预分频因子等于 1,则时钟频率x 1,否则频率x 2。由于经过 APB1 和 APB2 预分频后得到的 PCLK1...
STM32学习笔记(9)——(I2C续)读写EEPROM
一、概述 1. 背景介绍 在微机发展的早期,出现了BIOS(Basic Input Output System),它是个人电脑启动时加载的第一个软件,用来完成对系统的加电自检、各功能模块的初始化、基本输入输出的驱动程序及引导操作系统。人们希望掉电之后 BIOS 数据不能丢失,于是将 BIOS 烧录到 ROM。事实上它是一组固化到计算机内主板上一个 ROM 芯片上的程序。 最初的最初,BIOS 都是通过一种特殊的烧录方法烧入 ROM 中的,但是一旦烧进去,你只能读 ROM,里面的内容是无法更改的。万一发现错误,只能丢弃,换另一块ROM,重做一遍,这就非常麻烦了。 后来的后来,一位以色列工程师发明了EPROM(Erasable Programmable Read-Only Memory),这种芯片比较奇葩,封装顶部开了一个透明小窗口,如果要往芯片内部录入程序,就需要使用强紫外线进行擦除(当然你放到太阳底下也是可以的)。因此,一般情况下为了不破坏内部的数据,就需要用纸来盖住窗口。好景不长,程序员和硬件工程师还是觉得这样太麻烦了。 最后的最后,EEPROM(Electrically Er...
STM32学习笔记(8)——I2C总线设备
一、I2C协议简介 I2C通讯协议 (Inter-Integrated Circuit,读作I平方C、I方C) 是由Phiilps公司开发的,由于它引脚少,硬件实现简单,可扩展性强,不需要USART、CAN等通讯协议的外部收发设备,现在被广泛地使用在系统内多个集成电路间的通讯。 1. 物理层 (感谢野火的PPT,一部分内容参考了野火)如下图所示即为I2C的物理层: 下面来简要介绍物理层需要了解的知识点: 总线: 多个设备共用的信号线,有两条:一条双向串行数据线 (SDA),一条串行时钟线 (SCL)。 主机和从机: 总线上挂载着多个通讯主机和通讯从机,每个连接到总线的从机设备都有独一无二的通讯地址,主机通过这些地址对从机设备进行访问。一般来说,总线上挂载着五六个从机和一个主机就够用了。 通讯: 当主机与从机正在进行通讯的时候,从机设备输出低电平,将总线拉成低电平,其他设备输出高阻态,不能参与通讯。 上拉电阻: 两条总线均通过上拉电阻连接到电源。当所有从机设备空闲时,这些设备会输出高阻态,由上拉电阻把总线拉成高电平,这些设备就相当于与总线断开了。 如果不是用高阻态表示高电平...
STM32学习笔记(7)——DMA直接存储器访问
一、DMA简介 可参考STM32中文参考手册第10章DMA控制器。 直接存储器存取(Direct Memory Access,DMA) 用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。DMA 传输方式无需 CPU 直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为 RAM 与 I/O 设备开辟一条直接传送数据的通路, 能使 CPU 的效率大为提高。 DMA 是干什么用的呢?一般来说,如果没有DMA ,CPU如果想从外设“搬运”数据到存储器(Peripheral to Memory,P2M),或者从一个存储器到另一个存储器(Memory To Memory,M2M),数据必须要经过CPU,这就需要CPU 去亲力亲为。在运行过程中,CPU经常要为这种琐碎的事情被打断,很影响效率。所以,就有了DMA。现在,CPU 就不用那么麻烦了,CPU 只需要“叫”一声DMA,说你帮我去搬一下数据,从这搬到那,DMA 就会代替 CPU 完成这份工作,再也不用 CPU 自己去做了。 ...
STM32学习笔记(6)——USART串口通信
零、基础知识 本节主要写一下通信的一些基础知识,简单过一遍,防忘。 1. 通信基本知识 (1)数据传送方式 分类:串行和并行。 (2)数据通信方向 分类:全双工、半双工和单工。 (3)数据同步方式 分类:同步和异步。 (4)通信速率 比特率(Bitrate):每秒钟传输的二进制位数,单位为比特每秒(bit/s)。 波特率(Baudrate):表示每秒钟传输的码元个数,单位为波特(B),没有每秒!(常用的波特率:4800、9600、19200、38400、43000、56000、57600、115200) 码元:举个例子,当我们用一个二进制数(0或1)表示信息时,0或1为一个码元,它只有一个位数;当用两个二进制数(00,01,10,11)表示信息时,譬如01,就是一个码元,它有两个位数。 2. 串口通信协议 (1)物理层 物理层:规定通讯系统中具有机械、电子功能部分的特性,确保原始数据在物理媒体的传输。其实就是硬件部分。 RS-232标准 RS232标准串口主要用于工业设备直接通信。电平转换芯片一般有MAX3232,SP3232。 TTL电平标准是5V表示逻辑1,0V表示...
STM32学习笔记(5)——系统定时器SysTick
单独拿出来讲的一个内核外设(所以不要期望在STM32中文参考手册找到它!即使找到也只会叫你看cm3内核编程手册),说明它真的很重要。 一、系统定时器Systick 1. SysTick简介 SysTick是一个24位的系统节拍定时器,具有自动重载和溢出中断功能,所有基于Cortex M3或Cortex M4处理器的微控制器都有这个定时器。 Systick定时器常用来做延时,或者用来做实时系统的心跳时钟。这样可以节省MCU资源,不用浪费一个定时器。比如UCOS中,分时复用,需要一个最小的时间戳,一般在STM32+UCOS系统中,都采用Systick做UCOS心跳时钟。 它一个24位的倒计数定时器(意味着有2^24个时间间隔),计到0时,将从RELOAD寄存器中自动重装载定时初值。只要不把它在SysTick控制及状态寄存器中的使能位清除,就永不停息,即使在睡眠模式下也能工作。 学过51单片机的同学应该对计数器比较熟悉了。 SysTick在NVIC的中断向量号为6(可对照STM32中文参考手册9.1.2节中断和异常向量中表格的灰色部分)。 2. SysTick相关寄存器 SysTick...
STM32学习笔记(4)——NVIC中断优先级管理和外部中断EXTI
一、NVIC中断优先级管理 1. 中断简介 在Cortex-M3(CM3)内核中,每个中断的优先级都是用寄存器中的8位来设置的,这样就有2^8 =256级中断,意味着可以支持256个中断,这其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。但许多芯片厂商并没有使用CM3内核的全部东西,而是只用了它的一部分,而多余的部分应该是设计者考虑到后续应用发展而冗余设计的。 实际情况中,芯片厂商根据自己生产的芯片做出了调整。比如ST(意法半导体)公司的STM32F1xx和F4xx系列只使用了这个(寄存器NVIC->IPR,如图所示)8位中的高四位[7:4],低四位取零,这样2^4=16,只能表示16级中断嵌套。 STM32有84个中断,包括16个内核中断和68个可屏蔽中断,具有16级可编程的中断优先级。我们使用的是STM32F103系列,只有60个可屏蔽中断,而在107系列有68个。 2. 中断向量表 中断向量表为每个外设作了硬件编号,可以把它理解为默认顺序。如果有两个外设工作顺序发生冲突(一般在NVIC设置好后就很少发生这种情况)时,就按照这个表来分执行...
STM32学习笔记(3)——时钟系统
一、STM32时钟系统 1. STM32时钟系统框图 STM32的时钟系统非常强大,但也非常复杂。下面为时钟树: 下面分别介绍图中的各个元素 (STM32中文参考手册6.2节时钟): (1)最左边 最左边的OSC_IN和OSC_OUT是两个引脚,默认是外部晶振引脚。(我们的板子接了8MHz的晶振,数据手册表示可以接4——16MHz的晶振) MCO(microcontroller clock output)是输出内部时钟,该功能能将STM32内部的时钟通过引脚PA8输出,要进行引脚复用与功能设置。我们可以通过示波器(可惜我们没有,要到实验室去接)监控 MCO 引脚的时钟输出来验证系统时钟配置是否正确。STM32可以选择一个时钟信号输出到MCO上,可以选择为PLL输出的2分频、HSI、HSE、或者系统时钟(SYSCLK)。 (2) STM32的5个时钟源(蓝色框图) 这些时钟源由晶振电路或RC振荡器组成,为系统提供一定的工作频率。 HSI(high speed internal)是高速内部时钟,RC振荡器,频率为8MHz,精度不高。 HSE(high speed exter...
C++并发与多线程(5)——call_once和条件变量condition_varible
一、call_once 在多线程的环境下,有些时候我们不需要某给函数被调用多次或者某些变量被初始化多次,它们仅仅只需要被调用一次或者初始化一次即可。 为了解决上述多线程中出现的资源竞争导致的数据不一致问题,我们大多数的处理方法就是使用互斥锁来处理。在C++11中提供了最新的处理方法:使用std::call_once函数模板来处理,需包含头文件#include<mutex>。 头文件内对此的定义如下: 12template <class Fn, class... Args>void call_once (once_flag& flag, Fn&& fn, Args&&... args); 第一个参数是一个标记,第二个参数可以是函数、成员函数、函数对象、lambda函数。 call_once()需要与一个标记结合使用,这个标记为std::once_flag。其实once_flag是一个结构,call_once()就是通过标记来决定函数是否执行,调用成功后,就把标记设置为一种已调用状态。 多个线程同时执行时,一个线程会等待...



