STM32 文档整理

//***********************************************************************************************************//

|----------|-----------|
| 英文缩写 | 名称 |
| NVIC | 嵌套向量中断控制器 |
| SysTick | 系统滴答定时器 |
| RCC | 复位和时钟控制 |
| GPIO | 通用IO口 |
| AFIO | 复用IO口 |
| EXTI | 外部中断 |
| TIM | 定时器 |
| ADC | 模数转换器 |
| DMA | 直接内存访问 |
| USART | 同步/异步串口通信 |
| I2C | I2C通信 |
| SPI | SPI通信 |
| CAN | CAN通信 |
| USB | USB通信 |
| RTC | 实时时钟 |
| CRC | CRC校验 |
| PWR | 电源控制 |
| BKP | 备份寄存器 |
| IWDG | 独立看门狗 |
| WWDG | 窗口看门狗 |
| DAC | 数模转换器 |
| SDIO | SD卡接口 |
| FSMC | 可变静态存储控制器 |
| USB OTG | USB主机接口 |

//***********************************************************************************************************//

GPIO(General Purpose Input Output)通用输入输出口

可配置为8种输入输出模式

引脚电平:0V~3.3V,部分引脚可容忍5V

输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等

输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接收数据等

|----------|--------|---------------------------|
| 模式名称 | 性质 | 特征 |
| 浮空输入 | 数字输入 | 可读取引脚电平,若引脚悬空,则电平不确定 |
| 上拉输入 | 数字输入 | 可读取引脚电平,内部连接上拉电阻,悬空时默认高电平 |
| 下拉输入 | 数字输入 | 可读取引脚电平,内部连接下拉电阻,悬空时默认低电平 |
| 模拟输入 | 模拟输入 | GPIO无效,引脚直接接入内部ADC |
| 开漏输出 | 数字输出 | 可输出引脚电平,高电平为高阻态,低电平接VSS |
| 推挽输出 | 数字输出 | 可输出引脚电平,高电平接VDD,低电平接VSS |
| 复用开漏输出 | 数字输出 | 由片上外设控制,高电平为高阻态,低电平接VSS |
| 复用推挽输出 | 数字输出 | 由片上外设控制,高电平接VDD,低电平接VSS |

输入输出口流程:

  1. 配置RCC------时钟

  2. 配置GPIO------引脚号

     /*开启时钟*/
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
     
     /*GPIO初始化*/
     GPIO_InitTypeDef GPIO_InitStructure;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOA, &GPIO_InitStructure);	
    

//***********************************************************************************************************//

中断:在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU暂停当前正在运行的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行

中断优先级:当有多个中断源同时申请中断时,CPU会根据中断源的轻重缓急进行裁决,优先响应更加紧急的中断源

中断嵌套:当一个中断程序正在运行时,又有新的更高优先级的中断源申请中断,CPU再次暂停当前中断程序,转而去处理新的中断程序,处理完成后依次进行返回

NVIC的中断优先级由优先级寄存器的4位(0~15)决定,这4位可以进行切分,分为高n位的抢占优先级和低4-n位的响应优先级

抢占优先级高的可以中断嵌套,响应优先级高的可以优先排队,抢占优先级和响应优先级均相同的按中断号排队

|----------|-------------|-------------|
| 分组方式 | 抢占优先级 | 响应优先级 |
| 分组0 | 0位,取值为0 | 4位,取值为0~15 |
| 分组1 | 1位,取值为0~1 | 3位,取值为0~7 |
| 分组2 | 2位,取值为0~3 | 2位,取值为0~3 |
| 分组3 | 3位,取值为0~7 | 1位,取值为0~1 |
| 分组4 | 4位,取值为0~15 | 0位,取值为0 |

//***********************************************************************************************************//

TIM(Timer)定时器

    /*开启时钟*/
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	
	/*配置时钟源*/
	TIM_InternalClockConfig(TIM2);

	/*时基单元初始化*/
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	/*中断输出配置*/
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	/*NVIC中断分组*/
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	/*NVIC配置*/
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	/*TIM使能*/
	TIM_Cmd(TIM2, ENABLE);

    /*开启时钟*/
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	/*外部时钟配置*/
	TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x0F);
	
	/*时基单元初始化*/
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;	
	TIM_TimeBaseInitStructure.TIM_Period = 10 - 1;
	TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	/*中断输出配置*/
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);					
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	/*NVIC中断分组*/
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	/*NVIC配置*/
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	/*TIM使能*/
	TIM_Cmd(TIM2, ENABLE);

//***********************************************************************************************************//

EXTI(Extern Interrupt)外部中断

EXTI可以监测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序

支持的触发方式:上升沿/下降沿/双边沿/软件触发

支持的GPIO口:所有GPIO口,但相同的Pin不能同时触发中断

通道数:16个GPIO_Pin,外加PVD输出、RTC闹钟、USB唤醒、以太网唤醒

触发响应方式:中断响应/事件响应

外部中断流程:

  1. 配置RCC------时钟

  2. 配置GPIO------中断引脚号

  3. 配置AFIO------中断引脚选择

  4. 配置EXTI------边沿检测及控制

  5. 配置NVIC------优先级选择

     /*开启时钟*/
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
     
     /*GPIO初始化*/
     GPIO_InitTypeDef GPIO_InitStructure;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOB, &GPIO_InitStructure);
     
     /*AFIO选择中断引脚*/
     GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);
     
     /*EXTI初始化*/
     EXTI_InitTypeDef EXTI_InitStructure;
     EXTI_InitStructure.EXTI_Line = EXTI_Line14;
     EXTI_InitStructure.EXTI_LineCmd = ENABLE;
     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
     EXTI_Init(&EXTI_InitStructure);
     
     /*NVIC中断分组*/
     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
     
     /*NVIC配置*/
     NVIC_InitTypeDef NVIC_InitStructure;
     NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
     NVIC_Init(&NVIC_InitStructure);	
    

//***********************************************************************************************************//

OC(Output Compare)输出比较

输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形

每个高级定时器和通用定时器都拥有4个输出比较通道

高级定时器的前3个通道额外拥有死区生成和互补输出的功能

PWM(Pulse Width Modulation)脉冲宽度调制

在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域

PWM参数:

频率 = 1 / TS 占空比 = TON / TS 分辨率 = 占空比变化步距

//***********************************************************************************************************//

IC(Input Capture)输入捕获

输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数

每个高级定时器和通用定时器都拥有4个输入捕获通道

可配置为PWMI模式,同时测量频率和占空比

可配合主从触发模式,实现硬件全自动测量

//***********************************************************************************************************//

USART(Universal Synchronous/Asynchronous Receiver/Transmitter)通用同步/异步收发器

USART是STM32内部集成的硬件外设,可根据数据寄存器的一个字节数据自动生成数据帧时序,从TX引脚发送出去,也可自动接收RX引脚的数据帧时序,拼接为一个字节数据,存放在数据寄存器里

自带波特率发生器,最高达4.5Mbits/s

可配置数据位长度(8/9)、停止位长度(0.5/1/1.5/2)

可选校验位(无校验/奇校验/偶校验)

支持同步模式、硬件流控制、DMA、智能卡、IrDA、LIN

|--------|-------------------|--------|--------|--------|--------|
| 名称 | 引脚 | 双工 | 时钟 | 电平 | 设备 |
| USART | TX、RX | 全双工 | 异步 | 单端 | 点对点 |
| I2C | SCL、SDA | 半双工 | 同步 | 单端 | 多设备 |
| SPI | SCLK、MOSI、MISO、CS | 全双工 | 同步 | 单端 | 多设备 |
| CAN | CAN_H、CAN_L | 半双工 | 异步 | 差分 | 多设备 |
| USB | DP、DM | 半双工 | 异步 | 差分 | 点对点 |

//***********************************************************************************************************//

ADC(Analog-Digital Converter)模拟-数字转换器

ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁 12位逐次逼近型ADC,1us转换时间 输入电压范围:0~3.3V,转换结果范围:0~4095 18个输入通道,可测量16个外部和2个内部信号源 规则组和注入组两个转换单元 模拟看门狗自动监测输入电压范围

    /*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	/*设置ADC时钟*/
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//选择时钟6分频,ADCCLK = 72MHz / 6 = 12MHz
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	/*规则组通道配置*/
	ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
	
	/*ADC初始化*/
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;
	ADC_InitStructure.ADC_NbrOfChannel = 1;
	ADC_Init(ADC1, &ADC_InitStructure);
	
	/*ADC使能*/
	ADC_Cmd(ADC1, ENABLE);
	
	/*ADC校准*/
	ADC_ResetCalibration(ADC1);
	while (ADC_GetResetCalibrationStatus(ADC1) == SET);
	ADC_StartCalibration(ADC1);
	while (ADC_GetCalibrationStatus(ADC1) == SET);





uint16_t AD_GetValue(void)
{
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);
	while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
	return ADC_GetConversionValue(ADC1);
}

    /*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	/*设置ADC时钟*/
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//选择时钟6分频,ADCCLK = 72MHz / 6 = 12MHz
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	/*不在此处配置规则组序列,而是在每次AD转换前配置,这样可以灵活更改AD转换的通道*/
	
	/*ADC初始化*/
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;
	ADC_InitStructure.ADC_NbrOfChannel = 1;
	ADC_Init(ADC1, &ADC_InitStructure);
	
	/*ADC使能*/
	ADC_Cmd(ADC1, ENABLE);
	
	/*ADC校准*/
	ADC_ResetCalibration(ADC1);
	while (ADC_GetResetCalibrationStatus(ADC1) == SET);
	ADC_StartCalibration(ADC1);
	while (ADC_GetCalibrationStatus(ADC1) == SET);




uint16_t AD_GetValue(uint8_t ADC_Channel)
{
	ADC_RegularChannelConfig(ADC1, ADC_Channel, 1, ADC_SampleTime_55Cycles5);
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);
	while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
	return ADC_GetConversionValue(ADC1);
}
相关推荐
日晨难再1 小时前
嵌入式:STM32的启动(Startup)文件解析
stm32·单片机·嵌入式硬件
yufengxinpian1 小时前
集成了高性能ARM Cortex-M0+处理器的一款SimpleLink 2.4 GHz无线模块-RF-BM-2340B1
单片机·嵌入式硬件·音视频·智能硬件
__基本操作__2 小时前
历遍单片机下的IIC设备[ESP--0]
单片机·嵌入式硬件
网易独家音乐人Mike Zhou9 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
zy张起灵9 小时前
48v72v-100v转12v 10A大功率转换电源方案CSM3100SK
经验分享·嵌入式硬件·硬件工程
PegasusYu11 小时前
STM32CUBEIDE FreeRTOS操作教程(九):eventgroup事件标志组
stm32·教程·rtos·stm32cubeide·free-rtos·eventgroup·时间标志组
lantiandianzi16 小时前
基于单片机的多功能跑步机控制系统
单片机·嵌入式硬件
文弱书生65616 小时前
输出比较简介
stm32
哔哥哔特商务网16 小时前
高集成的MCU方案已成电机应用趋势?
单片机·嵌入式硬件
跟着杰哥学嵌入式16 小时前
单片机进阶硬件部分_day2_项目实践
单片机·嵌入式硬件