stm32外设

目录

GPIO 

GPIO输出 

 GPIO输入

EXIT外部中断

step1.配置GPIO、

AFIO(stm32f103) 

 SYSCFG(stm32f407)

 step2.配置EXIT

step3.配置NVIC 

step4.编写中断函数

TIM定时器 

 基本定时器

通用定时器 

 高级定时器

1. 定时中断

step1.开启时钟

step2.选择时基单元时钟源(这里定时中断选择内部时钟源)

step3.配置时基单元(预分频器、自动重装器、计数模式)

step4.配置输出中断控制(使能更新中断,输出至NVIC)

step5.配置NVIC(在NVIC中打开TIM中断通道,分配优先级)

step6.使能定时器 

2. 输出比较 

输出PWM

step0. RCC开启时钟(TIM、GPIO) 

 step1.配置时基单元(时钟源选择、预分频器PSC、计数器CNT计数模式、自动重载器ARR)

step2. 配置输出比较单元(捕获比较器CCR、输出比较模式、极性选择、输出使能)

step3. 配置GPIO(复用推免输出模式->输出PWM波)

step4.运行控制,使能TIM

3.输入捕获

测频率 :输入信号上升沿触发捕获单元的通道1从模式自动清零CNT)

step0. 开启时钟RCC(GPIO、TIM)

step1. 配置GPIO(上拉/浮空输入模式,GPIO复用为TIM2输入)

step2.配置时基单元(内部时钟源驱动下自增计数)

step3.配置输入捕获单元(输入滤波器、边沿极性选择、直连通道/交叉通道、分频器)

step4.从模式触发源(上升沿信号TI1FP1),从模式触发操作(reset--CNT清零)

step5.使能TIM。

测占空比:输入信号TI1FP1上升沿触发捕获单元的通道1(从模式自动清零CNT);输入信号TI1FP2上升沿触发捕获单元的通道2

ADC 

 输入通道

转换模式(单次/连续转换,非扫描/扫描模式)

触发控制

数据对齐

转换时间

校准

初始化步骤:

step0. 配置RCC(GPIO, ADC)

step1.配置GPIO(模拟输入)

step2. 配置ADC通用寄存器(ADC模式,CCLK分频器-stm32f4的ADC时钟不超过36Mhz)

step3.配置模拟多路开关(“点菜”:选择输入通道,配置通道转换顺序,采样周期)

step4.配置ADC转换(单次/连续,扫描/非扫描,通道数,触发控制-外部事件触发/软件触发,数据对齐方式)

(step5.模拟看门狗+中断配置)

step6.使能ADC​编辑

(step7. 若软件触发ADC,则需要调用库函数软件触发ADC采样。 )

DMA

 存储器A->存储器B 数据转运

step0.RCC开启DMA时钟 

step1.配置DMA(外设寄存器地址、数据长度、是否递增;存储器地址、数据长度、是否递增;传输方向;DMA传输模式选择-单次/循环;传输数据数目;优先级;FIFO模式...)

(step2.使能前,清除DMA数据流传输完成标志位)

step3. 使能DMA数据流,开始数据传输

外设寄存器->存储器 数据转运 

step0.RCC配置(GPIO、ADC、DAM)

step1.GPIO配置(模拟输入)

step2.DAM配置( 循环模式,P2M方向)

step3.使能DMA 

step4.ADC配置(通用配置,转换模式配置-扫描连续模式,ADC通道转换顺序和采样时间配置)

step5. 使能ADC 的DMA请求

step6.使能ADC

step7.软件触发,开启ADC转换

USART 

异步 全双工 单端 串行通信 

串口时序(小端模式:低位先行) 

 usart外设

波特率发生器 

初始化步骤 

step0.RCC配置(GPIO、USART)

step1.GPIO复用配置(Tx复用输出,Rx复用输入)

step2. 配置USART(波特率、字长、停止位、校验位、USART模式、硬件流控制)

step3.ITconfig配置接收中断

step4.配置NVIC 

 step5.使能USART

step6. 数据收发

多字节数据包接收

(发送) 给数据帧添加帧头、帧尾

(接收)状态机模式分析 

IIC 

同步 单双工 单端 串行通信 

硬件电路

为什么要上拉电阻并设置为开漏输出?

 时序基本单元

起始、终止条件 

主机发送一个字节 

 主机接收一个字节

应答位时基单元

完整时序图 

主机写时序

 主机读时序

复合格式时序

IIC外设

主机发送流程:

主机接收流程:

初始化步骤

 step0.RCC配置(GPIO、IIC)

step1,复用GPIO(开漏输出)

step2.配置IIC

step3.使能IIC

SPI 

同步 全双工 单端 串行通信 

硬件电路 

SPI时基单元

起始终止 

 字节交换(常用模式0)

SPI外设 


GPIO 

GPIO输出 

#include "led.h"
#include "Delay.h"


void led_init(void)
{
	// enable rcc
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
	
	// init GPIOF9,10
	GPIO_InitTypeDef *GPIO_InitStruct;
	GPIO_InitStruct->GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStruct->GPIO_Pin = led0 | led1;
	GPIO_InitStruct->GPIO_Speed = GPIO_Medium_Speed;
	GPIO_InitStruct->GPIO_OType = GPIO_OType_PP;
	GPIO_InitStruct->GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOF, GPIO_InitStruct);
}

void led_on(void)
{
	GPIO_WriteBit(GPIOF, led0, Bit_RESET);
	GPIO_WriteBit(GPIOF, led1, Bit_RESET);
}

void led_off(void)
{
	GPIO_WriteBit(GPIOF, led0, Bit_SET);
	GPIO_WriteBit(GPIOF, led1, Bit_SET);
}

void led_shining(void)
{
	led_on();
	Delay_ms(1000);
	led_off();
	Delay_ms(1000);
}

void led_turn(void)
{
	if(GPIO_ReadOutputDataBit(GPIOF, led0) == 0){
		led_off();
	}
	else{
		led_on();
	}
}

 GPIO输入

#include "led.h"
#include "Delay.h"


void led_init(void)
{
	// enable rcc
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
	
	// init GPIOF9,10
	GPIO_InitTypeDef *GPIO_InitStruct;
	GPIO_InitStruct->GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStruct->GPIO_Pin = led0 | led1;
	GPIO_InitStruct->GPIO_Speed = GPIO_Medium_Speed;
	GPIO_InitStruct->GPIO_OType = GPIO_OType_PP;
	GPIO_InitStruct->GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOF, GPIO_InitStruct);
}

void led_on(void)
{
	GPIO_WriteBit(GPIOF, led0, Bit_RESET);
	GPIO_WriteBit(GPIOF, led1, Bit_RESET);
}

void led_off(void)
{
	GPIO_WriteBit(GPIOF, led0, Bit_SET);
	GPIO_WriteBit(GPIOF, led1, Bit_SET);
}

void led_shining(void)
{
	led_on();
	Delay_ms(1000);
	led_off();
	Delay_ms(1000);
}

void led_turn(void)
{
	if(GPIO_ReadOutputDataBit(GPIOF, led0) == 0){
		led_off();
	}
	else{
		led_on();
	}
}
#include "stm32f4xx.h"                  // Device header
#include "led.h"
#include "key.h"

int main(void)
{	
	led_init();
	key_init();
	led_off();
	while(1)
	{
		if(key_read() == 1){
			led_turn();
		}
	}
	
}

EXIT外部中断

PS: STM32F103和STM32F407中,实现IO口与中断线映射的外设不一样。

stm32f103中是AFIO,stm32f407中是SYSCFG

 

涉及的外设:RCC、GPIO、AFIO(SYSCFG)、EXIT(不需要开启时钟)、NVIC(不需要开启时钟,在内核里,RCC只管内核外的外设)

stm32f407中断通道有23个 

EXIT外设可产生中断或事件: 

中断线路目的是把输入信号输入到NVIC,进一步会运行中断服务函数,实现功能,这样是
软件级的。而产生事件线路目的就是传输一个脉冲信号给其他外设使用,并且是电路级别的信号
传输,属于硬件级的。(减小CPU资源占用)

step1.配置GPIO、

AFIO(stm32f103) 

 

 SYSCFG(stm32f407)

 step2.配置EXIT

step3.配置NVIC 

 

step4.编写中断函数

TIM定时器 

 

 基本定时器

通用定时器 

可定时器级联增大定时时长 

 高级定时器

 

1. 定时中断

step1.开启时钟

step2.选择时基单元时钟源(这里定时中断选择内部时钟源)

step3.配置时基单元(预分频器、自动重装器、计数模式)

step4.配置输出中断控制(使能更新中断,输出至NVIC)

step5.配置NVIC(在NVIC中打开TIM中断通道,分配优先级)

step6.使能定时器 

2. 输出比较 

输出PWM

输出PWM波主要用到TIM的两个模块:时基单元(配置计数器 )、输出比较单元(配置PWM输出模式)

主要原理:通过比较CNT与CCR的值,实现高低电平翻转。通过配置ARR与CCR的值,实现输出不同频率的PWM波。

 

step0. RCC开启时钟(TIM、GPIO) 

 step1.配置时基单元(时钟源选择、预分频器PSC、计数器CNT计数模式、自动重载器ARR)

step2. 配置输出比较单元(捕获比较器CCR、输出比较模式、极性选择、输出使能)

step3. 配置GPIO(复用推免输出模式->输出PWM波)

PS:stm32f407中要通过GPIO_PinAFConfig显式得将引脚绑定为TIM输出通道 

step4.运行控制,使能TIM

3.输入捕获

 

 

测频率 :输入信号上升沿触发捕获单元的通道1从模式自动清零CNT)

step0. 开启时钟RCC(GPIO、TIM)

step1. 配置GPIO(上拉/浮空输入模式,GPIO复用为TIM2输入)

step2.配置时基单元(内部时钟源驱动下自增计数)

step3.配置输入捕获单元(输入滤波器、边沿极性选择、直连通道/交叉通道、分频器)

step4.从模式触发源(上升沿信号TI1FP1),从模式触发操作(reset--CNT清零)

step5.使能TIM。

测占空比:输入信号TI1FP1上升沿触发捕获单元的通道1(从模式自动清零CNT);输入信号TI1FP2上升沿触发捕获单元的通道2

ADC 

 输入通道

外部的 16 个通道在转换的时候又分为规则通道和注入通道,其中规则通道最多有 16 路,注入通
道最多有 4 路。

转换模式(单次/连续转换,非扫描/扫描模式)

触发控制

需要通过AFIO选择触发信号源是:外部事件(GPIO外部信号/定时器 ) or 软件控制(由ADC控制寄存器CR2某位控制)。

PS:通过TIM的TRGO事件外部触发ADC转换(当然外部事件触发ADC采样的话,需要设置为非连续模式,等待外部信号触发),再结合DMA对ADC数据寄存器进行数据搬运,就可以实现对输入模拟电压采样啦。

数据对齐

 ADC是12位的,但是数据寄存器是16位,故存在数据对齐问题;

转换时间

校准

(stm32f4内部自动校准) 

初始化步骤:

step0. 配置RCC(GPIO, ADC)

step1.配置GPIO(模拟输入)

step2. 配置ADC通用寄存器(ADC模式,CCLK分频器-stm32f4的ADC时钟不超过36Mhz)

 APB2:84MHz, CCLK:4分频

84 / 4 = 21MHz < 36MHz

step3.配置模拟多路开关(“点菜”:选择输入通道,配置通道转换顺序,采样周期)

有几个输入,就用几个通道,即调用几次该函数。 

step4.配置ADC转换(单次/连续,扫描/非扫描,通道数,触发控制-外部事件触发/软件触发,数据对齐方式)

(step5.模拟看门狗+中断配置)

step6.使能ADC

(step7. 若软件触发ADC,则需要调用库函数软件触发ADC采样。 )

DMA

支持字节(8bit)、半字(16bit)、字(32bit)访问。 

M2M(memory to memory) (stm32f407上M2M合并在传输方向里定义)

---1:软件触发,常用于存储器至存储器的转运;

---0:硬件触发,常用于外设至存储器的数据搬运(ADC,串口..)

自动重装器:使能循环模式,控制是否连续搬运,即传输计数器自减为0时,则重装,继续下一轮搬运。

PS:M2M下不能使能自动重装器,or DMA停不下来

传输计数器:搬运的数据数目 

开关控制:使能DMA,进入准备搬运状态 ,等待触发

 存储器A->存储器B 数据转运

step0.RCC开启DMA时钟 

step1.配置DMA(外设寄存器地址、数据长度、是否递增;存储器地址、数据长度、是否递增;传输方向;DMA传输模式选择-单次/循环;传输数据数目;优先级;FIFO模式...)

 

(step2.使能前,清除DMA数据流传输完成标志位)

step3. 使能DMA数据流,开始数据传输

外设寄存器->存储器 数据转运 

ADC扫描循环,DMA自动重装 (ADC每个通道完成转换后,硬件触发DMA事件,实现ADC数据寄存器16bit 至 存储器32bit的数据搬运,避免ADC数据寄存器的数据覆盖)

这里DMA的传输计数器置7,自动重装器使能。

step0.RCC配置(GPIO、ADC、DAM)

step1.GPIO配置(模拟输入)

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

step2.DAM配置( 循环模式,P2M方向)

void DMA_Init(DMA_Stream_TypeDef* DMAy_Streamx, DMA_InitTypeDef* DMA_InitStruct);

step3.使能DMA 

void DMA_Cmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState);

step4.ADC配置(通用配置,转换模式配置-扫描连续模式,ADC通道转换顺序和采样时间配置)

PS:软件触发ADC->连续模式;若外部信号上升沿触发->非连续模式。

void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct);

void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);

void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);

step5. 使能ADC 的DMA请求

/* Regular Channels DMA Configuration functions *******************************/
void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_DMARequestAfterLastTransferCmd(ADC_TypeDef* ADCx, FunctionalState NewState);

step6.使能ADC

void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);

step7.软件触发,开启ADC转换

void ADC_SoftwareStartConv(ADC_TypeDef* ADCx);

ps:这里还可以通过TIM定时触发ADC每次转换,ADC单通道转换后再触发DAM数据搬运

TIM2的TRGO更新事件 触发 ADC采样(非扫描、非连续) 每次转换完成 触发 DMA搬运数据(连续模式),实现以6.4khz采样频率,采样2048个点。
STM32 TIMER_TRGO触发+ADC采集 + DMA传输 + 中断均方根处理 实现三相电压显示_stm32定时器触发adc采样程序-CSDN博客

USART 

异步 全双工 单端 串行通信 

物理层:"RS-232"电平标准,“TTL”标准

协议层:数据包由【起始位、数据部分、校验位、停止位】构成,且通讯双方需规定相同的传输速率(波特率,注:2进制码元,波特率与比特率数值相同)

 

串口时序(小端模式:低位先行) 

 usart外设

波特率发生器 

初始化步骤 

step0.RCC配置(GPIO、USART)

step1.GPIO复用配置(Tx复用输出,Rx复用输入)

void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF);
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

step2. 配置USART(波特率、字长、停止位、校验位、USART模式、硬件流控制)

void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);

step3.ITconfig配置接收中断

void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);

step4.配置NVIC 

 step5.使能USART

void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);

step6. 数据收发

(接收数据则调用接收函数,发送则调用发送函数,查看串口状态则调用获取标志位函数)

/* Data transfers functions ***************************************************/ 
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);

多字节数据包接收

        串行收发时,单字节的数据包的起始位和停止位的添加与解析,是由USART外设的硬件电路自动完成的。但在实际应用中,我们往往需要发送多字节的数据包,如何在接收的时候判断数据帧的起始终止呢?这就需要发送端与接收端定义通信协议:指定数据帧的帧头、帧尾(or添加表示数据长度的信息帧),这样接收方就可以从数据帧中解析出有效数据。

PS:usart协议是给每次发送的一个字节数据(8 bit or 9 bit,区别是否有校验位)添加起始位与停止位,这里定义的通信协议是给发送的数据帧(多字节)添加帧头、帧尾(长度自定义)。

(发送) 给数据帧添加帧头、帧尾

(接收)状态机模式分析 

IIC 

同步 单双工 单端 串行通信 

        异步通信对时序要求严格,如usart通信则依赖其硬件电路,难以用软件模拟;且由于异步没有时钟线,若发送端串行发送过程中,发生其他事件中断占用CPU资源,接收方不知道,导致接收错误(接收超时)。

异步:时序要求严格,依赖硬件电路

同步:多一根时钟线,可软件模拟

硬件电路

为什么要上拉电阻并设置为开漏输出?

-- GPIO输出模式有2种:推挽和开漏。

推挽内接VCC电源,IIC多从机模式下,总线上会连接许多设备,若一个设备输出低电平(内部接地),一个设备输出高电平(内部接VCC),则会发生短路。

而开漏模式内部通过一个三极管开关接地,输出低电平时,开关导通,输出高电平时,开关断开,故需要外接电源,提供驱动。为了避免短路,又提供外部驱动,故需要上拉电阻。(但这也一定程度地限制了IIC的速度,低电平拉至高电平速度慢)

 时序基本单元

SCL由主机控制,从机仅在发送数据、应答时,主机释放SDA的控制,从机控制SDA. 

起始、终止条件 

主机发送一个字节 

 主机接收一个字节

应答位时基单元

完整时序图 

只有在起始和终止处,SDA状态会在SCL高电平时发送变换。 其余时候,无论主机or从机均在SCL低电平时发送数据,高电平时读取数。(高位先行)

主机写时序

  • 【s-slave address-W起始信号S产生后,所有从机就开始等待主机紧接下来广播的从机地址信号。(I2C 总线上,每个设备的地址都是唯一的,当主机广播的地址与某个设备地址相同时,这个设备就被选中了,没被选中的设备将会忽略之后的数据信号。根据I2C 协议,从机地址可以是7 位或10 位)在地址位之后,是传输方向的选择位(0 :主机向从机写数据,1:主机从从机读数据,主机释放SDA)       
  • 【A】广播完地址,从机接收到匹配的地址后,从机返回一个应答(ACK) 或非应答(NACK) 信号。        
  • 【DATA-A/NA】主机接收到应答信号后,主机开始正式向从机传输一个字节数据(DATA),每传输一个字节数据,等待从机返回应答信号ACK。(重复此过程,以实现N字节数据的传输)
  • 【P】 当数据传输结束时,主机向从机发送一个停止传输信号(P),表示不再传输数据。

 主机读时序

  • 【s-slave address-R】起始信号后,主机在总线上广播从机地址,指明主机写数据
  • 【A】对应地址从机应答
  • 【DATA】从机向SCK数据线上,传输1字节数据DATA,等待主机应答
  • 【A/NA】主机应答(A:收到数据,NA:希望从机停止发送数据)
  • 【P】主机发送停止信号

复合格式时序

        I2C 通讯更常用的是复合格式,以实现在从机的指定地址下进行读写。

        该传输过程有两次起始信号(S)。一般在第一次传输中,主机通过SLAVE_ADDRESS 寻找到从设备后,发送一段“数据”,这段数据通常用于表示从设备内部的寄存器或存储器地址(注意区分它与SLAVE_ADDRESS 的区别);在第二次的传输中,对该地址的内容进行读或写。也就是说,第一次通讯是告诉从机读写地址,第二次则是读写的实际内容。 

 

 

IIC外设

 

主机发送流程:

        写控制寄存器CR、数据寄存器DR,触发发送,检查状态寄存器SR(事件event是否发生,即标志位是否置1) 

主机接收流程:


 

初始化步骤

 step0.RCC配置(GPIO、IIC)

step1,复用GPIO(开漏输出)

step2.配置IIC

step3.使能IIC

发送接收的流程,读取事件标志位什么的看不下去啊.... 

SPI 

同步 全双工 单端 串行通信 

硬件电路 

PS:当从机没有被选择时(即SS引脚为高电平时),从机的MISO由推免输出转换为高阻态输出,防止MISO总线上从机输出冲突。 

移位示意图(模式1)

        以字节为单位,主机的时钟线控制主机和从机的移位寄存器 。

SCK上升沿时,主机的移位寄存器移出高位至MOSI总线,从机的移位寄存器移出高位至MISO;

SCK下降沿时,MOSI总线上的bit移至从机移位寄存器低位,MISO总线上的bit移至主机的移位寄存器低位。

        重复8个CLK,主机和从机完成一个字节的数据交换。

PS:主机只写,从机只读,则忽略MISO总线数据,这时MISO实际为高阻态0xFF(SPI的资源浪费) 

SPI时基单元

起始终止 

 字节交换(常用模式0)

        由时钟极性CPOL与时钟相位标志位CPHA控制,共4种模式。

        CPOL:控制空闲时刻,时钟线状态(0-低电平,1-高电平)

        CPHA:控制采样时刻,在SCK的第(1 or 2)个边沿采样(0-第一个边沿,1->第二个边沿)

        模式0比模式1快一点 

SPI外设 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值