GPIO 主要特性
● 受控I/O 多达16 个
● 输出状态:推挽或开漏+ 上拉/下拉
● 从输出数据寄存器(GPIOx_ODR) 或外设(复用功能输出)输出数据
● 可为每个I/O 选择不同的速度
● 输入状态:浮空、上拉/下拉、模拟
● 将数据输入到输入数据寄存器(GPIOx_IDR) 或外设(复用功能输入)
● 置位和复位寄存器(GPIOx_BSRR),对GPIOx_ODR 具有按位写权限
● 锁定机制(GPIOx_LCKR),可冻结I/O 配置
● 模拟功能
● 复用功能输入/输出选择寄存器(一个I/O 最多可具有16 个复用功能)
● 快速翻转,每次翻转最快只需要两个时钟周期
● 引脚复用非常灵活,允许将I/O 引脚用作GPIO 或多种外设功能中的一种
GPIO 8种工作模式(gpio_init.GPIO_Mode)
(1) GPIO_Mode_AIN 模拟输入
(2) GPIO_Mode_IN_FLOATING 浮空输入
(3) GPIO_Mode_IPD 下拉输入
(4) GPIO_Mode_IPU 上拉输入
(5) GPIO_Mode_Out_OD 开漏输出
(6) GPIO_Mode_Out_PP 推挽输出
(7) GPIO_Mode_AF_OD 复用开漏输出
(8) GPIO_Mode_AF_PP 复用推挽输出
GPIO 寄存器
每组IO口含下面7个寄存器。也就是7个寄存器,一共可以控制一组GPIO的16个IO口。
GPIOx->CRL :端口配置低寄存器
GPIOx->CRH:端口配置高寄存器
GPIOx->IDR:端口输入寄存器
GPIOx->ODR:端口输出寄存器
GPIOx->BSRR:端口位设置/清除寄存器
GPIOx->BRR :端口位清除寄存器
GPIOx->LCKR:端口配置锁存寄存器
其中主要寄存器: 输出数据寄存器(GPIOx_ODR) ;输入数据寄存器(GPIOx_IDR); 置位和复位寄存器(GPIOx_BSRR); GPIOx_MODER 寄存器用于选择I/O 方向(输入、输出、AF、模拟); GPIOx_OTYPER 和GPIOx_OSPEEDR 寄存器分别用于选择输出类型(推挽或开漏)和速度
外设复用功能
对于ADC 和DAC,在GPIOx_MODER 寄存器中将所需I/O 配置为模拟通道
对于其它外设:
— 在GPIOx_MODER 寄存器中将所需I/O 配置为复用功能
置位复位寄存器(GPIOx_BSRR) 是一个32 位寄存器,它允许应用程序在输出数据寄存器(GPIOx_ODR) 中对各个单独的数据位执行置位和复位操作
输入配置
对I/O 端口进行编程作为输入时:
● 输出缓冲器被关闭
● 施密特触发器输入被打开
● 根据GPIOx_PUPDR 寄存器中的值决定是否打开上拉和下拉电阻
● 输入数据寄存器每隔1 个AHB1 时钟周期对I/O 引脚上的数据进行一次采样
● 对输入数据寄存器的读访问可获取I/O 状态
输出配置
对I/O 端口进行编程作为输出时:
● 输出缓冲器被打开:
— 开漏模式:,输出寄存器中的“0”可激活N-MOS而输出寄存器中的“1”会使端
口保持高组态(Hi-Z)(P-MOS 始终不激活)。
— 推挽模式:输出寄存器中的“0”可激活N-MOS,而输出寄存器中的“1”可激活
P-MOS。
● 施密特触发器输入被打开
● 根据GPIOx_PUPDR 寄存器中的值决定是否打开弱上拉电阻和下拉电阻
● 输入数据寄存器每隔1 个AHB1 时钟周期对I/O 引脚上的数据进行一次采样
● 对输入数据寄存器的读访问可获取I/O 状态
● 对输出数据寄存器的读访问可获取最后的写入值
复用功能配置
对I/O 端口进行编程作为复用功能时:
● 可将输出缓冲器配置为开漏或推挽
● 输出缓冲器由来自外设的信号驱动(发送器使能和数据)
● 施密特触发器输入被打开
● 根据GPIOx_PUPDR 寄存器中的值决定是否打开弱上拉电阻和下拉电阻
● 输入数据寄存器每隔1 个AHB1 时钟周期对I/O 引脚上的数据进行一次采样
● 对输入数据寄存器的读访问可获取I/O 状态
模拟配置
对I/O 端口进行编程作为模拟配置时:
● 输出缓冲器被禁止。
● 施密特触发器输入停用,I/O 引脚的每个模拟输入的功耗变为零。施密特触发器的输出被
强制处理为恒定值(0)。
● 弱上拉和下拉电阻被关闭。
● 对输入数据寄存器的读访问值为“0”。
这些位通过软件写入,用于配置I/O 输出速度。
00:2 MHz(低速)
01:25 MHz(中速)
10:50 MHz(快速)
11:30 pF 时为100 MHz(高速)(15 pF 时为80 MHz 输出(最大速度))
结构体
DMA 简介
直接存储器访问(DMA) 用于在外设与存储器之间以及存储器与存储器之间提供高速数据传输。可以在无需任何CPU 操作的情况下通过DMA 快速移动数据。这样节省的CPU 资源可供其它操作使用。DMA 控制器基于复杂的总线矩阵架构,将功能强大的双AHB 主总线架构与独立的FIFO 结合在一起,优化了系统带宽。两个DMA 控制器总共有16 个数据流(每个控制器8 个),每一个DMA 控制器都用于管理一个或多个外设的存储器访问请求。每个数据流总共可以有多达8 个通道(或称请求)。每个通道都有一个仲裁器,用于处理DMA 请求间的优先级
DMA 主要特性
DMA 主要特性是:
● 双AHB 主总线架构,一个用于存储器访问,另一个用于外设访问
● 仅支持32 位访问的AHB 从编程接口
● 每个DMA 控制器有8 个数据流,每个数据流有多达8 个通道(或称请求)
● 每个数据流有单独的4级32 位先进先出存储器缓冲区(FIFO),可用于FIFO 模式或直接模式:
FIFO 模式:可通过软件将阈值级别选取为FIFO 大小的1/4、1/2 或3/4
— 直接模式
每个DMA 请求会立即启动对存储器的传输。当在直接模式(禁止FIFO)下将DMA请求配置为以存储器到外设模式传输数据时,DMA 仅会将一个数据从存储器预加载到内部FIFO,从而确保一旦外设触发DMA 请求时则立即传输数据.
● DMA 数据流请求之间的优先级可用软件编程(4 个级别:非常高、高、中、低),在软件优先级相同的情况下可以通过硬件决定优先级(例如,请求0 的优先级高于请求1)
● 每个数据流也支持通过软件触发存储器到存储器的传输(仅限DMA2 控制器)
● 要传输的数据项的数目可以由DMA 控制器或外设管理
— DMA 流控制器:要传输的数据项的数目是1 到65535,可用软件编程
— 外设流控制器:要传输的数据项的数目未知并由源或目标外设控制,这些外设通过硬件发出传输结束的信号
● 独立的源和目标传输宽度(字节、半字、字):源和目标的数据宽度不相等时,DMA 自动封装/解封必要的传输数据来优化带宽。这个特性仅在FIFO 模式下可用
DMA 控制器(DMA) RM0090
● 对源和目标的增量或非增量寻址
● 支持4 个、8 个和16 个节拍的增量突发传输。突发增量的大小可由软件配置,通常等于外设FIFO 大小的一半
● 5 个事件标志(DMA 半传输、DMA 传输完成、DMA 传输错误、DMA FIFO 错误、直接模式错误),进行逻辑或运算,从而产生每个数据流的单个中断请求
DMA 功能说明
DMA 控制器提供两个AHB 主端口:AHB 存储器端口(用于连接存储器)和AHB 外设端口(用于连接外设)。但是,要执行存储器到存储器的传输,AHB 外设端口必须也能访问存储器
仲裁器
一个DMA 控制器对应8 个数据流,数据流包含要传输数据的源地址、目标地址、数据等等信息。如果我们需要同时使用同一个DMA 控制器(DMA1 或DMA2)多个外设请求时,那必然需要同时使用多个数据流,那究竟哪一个数据流具有优先传输的权利呢?这就需要仲裁器来管理判断了。仲裁器管理数据流方法分为两个阶段。第一阶段属于软件阶段,我们在配置数据流时
可以通过寄存器设定它的优先级别,具体配置DMA_SxCR 寄存器PL[1:0]位,可以设置为非常高、高、中和低四个级别。第二阶段属于硬件阶段,如果两个或以上数据流软件设置优先级一样,则他们优先级取决于数据流编号,编号越低越具有优先权,比如数据流2 优先级高于数据流3。
传输类型
DMA 传输类型有单次(Single)传输和突发(Burst)传输。突发传输就是用非常短时间结合非常高数据信号率传输数据,相对正常传输速度,突发传输就是在传输阶段把速度瞬间提高,实现高速传输,在数据传输完成后恢复正常速度,有点类似达到数据块“秒传”效果。为达到这个效果突发传输过程要占用AHB 总线,保证要求每个数据项在传输过程不被分割,这样一次性把数据全部传输完才释放AHB 总线;而单次传输时必须通过AHB 的总线仲裁多次控制才传输完成
流配置过程
配置DMA 数据流x(其中x 是数据流编号)时应遵守下面的顺序:
1.如果使能了数据流,通过重置DMA_SxCR 寄存器中的EN 位将其禁止,然后读取此位以确认没有正在进行的数据流操作。将此位写为0 不会立即生效,因为实际上只有所有当前传输都已完成时才会将其写为0。当所读取EN 位的值为0 时,才表示可以配置数据流。因此在开始任何数据流配置之前,需要等待EN 位置0。应将先前的数据块DMA 传输中在状态寄存器(DMA_LISR 和DMA_HISR)中置1 的所有数据流专用的位置0,然后才可重新使能数据流。
2. 在DMA_SxPAR 寄存器中设置外设端口寄存器地址。外设事件发生后,数据会从此地址移动到外设端口或从外设端口移动到此地址。
3. 在DMA_SxMA0R 寄存器(在双缓冲区模式的情况下还有DMA_SxMA1R 寄存器)中设置存储器地址。外设事件发生后,将从此存储器读取数据或将数据写入此存储器。
4. 在DMA_SxNDTR 寄存器中配置要传输的数据项的总数。每出现一次外设事件或每出现一个节拍的突发传输,该值都会递减。
5. 使用DMA_SxCR 寄存器中的CHSEL[2:0] 选择DMA 通道(请求)。
6. 如果外设用作流控制器而且支持此功能,请将DMA_SxCR 寄存器中的PFCTRL 位置1。
7. 使用DMA_SxCR 寄存器中的PL[1:0] 位配置数据流优先级。
8. 配置FIFO 的使用情况(使能或禁止,发送和接收阈值)。232
9. 配置数据传输方向、外设和存储器增量/ 固定模式、单独或突发事务、外设和存储器数据宽度、循环模式、双缓冲区模式和传输完成一半和/ 或全部完成,和/或DMA_SxCR寄存器中错误的中断。
10. 通过将DMA_SxCR 寄存器中的EN 位置1 激活数据流。
一旦使能了流,即可响应连接到数据流的外设发出的任何DMA 请求。
一旦在AHB 目标端口上传输了一半数据,传输一半标志(HTIF) 便会置1,如果传输一半中断使能位(HTIE) 置1,还会生成中断。传输结束时,传输完成标志(TCIF) 便会置1,如果传输完成中断使能位(TCIE) 置1,还会生成中断。
DMA_ InitTypeDef 初始化结构体
5) DMA_Channel:DMA 请求通道选择,可选通道0 至通道7,每个外设对应固定的
通道,具体设置值需要查表它设定DMA_SxCR 寄存器的
CHSEL[2:0]位的值。例如,我们使用模拟数字转换器ADC3 规则采集4 个输入通
道的电压数据,查表可知使用通道2。
6) DMA_PeripheralBaseAddr:外设地址,设定DMA_SxPAR 寄存器的值;一般设置
为外设的数据寄存器地址,如果是存储器到存储器模式则设置为其中一个存储区
地址。ADC3 的数据寄存器ADC_DR 地址为((uint32_t)ADC3+0x4C)。
7) DMA_Memory0BaseAddr:存储器0 地址,设定DMA_SxM0AR 寄存器值;一般
设置为我们自定义存储区的首地址。我们程序先自定义一个16 位无符号整形数组
ADC_ConvertedValue[4]用来存放每个通道的ADC 值,所以把数组首地址(直接使
用数组名即可)赋值给DMA_Memory0BaseAddr。
8) DMA_DIR:传输方向选择,可选外设到存储器、存储器到外设以及存储器到存
储器。它设定DMA_SxCR 寄存器的DIR[1:0]位的值。ADC 采集显然使用外设到
存储器模式。
9) DMA_BufferSize:设定待传输数据数目,初始化设定DMA_SxNDTR 寄存器的值。
这里ADC 是采集4 个通道数据,所以待传输数目也就是4。
10) DMA_PeripheralInc:如果配置为DMA_PeripheralInc_Enable,使能外设地址自动
递增功能,它设定DMA_SxCR 寄存器的PINC 位的值;一般外设都是只有一个数
据寄存器,所以一般不会使能该位。ADC3 的数据寄存器地址是固定并且只有一
个所以不使能外设地址递增。
11) DMA_MemoryInc:如果配置为DMA_MemoryInc_Enable,使能存储器地址自动
递增功能,它设定DMA_SxCR 寄存器的MINC 位的值;我们自定义的存储区一
般都是存放多个数据的,所以使能存储器地址自动递增功能。我们之前已经定义
了一个包含4 个元素的数字用来存放数据,使能存储区地址递增功能,自动把每
个通道数据存放到对应数组元素内。
12) DMA_PeripheralDataSize:外设数据宽度,可选字节(8 位)、半字(16 位)和字(32
位),它设定DMA_SxCR 寄存器的PSIZE[1:0]位的值。ADC 数据寄存器只有低16
位数据有效,使用半字数据宽度。
13) DMA_MemoryDataSize:存储器数据宽度,可选字节(8 位)、半字(16 位)和字(32
位),它设定DMA_SxCR 寄存器的MSIZE[1:0]位的值。保存ADC 转换数据也要
使用半字数据宽度,这跟我们定义的数组是相对应的。
14) DMA_Mode :DMA 传输模式选择,可选一次传输或者循环传输,它设定
DMA_SxCR 寄存器的CIRC 位的值。我们希望ADC 采集是持续循环进行的,所
以使用循环传输模式。
15) DMA_Priority:软件设置数据流的优先级,有4 个可选优先级分别为非常高、高、
中和低,它设定DMA_SxCR 寄存器的PL[1:0]位的值。DMA 优先级只有在多个
DMA 数据流同时使用时才有意义,这里我们设置为非常高优先级就可以了。
16) DMA_FIFOMode:FIFO 模式使能,如果设置为DMA_FIFOMode_Enable 表示使
能FIFO 模式功能;它设定DMA_SxFCR 寄存器的DMDIS 位。ADC 采集传输使
用直接传输模式即可,不需要使用FIFO 模式。
17) DMA_FIFOThreshold:FIFO 阈值选择,可选4 种状态分别为FIFO 容量的1/4、
1/2、3/4 和满;它设定DMA_SxFCR 寄存器的FTH[1:0]位;DMA_FIFOMode 设
置为DMA_FIFOMode_Disable,那DMA_FIFOThreshold 值无效。ADC 采集传输
不使用FIFO 模式,设置改值无效。
18) DMA_MemoryBurst:存储器突发模式选择,可选单次模式、4 节拍的增量突发模
式、8 节拍的增量突发模式或16 节拍的增量突发模式,它设定DMA_SxCR 寄存
器的MBURST[1:0]位的值。ADC 采集传输是直接模式,要求使用单次模式。
19) DMA_PeripheralBurst:外设突发模式选择,可选单次模式、4 节拍的增量突发模
式、8 节拍的增量突发模式或16 节拍的增量突发模式,它设定DMA_SxCR 寄存
器的PBURST[1:0]位的值。ADC 采集传输是直接模式,要求使用单次模式。
中断和事件
参与了CPU就是外部中断 CPU没有参与就是事件
中断编程
在配置每个中断的时候一般有3 个编程要点:
1、使能外设某个中断,这个具体由每个外设的相关中断使能位控制。比如串口有发送
完成中断,接收完成中断,这两个中断都由串口控制寄存器的相关中断使能位控制。
2、初始化NVIC_InitTypeDef 结构体,配置中断优先级分组,设置抢占优先级和子优先级,使能中断请求
嵌套向量中断控制器(NVIC)
嵌套向量中断控制器NVIC 配置
代码清单17-3 NVIC 配置
外部中断/事件控制器(EXTI)
EXTI 初始化结构体
1) EXTI_Line:EXTI 中断/事件线选择,可选EXTI0 至EXTI22,可参考表17-1 选择。
2) EXTI_Mode:EXTI 模式选择,可选为产生中断(EXTI_Mode_Interrupt)或者产生事
件(EXTI_Mode_Event)。
3) EXTI_Trigger:EXTI 边沿触发事件,可选上升沿触发(EXTI_Trigger_Rising)、下
降沿触发( EXTI_Trigger_Falling) 或者上升沿和下降沿都触发
( EXTI_Trigger_Rising_Falling)。
4) EXTI_LineCmd:控制是否使能EXTI 线,可选使能EXTI 线(ENABLE)或禁用
(DISABLE)。
唤醒事件管理
STM32F4xx 能够处理外部或内部事件来唤醒内核(WFE)。唤醒事件可通过以下方式产生:
● 在外设的控制寄存器使能一个中断,但不在NVIC 中使能,同时使能Cortex™-M4F 系统控制寄存器中的SEVONPEND 位。当MCU 从WFE 恢复时,需要清除相应外设的中断挂起位和外设NVIC 中断通道挂起位(在NVIC 中断清除挂起寄存器中)。
● 配置一个外部或内部EXTI 线为事件模式。当CPU 从WFE 恢复时,因为对应事件线的挂起位没有被置位,不必清除相应外设的中断挂起位或NVIC 中断通道挂起位。
模数转换器(ADC)
ADC 简介
12 位ADC 是逐次趋近型模数转换器。它具有多达19 个复用通道,可测量来自16 个外部源、两个内部源和VBAT通道的信号。这些通道的A/D 转换可在单次、连续、扫描或不连续采样模式下进行。ADC 的结果存储在一个左对齐或右对齐的16 位数据寄存器中。ADC 具有模拟看门狗特性,允许应用检测输入电压是否超过了用户自定义的阈值上限或下限
ADC 主要特性
● 可配置12 位、10 位、8 位或6 位分辨率
● 在转换结束、注入转换结束以及发生模拟看门狗或溢出事件时产生中断
● 单次和连续转换模式
● 用于自动将通道0 转换为通道“n”的扫描模式
● 数据对齐以保持内置数据一致性
● 可独立设置各通道采样时间
● 外部触发器选项,可为规则转换和注入转换配置极性
● 规则通道转换期间可产生DMA 请求
输入通道
外部的16 个通道在转换的时候又分为规则通道和注入通道,其中规则通道最多有16路,注入通道最多有4 路。那这两个通道有什么区别?在什么时候使用?
规则通道
规则通道:顾名思意,规则通道就是很规矩的意思,我们平时一般使用的就是这个通道,或者应该说我们用到的都是这个通道,没有什么特别要注意的可讲。
注入通道
注入,可以理解为插入,插队的意思,是一种不安分的通道。它是一种在规则通道转换的时候强行插入要转换的一种。如果在规则通道转换过程中,有注入通道插队,那么就要先转换完注入通道,等注入通道转换完成后,再回到规则通道的转换流程。这点跟中断程序很像,都是不安分的主。所以,注入通道只有在规则通道存在时才会出现。
ADC_InitTypeDef 结构体
ADC_InitTypeDef 结构体定义在stm32f4xx_adc.h 文件内,具体定义如下:
ADC_Resolution:配置ADC 的分辨率,可选的分辨率有12 位、10 位、8 位和6 位。分辨率越高,AD 转换数据精度越高,转换时间也越长;分辨率越低,AD 转换数据精度越低,转换时间也越短。
ScanConvMode:可选参数为ENABLE 和DISABLE,配置是否使用扫描。如果是单通道AD 转换使用DISABLE,如果是多通道AD 转换使用ENABLE。
ADC_ContinuousConvMode:可选参数为ENABLE 和DISABLE,配置是启动自动连续转换还是单次转换。使用ENABLE 配置为使能自动连续转换;使用DISABLE 配置为单次转换,转换一次后停止需要手动控制才重新启动转换。
ADC_ExternalTrigConvEdge:外部触发极性选择,如果使用外部触发,可以选择触发的极性,可选有禁止触发检测、上升沿触发检测、下降沿触发检测以及上升沿和下降沿均可触发检测。
ADC_ExternalTrigConv:外部触发选择,可根据项目需求配置触发来源。实际上,我们一般使用软件自动触发。
ADC_DataAlign:转换结果数据对齐模式,可选右对齐ADC_DataAlign_Right 或者左对齐ADC_DataAlign_Left。一般我们选择右对齐模式。
ADC_NbrOfChannel:AD 转换通道数目。
编程要点
1) 初始化配置ADC 目标引脚为模拟输入模式;
2) 使能ADC 时钟;
3) 配置通用ADC 为独立模式,采样4 分频;
4) 设置目标ADC 为12 位分辨率,1 通道的连续转换,不需要外部触发;
5) 设置ADC 转换通道顺序及采样时间;
6) 配置使能ADC 转换完成中断,在中断内读取转换完数据;
7) 启动ADC 转换;
8) 使能软件触发ADC 转换。
ADC 转换结果数据使用中断方式读取,这里没有使用DMA 进行数据传输
SysTick—系统定时器
SysTick 寄存器介绍
SysTick—系统定时有4 个寄存器,简要介绍如下。在使用SysTick 产生定时的时候,
只需要配置前三个寄存器,最后一个校准寄存器不需要使用。
寄存器名称寄存器描述
CTRL SysTick 控制及状态寄存器
LOAD SysTick 重装载数值寄存器
VAL SysTick 当前数值寄存器
TIM6&7—基本定时器
STM32F42xxx 系列控制器有2 个高级控制定时器(1.8)、10 个通用定时器和2 个基本定时器,(6.7)
还有2 个看门狗定时器
流程过程
基本上定时器TIM6 和TIM7 是一个16 位向上递增的定时器,当我在自动重载寄存器(TIMx_ARR)添加一个计数值后并使能TIMx,计数寄存器(TIMx_CNT)就会从0 开始递增,当TIMx_CNT 的数值与TIMx_ARR 值相同时就会生成事件并把TIMx_CNT 寄存器清0,完成一次循环过程。如果没有停止定时器就循环执行上述过程。
时钟源
定时器要实现计数必须有个时钟源,基本定时器时钟只能来自内部时钟,高级控制定时器和通用定时器还可以选择外部时钟源或者直接来自其他定时器等待模式
寄存器
基本定时器计数过程主要涉及到三个寄存器内容,分别是计数器寄存器(TIMx_CNT)、预分频器寄存器(TIMx_PSC)、自动重载寄存器(TIMx_ARR),这三个寄存器都是16 位有效数字,即可设置值为0 至65535。
上溢说明
在TIMx_CNT 递增至与TIMx_ARR 值相等,我们叫做为定时器上溢。
影子寄存器
TIMx_ARR 有影子寄存器,可以通过TIMx_CR1 寄存器的ARPE 位控制影子寄存器功能,如果ARPE 位置1,影子寄存器有效,只有在事件更新时才把TIMx_ARR 值赋给影子寄存器。如果ARPE 位为0,修改TIMx_ARR 值马上有效
定时器周期计算
经过上面分析,我们知道定时事件生成时间主要由TIMx_PSC 和TIMx_ARR 两个寄存器值决定,这个也就是定时器的周期。比如我们需要一个1s 周期的定时器,具体这两个寄存器值该如何设置内。假设,我们先设置TIMx_ARR 寄存器值为9999,即当TIMx_CNT从0 开始计算,刚好等于9999 时生成事件,总共计数10000 次,那么如果此时时钟源周期为100us 即可得到刚好1s 的定时周期。
接下来问题就是设置TIMx_PSC 寄存器值使得CK_CNT 输出为100us 周期(10000Hz)的时钟。预分频器的输入时钟CK_PSC 为90MHz,所以设置预分频器值为(9000-1)即可满足 就是90 000 000 HZ 10000次有4个0 还差 3个0 所以 9000 -1
定时器基本初始化结构体
1 typedef struct {
2 uint16_t TIM_Prescaler; // 预分频器
3 uint16_t TIM_CounterMode; // 计数模式
4 uint32_t TIM_Period; // 定时器周期
5 uint16_t TIM_ClockDivision; // 时钟分频
6 uint8_t TIM_RepetitionCounter; // 重复计算器
7 } TIM_TimeBaseInitTypeDef;
(1) TIM_Prescaler:定时器预分频器设置,时钟源经该预分频器才是定时器时钟,它设定
TIMx_PSC 寄存器的值。可设置范围为0 至65535,实现1 至65536 分频。
(2) TIM_CounterMode:定时器计数方式,可是在为向上计数、向下计数以及三种中心对
齐模式。基本定时器只能是向上计数,即TIMx_CNT 只能从0 开始递增,并且无需初
始化。
(3) TIM_Period:定时器周期,实际就是设定自动重载寄存器的值,在事件生成时更新到
影子寄存器。可设置范围为0 至65535。
(4) TIM_ClockDivision:时钟分频,设置定时器时钟CK_INT 频率与数字滤波器采样时钟
频率分频比,基本定时器没有此功能,不用设置。
(5) TIM_RepetitionCounter:重复计数器,属于高级控制寄存器专用寄存器位,利用它可
以非常容易控制输出PWM 的个数。这里不用设置。
TIM1&8—高级定时器
介绍
高级控制定时器时基单元包含一个16 位自动重载计数器ARR,一个16 位的计数器CNT,可向上/下计数,一个16 位可编程预分频器PSC,预分频器时钟源有多种可选,有内部的时钟、外部时钟。还有一个8 位的重复计数器RCR,这样最高可实现40 位的可编程定时
时钟源
高级控制定时器有四个时钟源可选:
内部时钟源CK_INT
外部时钟模式1:外部输入引脚TIx(x=1,2,3,4)
外部时钟模式2:外部触发输入ETR
内部触发输入
寄存器
高级控制定时器时基单元包括四个寄存器,分别是计数器寄存器(CNT)、预分频器寄存(PSC)、自动重载寄存器(ARR)和重复计数器寄存器(RCR)。其中重复计数器RCR 是高级定时器独有,通用和基本定时器没有。前面三个寄存器都是16 位有效,TIMx_RCR 寄存器是8 位有效。
重复计数器RCR
在基本/通用定时器发生上/下溢事件时直接就生成更新事件,但对于高级控制定时器却不是这样,高级控制定时器在硬件结构上多出了重复计数器,在定时器发生上溢或下溢事件是递减重复计数器的值,只有当重复计数器为0 时才会生成更新事件。在发生N+1 个上溢或下溢事件(N 为RCR 的值)时产生更新事件。
重点掌握增加功能
输入捕获和输出比较功能
输入捕获的大概的原理
就是,当捕获到信号的跳变沿的时候,把计数器CNT 的值锁存到捕获寄存器CCR 中,把前后两次捕获到的CCR 寄存器中的值相减,就可以算出脉宽或者频率。如果捕获的脉宽的时间长度超过你的捕获定时器的周期,就会发生溢出,这个我们需要做额外的处理。
PWM 输入模式。
PWM 信号由输入通道TI1 进入,因为是PWM 输入模式的缘故,信号会被分为两路,一路是TI1FP1,另外一路是TI2FP2。其中一路是周期,另一路是占空比,具体哪一路信号对应周期还是占空比,得从程序上设置哪一路信号作为触发输入,作为触发输入的哪一路信号对应的就是周期,另一路就是对应占空比。作为触发输入的那一路信号还需要设置极性,是上升沿还是下降沿捕获
图 PWM 输入模式时序
PWM 信号由输入通道TI1 进入,配置TI1FP1 为触发信号,上升沿捕获。当上升沿的时候IC1 和IC2 同时捕获,计数器CNT 清零,到了下降沿的时候,IC2 捕获,此时计数器CNT 的值被锁存到捕获寄存器CCR2 中,到了下一个上升沿的时候,IC1 捕获,计数器CNT 的值被锁存到捕获寄存器CCR1 中。其中CCR2 测量的是脉宽,CCR1 测量的是周期。从软件上来说,用PWM 输入模式测量脉宽和周期更容易,付出的代价是需要占用两个捕获寄存器
PWM 输出模式
PWM 输出就是对外输出脉宽(即占空比)可调的方波信号,信号频率由自动重装寄存器ARR 的值决定,占空比由比较寄存器CCR 的值决定。
USART—串口通讯
功能引脚
TX:发送数据输出引脚。
RX:接收数据输入引脚。
数据寄存器
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 数据。
控制器
USART 有专门控制发送的发送器、控制接收的接收器,还有唤醒单元、中断控制等等。
使用USART 之前需要向USART_CR1 寄存器的UE 位置1 使能USART。发送或者接收数
据字长可选8 位或9 位,由USART_CR1 的M 位控制。
在发送数据时,编程的时候有几个比较重要的标志位我们来总结下。
在接收数据时,编程的时候有几个比较重要的标志位我们来总结下
USART 初始化结构体
uC/OS II
1. 一个完整的任务应该有如下三部分:
• 任务代码(程序)
• 任务的私有堆栈(用以保护运行环境)
•任务控制块(提供私有堆栈也是虚拟处理器的位置
任务就绪表
OSRdyGrp=00001011,那么就意味着OSRdyTbl[0]、OSRdyTbl[1]、OSRdyTbl[3]中有就绪的任务
举例:某任务的优先级prio=24,问该任务落在就绪表中的哪一位?
24的二进制位为00011000,D5、D4、D3位011,即OSRdyTbl[]的下标为3,D2、D1、D0为0,即优先级prio=24的任务在OSRdyTbl[3]的第0位
获取最高优先级任务
INT8U y;
y = OSUnMapTbl[OSRdyGrp]; //最高优先级所在的任务组
OSPrioHighRdy = (INT8U)((y << 3)+OSUnMapTbl[OSRdyTbl[y]]); //最高优先级任务所在的任务组的位
任务切换步骤:
1. 获得待运行就绪任务控制块的指针;调度器实施任务切换之前的主要工作时:获得待运行任务的TCB指针和当前任务的TCB指针
2. 对任务级调度器OSSched()的解释
综上所述
任务的切换就是断点数据的切换,断点数据的切换也就是CPU堆栈指针的切换,被中止运行任务的任务堆栈指针要保存到该任务的任务控制块中。待运行任务的任务堆栈指针要由该任务控制块转存到CPU的SP中
Void OSCtxSw(void)//任务切换函数
{
将R1,R2,R3及R4推入当前堆栈
//正在运行的任务块指针-》任务块指针
OSTCBCur->OSTCBStkPtr = SP;//把SP保存在中止任务控制块中 当前任务的任务控制块指针用来保存SP
OSTCBCur = OSTCBHighRdy;//系统获得待运行控制块
SP=OSTCBHighRdy->OSTCBStkPtr;
//待运行任务堆栈指针给SP
将R4,R3,R2及R1从新堆栈中弹出
执行中断返回指令
}
I^2C
I^2C总线是PHILIPS公司推出的设备内部串行总线,它由一根数据线SDA和一根时钟线SCL组成,SDA和SCL都为双向I/O线,通过上拉电阻Rp接+5v电源,总线空闲是皆为高电平
总共有五种工作状态:
A:总线非忙状态
该状态时数据线(SDA)和时钟线(SCL)都保持高电平。
B:启动状态
当时钟线(SCL)为高电平状态时,数据线(SDA)由高电平变为低电平的下降沿被认为是"启动"信号。
C:停止状态
当时钟线(SCL)为高电平状态时,数据线(SDA)由低电平变为高电平的下降沿被认为是"停止"信号。
D:数据有效状态
在出现"启动"信号后,在时钟线(SCL)为高电平状态时,数据线是稳定的,这时数据线的状态就是要传送的数据。数据线(SDA)上数据的改变必须在时钟线为低电平期间完成的,每位数据占有一个时钟脉冲。
E:应答信号(Ack),EEPROM在接收或发送一个字节的数据时,通常要发出或接收一个应答信号(Ack)。
I^2C总线协议有明确的规定:采用7位的寻址字节(寻址字节是起始信号后的第一个字节)。
D7~D1位组成从机的地址。D0位是数据传送方向位,为“0”时表示主机向从机写数据,为“1”时表示主机由从机读数据。
从机的7位寻址位有4位是固定位,3位是可编程位,这时仅能寻址8个同样的器件,即可以有8个同样的器件接入到该I^2C总线系统中
先发数据
SPI
全双工;
SPI接口一般使用4条线通信:
MISO主设备数据输入,从设备数据输出;
MOSI主设备数据输出,从设备数据输入;
SCLK:时钟信号,由主设备产生
CS:从设备片选信号,由主设备控制
注意:外设的写操作和读操作是同步完成的;如果只进行写操作,主机只须忽略接受到的字节;反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输
4种工作方式:
根据外设工作要求,其输出串行同步时钟极性和相位可以配置:
1. CPOL时钟极性 = 0 串行同步时钟的空闲状态为低电平;CPHA = 0 在串行同步时钟的第一个跳变沿数据被采样;
2. CPOL时钟极性 = 0 串行同步时钟的空闲状态为低电平;CPHA = 1 在串行同步时钟的第二个跳变沿数据被采样;
3. CPOL时钟极性 = 1 串行同步时钟的空闲状态为高电平;CPHA = 0 在串行同步时钟的第一个跳变沿数据被采样;(常用方式)
4. CPOL时钟极性 = 0 串行同步时钟的空闲状态为高电平;CPHA = 1 在串行同步时钟的第二个跳变沿数据被采样;
更多:
中断向量表首先中断向量表定义的是什么?定义的就是中断服务程序的跳转指令,因为每个中断向量在向量表中只有一个字节的存储空间,只能存放一条指令,所以通常存放跳转指令,使程序跳转到存储器的其他地方,再执行中断处理。
举例中断服务函数名字:
TIM6_DAC_IRQHandler
TIM7_IRQHandler
DMA2_Stream4_IRQHander
启动过程
(1)设置堆栈
(2)初始化PC指针
(3)设置向量表
(4)跳转到main函数
STM32的启动模式由芯片的启动引脚BOOT0和BOOT1决定:MCU在上电时会读取BOOT0和BOOT1引脚的电平状态并锁存,系统根据电平状态来从选择启动方式
复位和时钟控制(RCC)
复位
共有三种类型的复位,分别为系统复位、电源复位和备份域复位。
GPIO复用功能采用GPIO_PinAFConfig函数,此函数有3个参数:1.2确定那个引脚(I/O),第三个是复用为何种功能,在stm32f4xx_gpio.h中有列出来。