当前位置:文档之家› STM32学习笔记_STM32F103ZET6

STM32学习笔记_STM32F103ZET6

STM32学习笔记_STM32F103ZET6
STM32学习笔记_STM32F103ZET6

STM32F103 系列芯片的系统架构:

系统结构:

在每一次复位以后,所有除SRAM 和FLITF 以外的外设都被关闭,在使用一个外设之前,必须设置寄存器RCC_AHBENR 来打开该外设的时钟。

GPIO 输入输出,外部中断,定时器,串口。理解了这四个外设,基本就入门了一款MCU。

时钟控制RCC:

-4~16M 的外部高速晶振

-内部8MHz 的高速RC 振荡器

-内部40KHz低速RC 振荡器,看门狗时钟

-内部锁相环(PLL,倍频),一般系统时钟都是外部或者内部高速时钟经过PLL 倍频后得到

- 外部低速32.768K 的晶振,主要做RTC 时钟源

ARM存储器映像:

数据字节以小端格式存放在存储器中。一个字里的最低地址字节被认为是该字的最低有效字节,而最高地址字节是最高有效字节。

存储器映像与寄存器映射:

ARM 存储器映像

4GB

0X0000 00000X1FFF FFFF

0X2000 00000X3FFF FFFF

0X4000 00000X5FFF FFFF

寄存器说明:

寄存器名称

相对外设基地址的偏移值

编号

位表

读写权限

寄存器位

功能说明

使用C语言封装寄存器:

1、总线和外设基地址封装利用地址偏移

(1)定义外设基地址(Block2 首地址)

(2)定义APB2总线基地址(相对外设基地址偏移固定)

(3)定义GPIOX外设基地址(相对APB2总线基地址偏移固定)(4)定义GPIOX寄存器地址(相对GPIOX外设基地址偏移固定)(5)使用 C 语言指针操作寄存器进行读/写

//定义外设基地址

#define PERIPH_BASE ((unsigned int)0x40000000) 1)

//定义APB2 总线基地址

#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000) 2)

//定义GPIOC 外设基地址

#define GPIOC_BASE (AHB1PERIPH_BASE + 0x0800) 3)

//定义寄存器基地址这里以GPIOC 为例

#define GPIOC_CRL *(unsigned int*)(GPIOC_BASE+0x00) 4)

#define GPIOC_CRH *(unsigned int*)(GPIOC_BASE+0x04)

#define GPIOC_IDR *(unsigned int*)(GPIOC_BASE+0x08)

#define GPIOC_ODR *(unsigned int*)(GPIOC_BASE+0x0C)

#define GPIOC_BSRR *(unsigned int*)(GPIOC_BASE+0x10)

#define GPIOC_BRR *(unsigned int*)(GPIOC_BASE+0x14)

#define GPIOC_LCKR *(unsigned int*)(GPIOC_BASE+0x18)

//控制GPIOC 第0 管脚输出一个低电平5)

GPIOC_BSRR = (0x01<<(16+0));

//控制GPIOC 第0 管脚输出一个高电平

GPIOC_BSRR = (0x01<<0);

2、寄存器封装利用结构体、外设基地址和寄存器地址偏移

typedef unsigned int uint32_t; /*无符号32 位变量*/

typedef unsigned short int uint16_t; /*无符号16 位变量*/

/* GPIO 寄存器列表*/

typedef struct

{

uint32_t CRL; /*GPIO 端口配置低寄存器地址偏移: 0x00 */

uint32_t CRH; /*GPIO 端口配置高寄存器地址偏移: 0x04 */

uint32_t IDR; /*GPIO 数据输入寄存器地址偏移: 0x08 */

uint32_t ODR; /*GPIO 数据输出寄存器地址偏移: 0x0C */

uint32_t BSRR; /*GPIO 位设置/清除寄存器地址偏移: 0x10 */

uint32_t BRR; /*GPIO 端口位清除寄存器地址偏移: 0x14 */

uint16_t LCKR; /*GPIO 端口配置锁定寄存器地址偏移: 0x18 */

}GPIO_TypeDef;

只要给结构体设置好首地址,就能把结构体内成员的地址确定下来,然后就能以结构体的形式访问寄存器。

举例:将GPIOC0 输出低电平,具体代码如下:

GPIO_TypeDef * GPIOx; //定义一个GPIO_TypeDef 型结构体指针GPIOx GPIOx = GPIOC_BASE; //把指针地址设置为宏GPIOC_BASE 地址

GPIOx->BSRR =(1<<(16+0)); //通过指针访问并修改GPIOC_BSRR 寄存器

为了操作更简便灵活,直接使用宏定义好GPIO_TypeDef 类型的指针,而且指针指向各个GPIO 端口的首地址,那么即可直接用该宏访问寄存器。具体代码如下:

#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)

#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)

#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)

#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE)

#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE)

#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE)

#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE)

GPIOC->BSRR = (1<<(16+0));

后面实验程序的编写,都是使用ST 公司提供的固件库,已经把STM32 所有外设封装好,只需要调用即可。

GPIO:

GPIO引脚具有推挽和开漏两种输出模式,配置引脚输出模式使用GPIOx_CRL 和GPIOx_CRH寄存器。

推挽:输出高电平或低电平,一般选择此模式。

开漏:输出低电平或高阻态,

若输出高电平,应外加上拉电阻,实现电平匹配;

引脚具有线与关系,应用在I2C等总线通讯电路。

GPIO 工作模式

通过GPIO 内部的结构关系,决定了GPIO 可以配置成以下几种模式。

(1)输入模式(模拟、上拉、下拉、浮空)

在输入模式时,施密特触发器打开,输出被禁止。可通过输入数据寄存器GPIOx_IDR 读取I/O 状态。输入模式可以配置为模拟、上拉、下拉以及浮空模式。上拉和下拉输入很好理解,默认的电平由上拉或者下拉决定。浮空输入的电平是不确定的,完全由外部的输入决定,一般接按键的时候可以使用这个模式。模拟输入则用于ADC 采集。

(2)输出模式(推挽/开漏)

在输出模式中,推挽模式时双MOS 管以推挽方式工作,输出数据寄存器GPIOx_ODR 可控制I/O 输出高低电平。开漏模式时,只有N-MOS 管工作,输出数据寄存器可控制I/O 输出高阻态或低电平。输出速度可配置,有2MHz\25MHz\50MHz 的选项。此处的输出速度即I/O 支持的高低电平状态最高切换频率,支持的频率越高,功耗越大,如果功耗要求不严格,把速度设置成最大即可。在输出模式时,施密特触发器是打开的,即输入可用,通过输入数据寄存器GPIOx_IDR 可读取I/O 的实际状态。

(3)复用功能(推挽/开漏)

复用功能模式中,输出使能,输出速度可配置,可工作在开漏及推挽模式,但是输出信号源于其它外设,输出数据寄存器GPIOx_ODR 无效;输入可用,通过输入数据寄存器可获取I/O 实际状态,但一般直接用外设的寄存器来获取该数据信号。

(4)模拟输入输出(上下拉无影响)

模拟输入输出模式中,双MOS 管结构被关闭,施密特触发器停用,上/下拉也被禁止。其它外设通过模拟通道进行输入输出。通过对GPIO 寄存器写入不同的参数,就可以改变GPIO 的应用模式,再强调一下,要了解具体寄存器时一定要查阅《STM32F1xx 参考手册》中对应外设的寄存器说明。

在GPIO 外设中,通过设置“端口配置寄存器GPIOx_CRL 和GPIOx_CRH”可配置GPIO 的工作模式和输出速度。CRH 控制端口的高八位,CRL 控制端口的低八位。

STM32固件库:

ST 公司推出了一套固件库,内部已经将STM32 的全部外设寄存器的控制封装好,给用户提供一些API 函数,用户只需要学习如何使用这些API 函数即可。

什么是CMSIS 标准?CMSIS标准英文全称是Cortex MicroController Software Interface Standard,翻译为中文意思就是ARM Cortex 微控制器软件接口标准。

库文件之间的关系

stm32f10x.h 、system_stm32f10x.h 和system_stm32f10x.c 文件存放在“\STM32

最新固件库v3.5\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x”目录下,system_stm32f10x.h 是片上外设接入层系统头文件。主要是申明设置系统及

总线时钟相关的函数。与其对应的源文件是system_stm32f10x.c。这个文件里面有一个非常重要的SystemInit()函数申明,这个函数在我们系统启动的时候都会调用,用来设置系统的整个系统和总线时钟。

stm32f10x.h是STM32F10x的头文件,类似于51 单片机的reg.51,在开发STM32F10x 程序的时候基本上都会调用这个头文件,可见其重要性。此文件内部封装了STM32 的总线、内存和外设寄存器等,同时该文件还包含了一些时钟相关的定义和中断相关定义等。

stm32f10x_ppp.c 文件是STM32 外设的驱动源文件,比如stm32f10x_gpio.c 文件,里面已经封装好操作GPIO 外设底层的内容,提供给我们使用的是一些API函数。stm32f10x_ppp.h 就是对应的头文件。

还有stm32f10x_rcc.c、misc.c和misc.h文件他们都是存放在“\STM32 最新固件库v3.5\Libraries\STM32F10x_StdPeriph_Driver”内。

Application.c 文件用于存放用户编写的应用程序,文件名可以根据个人爱好命名。我们通常会命名为main.c,表示存放我们的主函数代码。

还要将STM32 的启动文件添加进来,否则系统不能启动。需根据使用的STM32 芯片来选择,因为开发板上使用的是高容量的STM32F1芯片,所以选择startup_stm32f10x_hd.s。启动文件startup_stm32f10x_hd.s存放在“\STM32 最新固件库v3.5\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm”内。

利用库函数模板创建工程,库函数将底层寄存器进一步封装,无需使用底层寄存器操作外设,直接利用库函数实现外设操作,例如

GPIO_SetBits(GPIOx,GPIO_Pin_n)//X:ABCDE,n:0~15

ARM存储器

程序编译结束后,从编译信息可以看出,代码占用FLASH 大小为:1228 字节(908+320),所用的SRAM 大小为:1024 个字节(1024+0)。

编译结果里面的几个数据的意义:

Program Size: Code=908 RO-data=320 RW-data=0 ZI-data=1024

Code:表示程序所占用FLASH 的大小。

RO-data:即Read Only-data,表示程序定义的常量,存储在FLASH内。

RW-data:即Read Write-data,表示已被初始化的变量,存储在SRAM内。

ZI-data:即Zero Init-data,表示未被初始化的变量,存储在SRAM内。

有了这个就可以知道你当前使用的flash 和sram 大小了,所以,一定要注意的是程序的大小不是.hex 文件的大小,而是编译后的Code 和RO-data 之和。

外设使用方法:

首先进行初始化,使能外设时钟,并配置相应的工作模式;

然后在应用外设相关的函数实现需要的功能。

时钟

在STM32 时钟系统中,有 5 个重要的时钟源,分别是LSI、LSE、HSI、HSE、PLL。按照时钟频率分可分为高速时钟源和低速时钟源,在这5 个中HSI,HSE 以及PLL 属于高速时钟,LSI 和LSE 属于低速时钟。按照时钟来源可分为外部时钟源和内部时钟源,外部时钟源就是在STM32 晶振管脚处接入外部晶振的方式获取时钟源,其中HSE 和LSE 是外部时钟源,其他的是内部时钟源。

如果我们选择HSE是PLL的时钟源,PLL 是SYSCLK 的时钟源,即SYSCLK 为72MHz,这个也是我们库函数模板中SystemInit 所配置的最终系统时钟。

SYSCLK 系统时钟是STM32 中绝大部分部件工作的时钟源。它的时钟来源可

以由HSI、HSE、PLLCLK 提供,相信大家选择STM32F1 这种高级芯片,都

希望有一个比较大的时钟频率,因此选择PLLCLK 作为系统时钟。PLLCLK又是从HSE或HSI 经过PLL 倍频得到。

APB1 和APB2 的区别,2>1,所以APB2 的速度大于APB1 的速度。

APB1 上面连接的是低速外设,包括电源接口、备份接口、CAN、USB、I2C1、I2C2、UART2、UART3 等;

APB2上面连接的是高速外设包括UART1、SPI1、Timer1、ADC1、ADC2、GPIO等。

大多数有关时钟输出部分都有一个使能控制,比如AHB 总线、APB1 外设、APB2 外设、内核时钟等。当需要使用某个时钟的时候一定要开启它的使能,否则将不工作。

时钟初始化配置函数SystemInit():

STM32系统复位后首先进入SystemInit 函数进行时钟的设置,将STM32F1系统时钟设置为72MHz (我们开发板上使用的STM32F103ZET6 最大可达到

72M (超频除外)),然后进入主函数。

在system_stm32f10x.c 文件中可以找到SystemInit()函数

调用SystemInit 函数之后,首先是选择HSI 作为系统时钟。在设置完相关寄存器后才换成HSE 作为系统时钟,接下来SystemInit 函数内部会调用SetSysClock()函数。

在system_stm32f10x.c文件的开头就有对此宏定义,系统默认的宏定义是72MHz,如下:

#define SYSCLK_FREQ_72MHz 72000000

如果你要设置为36MHz,只需要注释掉上面代码,然后加入下面代码即可:

#define SYSCLK_FREQ_36MHz 36000000

SystemInit 函数执行完,时钟大小设置如下:

SYSCLK(系统时钟)=72MHz

AHB 总线时钟(HCLK=SYSCLK) =72MHz

APB1 总线时钟(PCLK1=SYSCLK/2) =36MHz

APB2 总线时钟(PCLK2=SYSCLK/1) =72MHz

PLL 主时钟=72MHz

时钟使能配置函数:

固件库已经把时钟相关寄存器的使能配置都封装好,放在stm32f10x_rcc.c 和stm32f10x_rcc.h 中。。这些时钟函数可大致分为三类。一类是外设时钟使能函数,

一类是时钟源和倍频因子配置函数,还有一类是外设复位函数。

void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);

void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);

void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);

形参1举例:RCC_APB2Periph_GPIOC ,形参2举例:ENABLE

delay()函数是通过CPU 循环等待实现粗延时;

利用SysTick 系统定时器/通用定时器实现ms或us级的精确延时。

位带操作

STM32通过访问位带别名区来实现位操作,即将每个比特位膨胀成一个32 位字,当访问这些字的时候就达到了访问比特的目的。

STM32F1 中有两个区域支持位带操作,一个是SRAM 区的最低1MB 范围,一个是片内外设区的最低1MB范围(APB1、APB2、AHB外设)。

通常我们使用位带操作都是在外设区,在外设区中应用比较多的也就是GPIO外设,SRAM 区内很少使用位操作。

在STM32 应用程序开发中虽然可以使用库函数操作外设,但如果加上位操作就如虎添翼。

//IO 口操作,只对单一的IO 口

//确保n 的值小于16

#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出

#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入

#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出

#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入

#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出

#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入

#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出

#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入

#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出

#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入

#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出

#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入

#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出

#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入

中断

中断其实就是当CPU 执行程序时,由于发生了某种随机的事件(外部或内部),引起CPU 暂时中断正在运行的程序,转去执行一段特殊的服务程序(中断服务子程序或中断处理程序),以处理该事件,该事件处理完后又返回被中断的程序继续执行,这一过程就称为中断,引发中断的称为中断源。

Crotex-M3内核支持256个中断,其中包含了16个内核中断和240 个外部中断。STM32F103系列芯片有76 个中断通道,包括16 个内核中断和60 个可屏蔽中断,除了个别异常的优先级被定死外,其它异常的优先级都是可编程的。

中断向量表

NVIC英文全称是Nested Vectored Interrupt Controller,中文意思就是嵌套向量中断控制器,它属于M3 内核的一个外设,控制着芯片的中断相关功能。

在固件库core_cm3.h 文件内定义了一个NVIC 结构体,里面定义了相关寄存器,在配置中断时,我们通常使用的只有ISER、ICER 和IP 这三个寄存器,ISER是中断使能寄存器,ICER是中断清除寄存器,IP 是中断优先级寄存器。中断优先级

STM32F103 芯片支持60 个可屏蔽中断通道,每个中断通道都具备自己的中断优先级控制字节(8 位,理论上每个外部中断优先级可以设置为0-255,数值越小,优先级越高。但是STM32F103 中只使用 4 位,高4位有效),用于表达优先级的高 4 位又被分组成抢占式优先级和响应优先级,通常也把响应优先级称为“亚优先级”或“副优先级”,每个中断源都需要被指定这两种优先级。

高抢占式优先级的中断事件会打断当前的主程序或者中断程序运行,俗称中断嵌套。在抢占式优先级相同的情况下,高响应优先级的中断优先被响应。

当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理那一个,越靠前的先执行。

STM32F103 中指定中断优先级的寄存器位有4 位,这4 位的分组方式如图所示:

设置优先级分组可调用库函数NVIC_PriorityGroupConfig()实现,有关NVIC 中断相关的库函数都在库文件misc.c 和misc.h 中,所以当使用到中断时,一定要记得把misc.c 和misc.h 添加到工程组中。

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)

NVIC_PriorityGroupConfig 函数带一个形参用于中断优先级分组,该值范围可以是NVIC_PriorityGroup_0-NVIC_PriorityGroup_4,对应优先级与占用的位数信息如下:

中断配置

(1)使能外设某个中断,这个具体是由外设相关中断使能位来控制,比如定时器有溢出中断,这个可由定时器的控制寄存器中相应中断使能位来控制。(2)设置中断优先级分组,初始化NVIC_InitTypeDef 结构体,设置抢占优先级和响应优先级,使能中断请求。

NVIC_InitTypeDef 结构体如下

typedef struct

{

uint8_t NVIC_IRQChannel; //中断源

uint8_t NVIC_IRQChannelPreemptionPriority; //抢占优先级

uint8_t NVIC_IRQChannelSubPriority; //响应优先级

FunctionalState NVIC_IRQChannelCmd; //中断使能或失能

} NVIC_InitTypeDef;

(3)编写中断服务函数

配置好中断后如果有触发,即会进入中断服务函数,那么中断服务函数也有固定的函数名,可以在startup_stm32f10x_hd.s 启动文件查看,启动文件提供的只是一个中断服务函数名,具体实现什么功能还需要我们自己编写,可以将中断服务函数放在stm32f10x_it.c 文件内,也可以放在自己的应用程序中。通常我们把中断函数放在应用程序中。这里提醒一下大家,不要任意修改中断服务函数名,因为启动文件内中断服务函数名已经固定,如果要修改,你还必须在启动文件内把原中断函数修改。

外部中断

STM32F10x 外部中断/事件控制器(EXTI)包含多达20 个用于产生事件/中断请求的边沿检测器。EXTI 的每根输入线都可单独进行配置,以选择类型(中断或事件)和相应的触发事件(上升沿触发、下降沿触发或边沿触发),还可独立地被屏蔽。

中断线路最终会输入到NVIC 控制器中,从而会运行中断服务函数,实现中断内功能,这个是软件级的。

而事件线路最后产生的脉冲信号会流向其他的外设电路,通常用来触发定时器、ADC 等开始转换,是硬件级的。

EXTI时钟是由PCLK2,即APB2 提供。

需要通过AFIO 的外部中断配置寄存器 1 的EXTIx[3:0]位来决定对应的中断线映射到哪个GPIO端口上,对于中断线映射到GPIO 端口上的配置函数在stm32f10x_gpio.c 和stm32f10x_gpio.h 中,所以使用到外部中断时要把这个文件加入到工程中,在创建库函数模板的时候我们默认已经添加。

EXTI 配置步骤(EXTI 相关库函数在stm32f10x_exti.c 和stm32f10x_exti.h 文件中)

(1)使能IO 口时钟,配置IO 口模式为输入

(2)开启AFIO 时钟,设置IO 口与中断线的映射关系

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);

们将中断线0映射到GPIOA 端口,那么就需要如下配置:

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);

这时候GPIOA.0 管脚就与中断线0 连接起来

(3)配置中断分组(NVIC),使能中断

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//EXTI0中断通道

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级

NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; // 子优先级

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能

NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC 寄存器

(4)初始化EXTI,选择触发方式

配置好NVIC 后,还需要对中断线上的中断初始化,EXTI 初始化库函数如下:void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);

函数形参是有一个结构体EXTI_InitTypeDef 类型的指针变量,EXTI_InitTypeDef 结构体成员变量如下:

typedef struct

{

uint32_t EXTI_Line; //中断/事件线可配置参数为EXTI0-EXTI20

EXTIMode_TypeDef EXTI_Mode; //EXTI 模式

//配置为中断模式EXTI_Mode_Interrupt和事件模式EXTI_Mode_Event EXTITrigger_TypeDef EXTI_Trigger; //EXTI 触发方式

//配置为上升沿触发EXTI_Trigger_Rising、下降沿触发EXTI_Trigger_Falling、上//升沿和下降沿触发EXTI_Trigger_Rising_Falling。

FunctionalState EXTI_LineCmd; //中断线使能或失能

//ENABLE使能,DISABLE 失能

}EXTI_InitTypeDef;

(5)编写EXTI 中断服务函数

所有中断函数都在STM32F1启动文件中,外部中断函数名如下:

EXTI0_IRQHandler

EXTI1_IRQHandler

EXTI2_IRQHandler

EXTI3_IRQHandler

EXTI4_IRQHandler

EXTI9_5_IRQHandler

EXTI15_10_IRQHandler

定时器中断

STM32F1 的定时器功能非常强大,其包含2 个基本定时器(TIM6、TIM7)、4 个通用定时器(TIM2-TIM5)和2 个高级定时器(TIM1、TIM8),共计8 个。

通用定时器是在基本定时器的基础上扩展而来,增加了输入捕获与输出比较等功能。高级定时器又是在通用定时器基础上扩展而来,增加了可编程死区互补输出、重复计数器、带刹车(断路)功能,这些功能主要针对工业电机控制方面。

STM32F1 的通用定时器包含一个16 位自动重载计数器(CNT),该计数器由

可编程预分频器(PSC)驱动。用途包括测量输入信号的脉冲宽度(输入捕获)或者生成输出波形(输出比较和PWM)等。使用定时器预分频器和RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。

(1)时钟

通用定时器的时钟来源有4种可选:

A.内部时钟(CK_INT)

B.外部时钟模式1:外部输入引脚TIx(x=1,2,3,4)

C.外部时钟模式2:外部触发输入ETR

D.内部触发输入(ITRx(x=0,1,2,3))

通常我们都是将内部时钟(CK_INT)作为通用定时器的时钟来源,而且通用定时器的时钟是APB1 时钟的2倍,即APB1 的时钟分频数不为1。所以通用定时器的时钟频率是72MHz。

高级定时器的时钟不是来自APB1,而是来自APB2。

(2)控制器

通用定时器控制器部分包括触发控制器、从模式控制器以及编码器接口。

STM32 IIC 学习笔记总结

STM32系列IIC学习笔记经验总结一、各寄存器内容与组织:控制、地址匹配、数据、状态、时钟控制、上升沿控制

二、IIC协议及STM32的master实现 EVENT后的第一个符号表示事件发生后对应的标志位的状态,着重看7位地址的通信;

三、基础知识(主要讨论起主机模式,从机模式的配置与使用可类比) 1.默认工作在从机模式,产生起始信号后自动转为主机模式,产生终止信号或仲裁失权后自动转为从机模式;起止信号由主 机模式下的软件实现,地址也只能由主机发送,响应信号由接收器发出(软件实现),要注意区别主机、从机、发送机、接收机; 2.数据通信的直接通道,SDA LineShift RegisterDRMemory(数据寄存器与存储器直接的数据交换发生在DMA模式, 另外若从机在SDA接收到的是地址则直接会与地址寄存器比较,而不会送入数据寄存器) 3.主机产生时钟信号,一串数据总是以起始于start信号,终止于stop信号,一旦SDA线上产生start位信号,主机模 式便被选中;9个寄存器的功能分配简单明了:I2C_CR2主要配置时钟与模块中断及DMA使能位,I2C_CR1则主要产生Start等控制信号,I2C_SR2主要是MSL、TRA和BUSY标志位,I2C_SR1则是其他事件的标志位,接下来就是存储数据的I2C_DR,时钟设置的I2C_CC4R和I2C_TRISE,地址匹配的I2C_OAR1和I2C_OAR2; 4.主机模式必要操作序列:外围时钟输入最少2M(标准模式)、4M(快速模式) 1)配置I2C_CR2寄存器以产生正确时序; 2)配置时钟控制寄存器I2C_CCR; 3)配置上升时间寄存器I2C_TRISE; 4)配置I2C_CR1寄存器以使能接口电路; 5)配置I2C_CR1寄存器,置位START位以产生起始信号; 5.时序具体解析 1)Start信号,置位I2C_CR1的START位以产生起始信号(在总线空闲时,即I2C_SR2的BUSY清零),使转为主机模式(置位I2C_SR2的MSL);在主机模式下,置位START位会在当前字节传输完成后产生一个重启ReStart信号;一旦Start信号送出,I2C_SR1的SB位会由硬件置位并产生中断(前提是ITEVFEN位被置位,貌似文档有误,我认为应是IC2_SR2的ITEVTEN位),然后需要读SR1和写DR以清零SB(这也符合操作时序); 2)从机地址发送,7位模式下,地址字节一旦送出,I2C_SR1的ADDR位会由硬件置位并产生中断(前提是ITEVFEN 置位),然后主机等待读取SR1和SR2以清零ADDR(稍微符合,读SR2貌似饶了一步);7位模式下,地址字节最低位若是0则说明主机要进入发送模式,若是1则是接收模式;I2C_SR2的TRA表示主机在发送模式还是接收模式; 3)主机发送模式,地址送出且ADDR清零后,主机会将DR中数据发送到SDA line(当然经过Shift Register),主机会等到第一个数据写入DR(EV8_1阶段),若收到响应脉冲,SR1中的TxE位会置位(前提是ITEVFEN和ITBUFEN已置位);在最后一个字节传输结束前的传输过程中,若TxE置位且某数据字节没有写入DR,BTF会置位直到(硬件清零)该数据字节被写入到DR,这个过程中SCL会一直被拉低; 4)主机发送模式关闭通信,最后一个字节被写入DR,CR1的STOP位要由软件置位而产生停止信号,接口自动转为从机模式(MSL清零);置位Stop位即对应于EV8_2事件; 5)主机接收模式,地址送出且ADDR清零后,主机会进入接收模式,接口会从SDA line中读数据到DR中(同样经过Shift Register);每个字节接收后的操作序列为,产生应答信号(前提是CR1的ACK位置位),RxNE位置位并产生中断(前提是SR2的ITEVFEN和ITBUFEN置位);在最后一个字节传输结束前的传输过程中,若RxNE 置位且某数据未从DR中读取,BTF会置位直到(硬件清零)该数据字节被读出,这个过程SCL会一直被拉低; 6)主机接收模式关闭通信,收到最后一个字节后会发送NACK信号给从机,从机收到NACK会释放总线(SDA和SCL),此时主机便可发送一个Stop或Restart信号;在读完倒数第二个字节后(RxNE中断后),要清零ACK 位以产生NACK应答,要置位STOP/START位以产生Stop/Restart信号;在单字节数据接收状况,NACK 要在ADDR清零前(EV6)设置,STOP信号要在ADDR清零后配置;Stop信号产生后,主机自动进入从机模式(SR2的MSL清零); 7)最后一字节数据接收的ACK响应前若RxNE清零(ACK清零与Stop请求)没有完成,则建议采取以下步骤以确保ACK位在最后一字节数据接收前被清零,STOP位在最后一字节数据接受完后(没有附加数据)被置位: (1)2字节的数据接收:等到ADDR=1;清零ACK,置位POS;清零ADDR;等到BTF=1(数据1在DR,

STM32学习笔记

STM32学习笔记整理 端口复用配置过程 引脚具体可以复用为啥功能,参考芯片手册STM32F103ZET6.Pdf 具体每个引脚配置成什么模式,参考STM32中文参考手册,第八章,通用IO和复用。NVIC中断

假定设置中断优先级组为2,然后设置 中断3(RTC中断)的抢占优先级为2,响应优先级为1。中断6(外部中断0)的抢占优先级为3,响应优先级为0。中断7(外部中断1)的抢占优先级为2,响应优先级为0。 那么这3个中断的优先级顺序为:中断7>中断3>中断6 特别说明: 一般情况下,系统代码执行过程中,只设置一次中断优先级分组,比如分组2,设置好分组之后一般不会再改变分组。随意改变分组会导致中断管理混乱,程序出现意想不到的执行结果。 首先,系统运行后先设置中断优先级分组。调用函数: void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup); 整个系统执行过程中,只设置一次中断分组。 然后,中断初始化函数 NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 抢占优先级为1 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 子优先级位2 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据上面指定的参数初始化NVIC寄存器 结构体内容NVIC_InitTypeDef typedef struct {

MINI-STM32 开发板入门教程.

MINI-STM32 开发板入门教程(一) 开发环境建立及其应用 我们常用的 STM32 开发编译环境为 Keil 公司的 MDK (Microcontroller Development Kit) 和 IAR 公司的 EWARM. 在这里我们提供了比较稳定的新版本编译软件下载: MDK3.50 点击此处下载 EWARM 5.40 点击此处下载 限于篇幅, 在我们的教程里面将先以 MDK 下的一个例子来介绍如何使用 MDK 进行嵌入式 应用开发. MDK 安装与配置: 基于 MDK 下的开发中基本的过程: (1) 创建工程; (2) 配置工程; (3) 用 C/C++ 或者汇编语言编写源文件; (4) 编译目标应用程序 (5) 修改源程序中的错误 (6) 测试链接应用程序 ---------------------------------------------------------------- (1) 创建一个工程: 在 uVision 3 主界面中选择 "Project" -> "New uVision Project" 菜单项, 打开一个标准对话框选择好你电脑中的保存目录后, 输入一个你的工程名字后点确认.我们的工程中建了一个名字叫 "NewProject" 的工程. 从设备库中选择目标芯片, 我们的 MINI-STM32 开发板使用的是 STM32F103V8T6, 因此选 中 STMicrocontroller 下对应的芯片: ARM 32-bit Cortex-M3 Microcontroller, 72MHz, 64kB Flash, 20kB SRAM, PLL, Embedded Internal RC 8MHz and 32kHz, Real-Time Clock, Nested Interrupt Controller, Power Saving Modes, JTAG and SWD,

STM32学习笔记

输入模式初始化GPIOE2,3,4 ①IO口初始化:GPIO_InitTypeDef GPIO_InitStructure; ②使能PORTA,PORTE时钟: RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE); ③PE.2.3.4端口配置:GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; ④设置成(上拉)输入:GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; ⑤GPIO_Init(GPIOE, &GPIO_InitStructure); 输出模式初始化 ①IO口初始化:GPIO_InitTypeDef GPIO_InitStructure; ②使能PB,PE端口时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); ③3LED0-->PB.5 端口配置GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; ④设置(推挽)输出模式GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; ⑤设置IO口速度为50MHz GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; ⑥说明初始化哪个端口GPIO_Init(GPIOB, &GPIO_InitStructure); 在LED灯试验中初始为高电平灭GPIO_SetBits(GPIOB,GPIO_Pin_5); 再初始化相同发输出模式时③④⑤可省略例如(经实验初始化恰好为不同IO口相同IO序号③可省略,应该不规范吧) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1-->PE.5 端口配置, 推挽输出GPIO_Init(GPIOE, &GPIO_InitStructure); //推挽输出,IO口速度为50MHz GPIO_SetBits(GPIOE,GPIO_Pin_5); //PE.5 输出高 1,头文件可以定义所用的函数列表,方便查阅你可以调用的函数; 2,头文件可以定义很多宏定义,就是一些全局静态变量的定义,在这样的情况下,只要修改头文件的内容,程序就可以做相应的修改,不用亲自跑到繁琐的代码内去搜索。 3,头文件只是声明,不占内存空间,要知道其执行过程,要看你头文件所申明的函数是在哪个.c文件里定义的,才知道。 4,他并不是C自带的,可以不用。 5,调用了头文件,就等于赋予了调用某些函数的权限,如果你要算一个数的N次方,就要调用Pow()函数,而这个函数是定义在math.c里面的,要用这个函数,就必需调用math.h 这个头文件。

STM32入门教程

前言 一天入门STM32,仅一天的时间,是否有真的这么快。不同的人对入门的理解不一样,这篇一天入门STM32的教程,我们先对入门达成一个共识,如果你有异议,一天入门不了,请不要较真,不要骂街,保持一个工程师该有的修养,默默潜心学习,因为你还有很大的上升空间。 我眼中的入门:(前提是你学过51单片机和C语言) 1、知道参考官方的什么资料来学习,而不是陷入一大堆资料中无从下手。 2、知道如何参考官方的手册和官方的代码来独立写自己的程序,而不是一味的看到人家写的代码就觉得人家很牛逼。 3、消除对STM32的恐惧,消除对库开发的恐惧,学习是一个快乐而富有成就感的过程。

第1章一天入门STM32 本章参考资料:《STM32中文参考手册》《CM3权威指南CnR2》 学习本章时,配合《STM32中文参考手册》GPIO章节一起阅读,效果会更佳,特别是涉及到寄存器说明的部分。 1.151与STM32简介 51是嵌入式学习中一款入门级的精典MCU,因其结构简单,易于教学,且可以通过串口编程而不需要额外的仿真器,所以在教学时被大量采用,至今很多大学在嵌入式教学中用的还是51。51诞生于70年代,属于传统的8位单片机,如今,久经岁月的洗礼,既有其辉煌又有其不足。现在的市场产品竞争激烈,对成本极其敏感,相应地对MCU的要求也更苛刻:功能更多,功耗更低,易用界面和多任务。面对这些要求,51现有的资源就显得得抓襟见肘了。所以无论是高校教学还是市场需求,都急需一款新的MCU来为这个领域注入新的活力。 基于这市场的需求,ARM公司推出了其全新的基于ARMv7架构的32位Cortex-M3微控制器内核。紧随其后,ST(意法半导体)公司就推出了基于Cortex-M3内核的MCU—STM32。STM32凭借其产品线的多样化、极高的性价比、简单易用的库开发方式,迅速在众多Cortex-M3MCU中脱颖而出,成为最闪亮的一颗新星。STM32一上市就迅速占领了中低端MCU市场,受到了市场和工程师的无比青睐,颇有星火燎原之势。 作为一名合格的嵌入式工程师,面对新出现的技术,我们不是充耳不闻,而是要尽快吻合市场的需要,跟上技术的潮流。如今STM32的出现就是一种趋势,一种潮流,我们要做的就是搭上这趟快车,让自己的技术更有竞争力。 1.1.151与STM32架构的区别 我们先普及一个概念,单片机(即MCU)里面有什么。一个人最重要的是大脑,身体的各个部分都在大脑的指挥下工作。MCU跟人体很像,简单来说是由一个最重要的内核加其他外设组成,内核就相当于人的大脑,外设就如人体的各个功能器官。 下面我们来简单介绍下51和STM32的结构。 1.51系统结构 51系统结构框图

stm32的GPIO学习笔记讲课教案

s t m32的G P I O学习 笔记

I/O口工作模式: 1.高阻输入 输入模式的结构比较简单,就是一个带有施密特触发输入(Schmitt-triggered input)的三态缓冲器(U1),并具有很高的阻抗。施密特触发输入的作用是能将缓慢变化的或者是畸变的输入脉冲信号整形成比较理想的矩形脉冲信号。 执行 GPIO管脚读操作时,在读脉冲(Read Pulse)的作用下会把管脚(Pin)的当前电平状态读到内部总线上(Internal Bus)。 2.推挽输出 推挽电路是两个参数相同的三极管或MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小、效率高. 在推挽输出模式下,GPIO还具有回读功能,实现回读功能的是一个简单的三态门 U2。注意:执行回读功能时,读到的是管脚的输出锁存状态,而不是外部管脚 Pin的状态。 3.开漏输出 开漏是用来连接不同电平的器件,匹配电平用的,因为开漏引脚不连接外部的上拉电阻时,只能输出低电平,如果需要同时具备输出高电平的功能,则需要接上拉电阻,很好的一个优点是通过改变上拉电源的电压,便可以改变传输电平,比如加上上拉电阻就可以提供TTL/CMOS电平输出等。

开漏输出和推挽输出相比结构基本相同,但只有下拉晶体管 T1而没有上拉晶体管。同样,T1实际上也是多组可编程选择的晶体管。开漏输出的实际作用就是一个开关,输出“1”时断开、输出“0”时连接到 GND(有一定内阻) 开漏输出和推挽输出相比结构基本相同,但只有下拉晶体管 T1而没有上拉晶体管。同样,T1实际上也是多组可编程选择的晶体管。开漏输出的实际作用就是一个开关,输出“1”时断开、输出“0”时连接到 GND(有一定内阻). 4.钳位二级管 其作用是防止从外部管脚 Pin输入的电压过高或者过低。 提高输出电压一种简单的做法:是先在 GPIO管脚上串联一只二极管(如 1N4148),然后再接上拉电阻。 ///////////////////////////////////////////////////////////////////////////////////////////////////////// STM32的GPIO管脚深入分析: 概述:STM23的每个GPIO引脚都可以由软件配置成输出(推挽或开漏),输入(带或不带上拉或下拉)或复用的外设功能端口。多数GPIO引脚与数字或模拟的复用外设共用;除了具有模拟输入(ADC)功能的管脚之外,其他的GPIO引脚都有大电流通过能力。 tip:每个IO口可以自由编程,单IO口寄存器必须要按32位bit被访问。 STM32的每个IO端口都有7个寄存器来控制 一.具体如下8种模式:

用STM32一步一步点亮led灯

STM32之一步一步点亮led (2011-05-09 19:40) 标签: stm32led v3.4MDK 4.12入门分类:stm32 入手stm32以来,一直想快速上手,所以在各大论坛闲逛,各个达人的blog 上学习,正所谓欲速则不达,心急是吃不了热豆腐的!有木有? 最终决定使用st官网的库开发,据大侠们写道使用库可以快速上手,貌似的确如此,一个个教程写的那么好,直接拿过来用就是了。可是那么多个库,聪明的你请告诉到底选择哪一个啊?My God!实话实说,我被这些库折腾了个够!好吧,我最后还是承认最后用的是v3.4的库,是很方便! 切入正题,点亮LED。 硬件:红牛开发板,STM32F103ZET6(144封装). 软件:RealView MDK 4.12 stm32固件库:v3.4 附上自己整理后的库: V3.4_clean.rar 根据官网库自己整理了下,新建了工程模板如下图:(主要参考文章《在 Keil MDK+环境下使用STM32 V3.4库.pdf》)在KeilMDK+环境下使用STM32V3.4库.pdf 入图所示:新建一个目录01_ProLed,建议放在英文路径下,避免不必要的麻烦。将上面的库v3.4解压到此目录,再新建一个project目录,存放工程。 说明: CMSIS:最底层接口。StartUp:系统启动文件。StdPeriph_Lib:stm32外围设

备驱动文件。Project:工程文件。User:用户文件。新建工程步骤:此处略去300字。 简单说明: 1.core_cm3.c/core_cm3.h 该文件是内核访问层的源文件和头文件,查看其中的代码多半是使用汇编语言编写的。在线不甚了解。--摘自《在Keil MDK+环境下使用STM32 V3.4库》 2.stm32f10x.h 该文件是外设访问层的头文件,该文件是最重要的头文件之一。就像51里面的reg51.h一样。例如定义了 CPU是哪种容量的 CPU,中断向量等等。除了这些该头文件还定义了和外设寄存器相关的结构体,例如: 1.typedef struct

STM32各模块学习笔记

STM32 中断优先级和开关总中断 一,中断优先级: STM32(Cortex-M3) 中的优先级概念 STM32(Cortex-M3) 中有两个优先级的概念 —— 抢占式优先级和响应优先级,有人把响应优 先级称作 '亚优先级 '或 '副优先级 ',每个中断源都需要被指定这两种优先级。 具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应, 即中断嵌 套,或者说高抢占式优先级的中断可以嵌套低抢占式优先级的中断。 当两个中断源的抢占式优先级相同时, 这两个中断将没有嵌套关系, 当一个中断到来后, 如 果正在处理另一个中断, 这个后到来的中断就要等到前一个中断处理完之后才能被处理。 如 果这两个中断同时到达, 则中断控制器根据他们的响应优先级高低来决定先处理哪一个; 如 果他们的抢占式优先级和响应优先级都相等, 则根据他们在中断表中的排位顺序决定先处理 哪一个。 既然每个中断源都需要被指定这两种优先级, 就需要有相应的寄存器位记录每个中断的优先 级;在 Cortex-M3 中定义了 8 个比特位用于设置中断源的优先级,这 8 个比特位可以有 8 种分配方式,如下: 这就是优先级分组的概念。 Cortex-M3 允许具有较少中断源时使用较少的寄存器位指定中断源的优先级,因此 STM32 把指定中断优先级的寄存器位减少到 4 位,这 4个寄存器位的分组方式如下: 第 0 组:所有 4 位用于指定响应优先级 第 1 组:最高 1 位用于指定抢占式优先级,最低 第 2 组:最高 2 位用于指定抢占式优先级,最低 第 3 组:最高 3 位用于指定抢占式优先级,最低 第 4 组:所有 4 位用于指定抢占式优先级 所有 8 位用于指定响应优先级 最 高 1 位用于指定抢占式优先级, 最高 2 位用于指定抢占式优先级, 最高 3 位用于指定抢占式优先级, 最高 4 位用于指定抢占式优先级, 最高 5 位用于指定抢占式优先级, 最高 6 位用于指定抢占式优先级, 最高 7 位用于指定最低 7 位用于指定响应优先级 最低 6 位用于指定响应优先级 最低 5 位用于指定响应优先级 最低 4 位用于指定响应优先级 最低 3 位用于指定响应优先级 最低 2 位用于指定响应优先级 最低 1 位用于指定响应优先级 3 位用于指定响应优先 级 2 位用于指定响应优先 级

STM32入门基本知识

STM32学前班教程之一:选择他的理由 经过几天的学习,基本掌握了STM32的调试环境和一些基本知识。想拿出来与大家共享,笨教程本着最大限度简化删减STM32入门的过程的思想,会把我的整个入门前的工作推荐给大家。就算是给网上的众多教程、笔记的一种补充吧,所以叫学前班教程。其中涉及产品一律隐去来源和品牌,以防广告之嫌。全部汉字内容为个人笔记。所有相关参考资料也全部列出。:lol 教程会分几篇,因为太长啦。今天先来说说为什么是它——我选择STM32的原因。 我对未来的规划是以功能性为主的,在功能和面积之间做以平衡是我的首要选择,而把运算放在第二位,这根我的专业有关系。里面的运算其实并不复杂,在入门阶段想尽量减少所接触的东西。 不过说实话,对DSP的外设并和开发环境不满意,这是为什么STM32一出就转向的原因。下面是我自己做过的两块DSP28的全功能最小系统板,在做这两块板子的过程中发现要想尽力缩小DSP的面积实在不容易(目前只能达到50mm×45mm,这还是没有其他器件的情况下),尤其是双电源的供电方式和的电源让人很头疼。 后来因为一个项目,接触了LPC2148并做了一块板子,发现小型的ARM7在外设够用的情况下其实很不错,于是开始搜集相关芯片资料,也同时对小面积的AVR和51都进行了大致的比较,这个时候发现了CortexM3的STM32,比2148拥有更丰富和灵活的外设,性能几乎是2148两倍(按照MIPS值计算)。正好2148我还没上手,就直接转了这款STM32F103。 与2811相比较(核心供电情况下),135MHz×1MIPS。现在用STM32F103,72MHz×,性能是DSP的66%,STM32F103R型(64管脚)芯片面积只有2811的51%,STM32F103C型(48管脚)面积是2811的25%,最大功耗是DSP的20%,单片价格是DSP的30%。且有更多的串口,CAP和PWM,这是有用的。高端型号有SDIO,理论上比SPI速度快。 由以上比较,准备将未来的拥有操作系统的高端应用交给DSP的新型浮点型单片机28335,而将所有紧凑型小型、微型应用交给STM32。 STM32学前班教程:怎么开发 sw笨笨的STM32学前班教程之二:怎么开发目前手头的入门阶段使用的开发器概述 该产品为简易STM32调试器和DEMO板一体化的调试学习设备,价格在一百多块。 2、硬件配置

stm32pwm输入捕捉模式学习笔记

stm32 pwm输入捕捉模式学习笔记 (本文来自:android_chunhui的博客) PWM输入是输入捕获的一个特殊应用,输入捕获就是当连接到定时器的引脚上产生电平变化时对应的捕获装置会立即将当前计数值复制到另一个寄存器中。你可以开启捕获中断然后在中断处理函数中读出保存的计数值。主要用于读取pwm的频率和占空比。 与输入捕获不同的是PWM输入模式时,用到两个通道(一般用TIMx_CH1或TIMx_CH2),只给其中一个通道分配gpio时钟即可,另一个在内部使用。给一个通道分配gpio时钟后,需要设置另一个为从机且复位模式。(例如使用ch2,ch1就得设置成从机模式)。当一个输入信号(TI1或TI2)来临时,主通道捕获上升沿,从机捕获下降沿。 假设pwm从低电平开始触发,当上升沿来临时,两个通道TIM_CNT均复位开始计数,下一个下降沿来临,从机读取TIM_CNT中的值,记为CCR1,下一个上升沿来临,主通道读取TIM_CNT的值,记为CCR2。所以CCR2/f,为pwm周期,倒数即频率。CCR1/CCR2就是占空比。 下面是pwm捕获模式下的配置: void Tim2_PWMIC_Init(void) { TIM_ICInitTypeDef TIM_ICInitStructure; TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; //***通道选择,通道一为从机TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿触发 TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //管脚与寄存器对应关系TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //输入预分频。意思是控制在多少个输入周期做一次捕获,如果 //输入的信号频率没有变,测得的周期也不会变。比如选择4分频,则每四个输入周期才做一次捕获,这样在输入信号变化不频繁的情况下, //可以减少软件被不断中断的次数。 TIM_ICInitStructure.TIM_ICFilter = 0x0; //滤波设置,经历几个周期跳变认定波形稳定0x0~0xF TIM_PWMIConfig(TIM2, &TIM_ICInitStructure); //根据参数配置TIM外设信息TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2); //选择IC2为始终触发源 TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);//TIM从模式:触发信号的上升沿重新初始化计数器和触发寄存器的更新事件 TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable); //启动定时器的被动触发 TIM_Cmd(TIM2,ENABLE); //启动TIM2 TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE); //打开中断 } //中断服务函数

STM32F103RCT6使用说明

STM32开发板使用手册 风帆 STM32开发板是风帆电子为初学者学习STM32 Cortex M3 系列ARM 而设计的学习板。以STM32F103RCT6芯片为核心,配套2.4/2.8寸彩色TFT屏模块,板载UART、USB、ADC电压调节、按键、JTAG接口、彩屏接口、流水灯、SD卡接口、IO引出口等多种硬件资源。

JTAG 口 2个LED 灯 GPIOA 引出1O USB 串口1 DS10B20预留 HS0038红外接收头 红外温度传感器连接头 GPIOB@C 引出IO OLED@LCD 共用接口 STM32F103RCT6 2.4/2.8寸LCD 接口 485芯片 RS485接口 1:A; 3:B NRF24L01 模块接口 W25Q1 6 FLASH 芯片 SD 卡接口(在背面) JF24C 模块预留接口 GPIO C@D 引出IO 蜂鸣器跳线 PS/2鼠标键盘接口 三个按 键: WAKEUP KEY0 KEY1 RESET 按键 Rs232接口 电源开关 USB 接口 电源指示灯 自恢复保险丝 MAX232 电源芯片 24c02 3.3V 、5V 电 源输出; 线序为: GND/3.3V GND/5V BOOT 设置 线序为: GND /GND BOOT1/BOOT0 3.3V/3.3V

此板子不管硬件还是软件完全无缝接兼容正点原子的MINSTM32,并对MINSTM32进行了完美的升级,让我们用最少的钱做更多的事,具体升级的部分包括: 1、C PU的升级 利用ST意法半导体的CPU兼容性强的优点,此板采用比 STM32F103RBT6性能更强、且完全兼容的的STM32F103RCT6升级 CPU,把完美的MINNI STM板子的功能发挥到极致,具体2个CPU 的主要资源对比如下: 可以看出,FLASH增加了一倍,达到256K,RAM也增加了1倍,让 我们不用再为FLASH\RAM小而烦恼,使我们的存储空间更为强大; 增加了一个16位普通IC/OC/PWM),2个16位基本(IC/OC/PWM),1个STI,2个USART,这里比STM32F103RB还多了一个DAC通 道,这个STM32F103RB是没有的

STM32学习笔记之二_中断

STM32中中断的理解 一、什么是中断 中断是指在计算机执行程序的过程中,当出现异常情况或者特殊请求时,计算机停止现行的程序的运行,转而对这些异常处理或者特殊请求的处理,处理结束后再返回到现行程序的中断处,继续执行原程序。 中断处理过程: (1)保护被中断进程现场。为了在中断处理结束后能够使进程准确地返回到中断点,系统必须保存当前处理机程序状态字PSW和程序计数器PC等的值。 (2)分析中断原因,转去执行相应的中断处理程序。在多个中断请求同时发生时,处理优先级最高的中断源发出的中断请求。 (3)恢复被中断进程的现场,CPU继续执行原来被中断的进程。 二、什么是中断服务程序 处理中断事件的程序被称为中断服务程序。 三、什么是中断向量 中断向量就是中断服务程序的入口地址。 四、什么是中断向量号 中断号也叫中断类型号,或者中断请求号。 中断是指在CPU运行期间,被CPU内部或外部事件所打断、暂停当前程序的执行而转去执行一段特定的处理内部或外部时间程序的过程。外部设备进行I/O操作时,会随机产生中断请求信号。这个信号中会有特定的标志,使计算机能够判断是哪个设备提出中断请求,这个信号就叫做中断号。 五、什么是中断向量地址 中断向量地址就是内存中存放中断服务程序入口地址的地址。 六、什么是中断向量表 CPU是根据中断向量号获取中断向量值,即对应中断服务程序的入口地址值。因此为了让CPU由中断向量号查找到对应的中断向量,就需要在内存中建立一张查询表,即中断向量表。 七、STM32中中断发生时系统找到对应中断服务执行的过程 (1)根据中断设发生备确定对应的中断向量号。

(3)执行中断服务程序。 以ALIENTEK Mini STM32开发板范例代码中的定时器中断实验为例来说明。 (1)根据中断设发生备确定对应的中断向量号。 在main.c中: TIM3_Int_Init(4999,7199); 在timer.c中: void TIM3_Int_Init(u16 arr,u16 psc) { . . . NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断号 . . . } 在stm32f10x.h中: typedef enum IRQn { . . . TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ . . . } 根据以上三个文件可以确定,定时器TIM3对应的中断向量号为TIM3_IRQn,而TIM3_IRQn = 29,所以,定时器TIM3对应的中断向量号为29。

STM32教程(1)

第一部分开发板介绍 1.1 STM32开发板简介 开发板配置: ●CPU主芯片是STM32F103VCT6,主频72MHz,256KB FLASH ,48KB RAM; ●3个按键,可实现中断或查询方式判断是否有键按下; ●4个发光二极管LED,可进行流水灯或花样显示; ●1个无源蜂鸣器,可用PWM驱动; ●1个电位器,可配合内部AD进行AD转换; ●1个RS232串行通信接口,可使开发板与PC机进行通信; ●1个基于SPI串行总线的触摸屏转换接口芯片,可进行触屏操作; ●1个基于IIC串行总线的EEPROM,可进行数据存储; ●1个基于CPU片内SDIO的TF卡接口,可进行数据读写; ●1个FSMC控制的2.83英寸TFT液晶屏,可进行图片文字显示; ●1个蓝牙模块,可使开发板与PC机进行通信; ●1个USBmin2.0接口为开发板供电; ●所有I/O口引出,可通过跳线自行配置和自制外围模块连接;

下面介绍一下STN32开发板的各个部分。 1、LED灯 STM32开发板有4个LED灯,它们在开发板上的标号分别为LED1、LED2、LED3、LED4。在调试代码的时候,使用LED来指示程序状态,是非常不错的辅助调试方法。 2、按键 STM32开发板有三个普通按键,它们在开发板上的标号分别为KEY1、KEY2、KEY3。可以用于人机交互的输入,三个按键通过跳线帽连接到STM32的开发板的IO口上。 3、电源指示灯 开发板上有一个蓝色电源指示灯,它在开发板上的标号为LED5(POWER)。用于指示电源状态。该开发板通过USB供电,在该电源开启的情况下,指示灯亮,否则不亮。通过这个LED灯判断开发板的上电情况。 4、蓝牙 开发板上有一个蓝牙模块,它在开发板上的标号为Bluetooth。用于开发板与电脑进行无线通讯。 5、SD卡接口 SD卡接口在开发板上的标号为TF_Card。SD卡是最常见的存储设备,是很多数码设备的存储媒介,比如数码相框、数码相机、MP5等。STM32开发板自带了SD卡接口,可用于SD卡试验,方便大家学习SD卡。 6、AT24C01 EEPROM EEPROM型号为A T24C01,用于掉电数据保存。因为STM32内部没有EEPROM,所以开发板外扩了24C01,用于存储重要的数据,也可以用来做IIC实验,及其他应用。 7、RS232接口 RS232在开发板上的标号为J2。用于与电脑进行通信,也可以用来做USART实验。 8、滑动变阻器 滑动变阻器在开发板上的标号为ADJ_RES。通过调节滑动变阻器来改变电压值,可以用来做AD转换的实验。 9、蜂鸣器 蜂鸣器在开发板上的标号为Buzzer。通过调节定时器产生的PWM波的占空比来改变蜂鸣器的声音,可以用来做PWM实验,及其他应用。 10、液晶屏 触摸屏在开发板上的标号为TFT。用来显示一些图片和汉字。可以用来学习触摸屏的一些实验。触摸屏都需要一个AD转换器,STM32开发板触摸屏控制芯片为TSC2046。 11、引出IO口 开发板有很多引出IO口,可以通过跳线帽选择是连接各部分的功能模块还是用作引出IO 口,引出的IO口方便大家使用,可以连接外部器件。 1.2 STM32开发板硬件详解 本节介绍STM32开发板的各部分硬件,让大家对开发板的各部分硬件原理有个了解。

详细的STM32单片机学习笔记

详细的STM32单片机学习笔记 STM32单片机学习笔记 1、AHB系统总线分为APB1(36MHz)和APB2(72MHz),其中21,意思是APB2接高速设备 2、Stm32f10x.h相当于reg52.h(里面有基本的位操作定义),另一个为stm32f10x_conf.h 专门控制外围器件的配置,也就是开关头文件的作用 3、HSE Osc(High Speed External Oscillator)高速外部晶振,一般为8MHz,HSI RC(High Speed InternalRC)高速内部RC,8MHz 4、LSE Osc(Low Speed External Oscillator)低速外部晶振,一般为32.768KHz,LSI RC (Low Speed InternalRC)低速内部晶振,大概为40KHz左右,提供看门狗时钟和自动唤醒单元时钟源 5、SYSCLK时钟源有三个来源:HSI RC、HSE OSC、PLL 6、MCO[2:0]可以提供4源不同的时钟同步信号,PA8 7、GPIO口貌似有两个反向串联的二极管用作钳位二极管。 8、总线矩阵采用轮换算法对系统总线和DMA进行仲裁 9、ICode总线,DCode总线、系统总线、DMA总线、总线矩阵、AHB/APB桥 10、在使用一个外设之前,必须设置寄存器RCC_AHBENR来打开该外设的时钟 11、数据字节以小端存储形式保存在存储器中 12、内存映射区分为8个大块,每个块为512MB 13、FLASH的一页为1K(小容量和中容量),大容量是2K。 14、系统存储区(SystemMemory)为ST公司出厂配置锁死,用户无法编辑,用于对FLASH 区域进行重新编程。所以我们烧写程序务必选择BOOT1 = 0,这样通过内嵌的自举程序对

芯达STM32入门系列教程之三《如何使用J-Flash调试》

STM32入门系列教程如何使用J-Flash调试 Revision0.01 (2010-04-12)

对初学者来说,要进行STM32的程序下载调试,一般有三种方法: (1)使用SEGGER J-Flash(J-Link)下载程序到闪存中运行; (2)使用串口ISP来下载HEX文件到CPU中运行; (3)J-Link+MDK组合,来在线调试程序(可下载、调试)。 本文档讲述如何在芯达STM32开发板上使用SEGGER J-Flash下载HEX文件。而其他两种方法,我们将在文档《如何使用MDK+J-Link调试》、以及《如何使用STM32-ISP下载调试》中详细说明。 先来解释SEGGER。实际上,大家更为熟悉的ARM仿真器J-Link,就是由SEGGER公司开发的。J-Link是SEGGER为支持仿真ARM内核芯片推出的JTAG 仿真器。 不管什么CPU的仿真器,都需要安装其相应的驱动后才能使用。J-Link也不例外,它的驱动软件可以去官方网站:https://www.doczj.com/doc/1215794822.html,下载最新版本。这里使用的驱动软件版本是V4.08l,该驱动的安装非常简单,请参考文档《如何安装J-Link驱动软件》。 安装完毕,会出现如下两个图标: 现在开始我们的工作吧! 步骤一先进行设备连接操作。芯达STM开发板的JTAG口(开发板面朝上,最顶端有一个JTAG20pin的插口),与J-Link V8仿真器的输出排线连接,J-Link另一头的USB插口则插在电脑的USB口上。这时,J-Link的指示灯开始闪烁,并保持“点亮”的状态。 注意:大家购买J-Link仿真器的时候,JTAG接口要求是标准的20pin的2.54间距的针座。否则需要转接卡进行JTAG接口的转换。 步骤二进入PC的桌面,点击上图左边的图标:J-Flash ARM V4.081,出现如下界面:

STM32学习心得笔记

STM32学习心得笔记 时钟篇 在STM32中,有五个时钟源,为HSI、HSE、LSI、LSE、PLL。 ①、HSI是高速内部时钟,RC振荡器,频率为8MHz。 ②、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为 4MHz~16MHz。 ③、LSI是低速内部时钟,RC振荡器,频率为40kHz。 ④、LSE是低速外部时钟,接频率为32.768kHz的石英晶体。 ⑤、PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍, 但是其输出频率最大不得超过72MHz。 其中40kHz的LSI供独立看门狗IWDG使用,另外它还可以被选择为实时时钟RTC的时钟源。另外, 实时时钟RTC的时钟源还可以选择LSE,或者是HSE的128分频。RTC的时钟源通过RTCSEL[1:0]来选择。 STM32中有一个全速功能的USB 模块,其串行接口引擎需要一个频率为48MHz的时

钟源。该时钟源只能 从PLL输出端获取,可以选择为1.5分频或者1分频,也就是,当需要使用USB模块时,PLL 必须使能, 并且时钟频率配置为48MHz或72MHz。 另外,STM32还可以选择一个时钟信号输出到MCO脚(PA8)上,可以选择为PLL输出的2分频、HSI、HSE、或者系统时钟。 系统时钟SYSCLK,它是供STM32中绝大部分部件工作的时钟源。系统时钟可选择为PLL 输出、HSI或者HSE。系统时钟最 大频率为72MHz,它通过AHB分频器分频后送给各模块使用,AHB分频器可选择1、2、4、8、16、64、128、256、512分 频。其中AHB分频器输出的时钟送给5大模块使用: ①、送给AHB 总线、内核、内存和DMA使用的HCLK时钟。 ②、通过8分频后送给Cortex的系统定时器时钟。 ③、直接送给Cortex的空闲运行时钟FCLK。 ④、送给APB1分频器。APB1分频器可选择1、2、4、8、16分频,其输出一路供APB1外设使用(PCLK1,最大频率36MHz), 另一路送给定时器(Timer)2、3、4倍频器使用。该倍频器可选择1或者2倍频,时钟输出供定时器2、3、4使用。

(完整版)STM32F103通用教程

STM32F103_使用心得 IO端口输入输出模式设置:...........; Delay延时函数:..............; IO端口使用总结:...............; IO口时钟配置:................; 初始化IO口参数:...............; 注意:时钟使能之后操作IO口才有效!......; IO端口输出高低电平函数:...........; IO的输入 IO端口输入输出模式设置: (1) Delay延时函数: (2) IO端口使用总结: (2) IO口时钟配置: (2) 初始化IO口参数: (2) 注意:时钟使能之后操作IO口才有效! (2) IO端口输出高低电平函数: (2) IO的输入和输出宏定义方式: (3) 读取某个IO的电平函数: (3) IO口方向切换成双向 (3) IO 口外部中断的一般步骤: (3) 内部ADC使用总结: (4) LCDTFT函数使用大全 (5) TFTLCD使用注意点: (5)

IO端口宏定义和使用方法: (6) Keil使用心得: (6) ucGUI移植 (6) DDS AD9850测试程序: (6) ADC 使用小结: (7) ADC测试程序: (9) DAC—tlv5638测试程序 (9) 红外测试程序: (9) DMA使用心得: (9) 通用定时器使用: (9) BUG发现: (10) 编程总结: (10) 时钟总结: (10) 汉字显示(外部SD卡字库): (11) 字符、汉字显示(内部FLASH) (12) 图片显示: (16) 触摸屏: (17) 引脚连接: (19) IO端口输入输出模式设置: Delay延时函数: delay_ms(u16 nms); delay_us(u32 nus); IO端口使用总结: 1)使能IO 口时钟。调用函数为RCC_APB2PeriphClockCmd()。 2)初始化IO 参数。调用函数GPIO_Init();

相关主题
文本预览
相关文档 最新文档