GPIO:通用输入输出端口
GPIO特点:
1.快速翻转,每次翻转最快只需要两个时钟周期(F1最高速度可以到50Mhz)
2.每个IO口都可以做中断
3.支持8种工作模式
GPIO电气特性:
STM32工作电压范围:2 V ≤ VDD ≤ 3.6 V
GPIO识别电压范围:
COMS端口:-0.3V ≤ VIL ≤ 1.164V(0);1.833V ≤ VIH ≤ 3.6V(1)
TTL端口:电平TF,5V
GPIO输出电流:单个IO最大25mA,总最大150mA,如果大于要考虑扩流方案:接三极管、MOS管、继电器
STM32引脚类型:电源引脚、晶振引脚、复位引脚、下载引脚、BOOT引脚、GPIO引脚
IO引脚分布特点:按组存在、组数视芯片而定、每组最多16个IO引脚
施密特触发器:整形电路,非标准方波->方波
GPIO寄存器介绍
F1系列:
CRL、CRH:配置工作模式,输出速度
IDR:输入数据,用于判断IO引脚电平
ODR:输出数据,用于设置IO引脚输出电平
BSRR:ODR寄存器的值
F4/F7/H7系列:
MODER:设置模式
OTYPER:输出类型
OSPEEDR:输出速度
PUPDR:上下拉电阻
IDR:输入数据
ODR:输出数据
BSRR:ODR寄存器值
建议使用BSRR寄存器控制输出
使用ODR,在读和修改访问之间产生中断时,可能会发生风险;BSRR则无风险。
设置通用外设驱动模型(四步法)
1,初始化:时钟设置、参数设置、IO设置、中断设置(开中断、设NVIC)
2,读函数(可选):从外设读取数据
3,写函数(可选):往外设写入数据
4,中断服务函数(可选):根据中断标志,处理外设各种中断事务
GPIO配置步骤:
1,使能时钟:__HAL_RCC_GPIOx_CLK_ENABLE()
2,初始化GPIO:HAL_GPIO_Init()
3,设置输出状态(可选):控制IO输出高/低电平--HAL_GPIO_WritePin() 、每次调用IO输出电平翻转一次--HAL_GPIO_TogglePin()
4,读取IO电平(可选):HAL_GPIO_ReadPin()
结构体
typedef struct
{ uint32_t Pin; /* 引脚号 */ uint32_t Mode; /* 模式设置 */ uint32_t Pull; /* 上拉下拉设置 */ uint32_t Speed; /* 速度设置 */uint32_t Alternate; /* 复用功能 */
} GPIO_InitTypeDef;
中断:打断CPU执行正常的程序,转而处理紧急程序,然后返回原暂停的程序继续运行
中断的作用:1,实时控制;2,故障处理;3,数据传输
中断的意义:高效处理紧急程序,不会一直占用CPU资源
GPIO外部中断简图:GPIO->AFIO(F1)、SYSCFG(F4/F7/H7)->EXTI->NVIC->CPU
NVIC:嵌套向量中断控制器,属于内核
中断向量表:定义一块固定的内存,以4字节对齐,存放各个中断服务函数程序的首地址
中断向量表定义在启动文件,当发生中断,CPU会自动执行对应的中断服务函数
NVIC还有:中断挂起,解挂,激活标志等非常用功能。
中断优先级:
抢占优先级(pre)>响应优先级(sub)>自然优先级
数值越小,优先级越高
NVIC的使用:
1,设置中断分组(SCB_AIRCR):HAL_NVIC_SetPriorityGrouping
2,设置中断优先级(NVIC_IPRx):HAL_NVIC_SetPriority
3,使能中断(NVIC_ISER):HAL_NVIC_EnableIRQ
EXTI基本概念:
外部(扩展)中断事件控制器,包含20个产生事件/中断请求的边沿检测器,即总共:20条EXTI线(F1)
中断和事件的理解:
中断:要进入NVIC,有相应的中断服务函数,需要CPU处理
事件:不进入NVIC,仅用于内部硬件自动控制的,如:TIM、DMA、ADC
EXTI主要特性:
F1/F4/F7系列
每条EXTI线都可以单独配置:选择类型(中断或者事件)、触发方式(上升沿,下降沿或者双边沿触发)、支持软件触发、开启/屏蔽、有挂起状态位
H7系列
由其它外设对 EXTI 产生的事件分为可配置事件和直接事件。
可配置事件:简单概括,基本和F1/F4/F7系列类似
直接事件:固定上升沿触发、不支持软件触发、无挂起状态位(由其它外设提供)
AFIO:复用功能IO,主要用于重映射和外部中断映射配置
配置AFIO寄存器之前要使能AFIO时钟:__HAL_RCC_AFIO_CLK_ENABLE();
1,调试IO配置
2,重映射配置
3,外部中断配置
SYSCFG:系统配置控制器,用于外部中断映射配置等
使能SYSCFG时钟:__HAL_RCC_SYSCFG_CLK_ENABLE();
外部中断配置
如何使用中断:
GPIO外部中断:设置输入模式(GPIO)->设置EXTI和IO映射关系(AFIO或SYSCFG)->EXTI->
外设中断:开启外设相关中断(USART/TIM/SPI…)->
设置中断分组、优先级、使能(NVIC)->按优先级顺序,依次处理中断(CPU)
EXTI的配置步骤(外部中断):
1,使能GPIO时钟:__HAL_RCC_GPIOx_CLK_ENABLE
2,设置GPIO输入模式
3,使能AFIO/SYSCFG时钟
4,设置EXTI和IO对应关系
5,设置EXTI屏蔽,上/下沿
6,设置NVIC
设置中断分组:HAL_NVIC_SetPriorityGrouping,此函数仅需设置一次
设置中断优先级:HAL_NVIC_SetPriority
使能中断:HAL_NVIC_EnableIRQ
7,设计中断服务函数:EXTIx_IRQHandler,中断服务函数,清中断标志
步骤2 - 5使用HAL_GPIO_Init一步到位
STM32有:EXTI0~4(5)、EXTI9_5(1)、EXTI15_10(1),7个外部中断服务函数
RS-232电平与COMS/TTL电平对比
1,RS-232电平--逻辑1:-15V ~ -3V;逻辑0:+3V ~ +15V
2,COMS电平(3.3V)--逻辑1:3.3V;逻辑0:0V
3, TTL电平(5V)--逻辑1:5V;逻辑0:0V
RS-232通信示意图:
控制器A<-(TTL/COMS电平)->电平转换芯片<-(RS-232电平)->DB9接口<-(RS-232电平)->DB9接口<-(RS-232电平)->电平转换芯片<-(TTL/COMS电平)->控制器B
电平转换芯片:MAX3232或者SP3232等
串口与电脑USB口通信示意图:
USB接口(安装CH340 USB 虚拟串口驱动)<-(USB电平标准)->Type-c接口<-(USB电平标准)->USB/串口转换电路(CH340C)<-(TTL/COM电平)->STM32开发板(TXD/RXD)
USART简介
USART:通用同步异步收发器
UART:通用异步收发器
USART/UART都可以与外部设备进行全双工异步通信
USART,常用的也是异步通信
USART主要特征:
1,全双工异步通信
2,单线半双工通信
3,单独的发送器和接收器使能位
4,可配置使用DMA的多缓冲器通信
5, 多个带标志的中断源
设置USART/UART波特率(F1):
波特率计算公式:baud=fck /(16∗USARTDIV)
USARTDIV=DIV_Mantissa+(DIV_Fraction/16)
fck 是串口的时钟,如:USART1的时钟是PCLK2,其他串口都是PCLK1
USARTDIV的值写入USART_BRR寄存器
/*波特率为115200为例:115200=72000000/(16∗USARTDIV)->USARTDIV=39.0625*/
uint16_t mantissa;
uint16_t fraction;
mantissa=39;
fraction=0.0625*16+0.5=0x01; /* USARTDIV = DIV_Mantissa + (DIV_Fraction/16) */
USART1->BRR = (mantissa << 4) + fraction;
寄存器版本例程的写法:USART1->BRR =(fck +(baud/2))/baud
USART/UART波特率(F4):
波特率计算公式:baud=fck /(8∗(2−OVER8)∗USARTDIV)
USARTDIV=DIV_Mantissa+(DIV_Fraction/8∗(2−OVER8))
USART/UART波特率(F7):
16倍过采样波特率计算公式:baud=fck /USARTDIV
8倍过采样波特率计算公式:baud=(2∗fck )/USARTDIV
USART/UART波特率(H7):
16倍过采样波特率计算公式:baud=(usart_ker_ckpres)/USARTDIV
8倍过采样波特率计算公式:baud=(2∗usart_ker_ckpres)/USARTDIV
usart_ker_ckpres是串口的工作时钟
波特率寄存器(BRR):把USART_CR1寄存器的位15设置为0,即使用16倍过采样。
HAL库外设初始化MSP回调机制:
HAL_PPP_Init()->调用MSP回调函数:HAL_PPP_MspInit()
MSP回调函数作用:配置PPP外设用到的硬件,如:GPIO、NVIC、CLOCK等,用户可选择是否使用并重新定义该函数
HAL库外设初始化MSP回调机制- USART为例:
HAL_UART_Init()->HAL_UART_MspInit()->
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{GPIO_InitTypeDef gpio_init_struct;if(huart->Instance == USART1) /* 如果是串口1,进行串口1 MSP初始化 */{/* (1)使能USART1和对应IO时钟,(2)初始化IO,(3)使能USART1中断,设置优先级 */}
}
HAL库中断回调机制:
HAL_PPP_IRQHandler()->HAL_PPP_xxxCallback()
HAL库中断回调机制 - USART为例(F1):
USARTx_IRQHandler()或者UARTx_IRQHandler()->HAL_USART_IRQHandler()或者HAL_UART_IRQHandler()->调用中断回调函数
UART中断回调函数:
HAL_UART_TxCpltCallback() /* 发送完成回调函数 */
HAL_UART_TxHalfCpltCallback() /* 半发送完成回调函数 */
HAL_UART_RxCpltCallback() /* 接收完成回调函数 */
HAL_UART_RxHalfCpltCallback() /* 半接收完成回调函数 */
HAL_UART_ErrorCallback() /* UART错误回调函数 */
HAL_UART_AbortCpltCallback() /* UART中止回调函数 */
HAL_UART_AbortTransmitCpltCallback() /* UART发送中止回调函数 */
HAL_UART_AbortReceiveCpltCallback() /* UART接收中止回调函数 */
USART/UART异步通信配置步骤:
1,配置串口工作参数:HAL_UART_Init()
2,串口底层初始化:HAL_UART_MspInit() 配置GPIO、NVIC、CLOCK等
3,开启串口异步接收中断:HAL_UART_Receive_IT()
4,设置优先级,使能中断:HAL_NVIC_SetPriority()、 HAL_NVIC_EnableIRQ()
5,编写中断服务函数:USARTx_IRQHandler()、 UARTx_IRQHandler()
6,串口数据发送:USART_DR, HAL_UART_Transmit()
USART/UART异步通信相关函数介绍:
1,HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
关键结构体(F1):
typedef struct
{ uint32_t BaudRate; /* 波特率 */ uint32_t WordLength; /* 字长 */uint32_t StopBits; /* 停止位 */ uint32_t Parity; /* 奇偶校验位 */ uint32_t Mode; /* UART 模式 */ uint32_t HwFlowCtl; /* 硬件流设置 */ uint32_t OverSampling; /* 过采样设置 */
}UART_InitTypeDef
2,HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
作用:以中断的方式接收指定字节的数据
形参 1 是 UART_HandleTypeDef 结构体类型指针变量
形参 2 是指向接收数据缓冲区
形参 3 是要接收的数据大小,以字节为单位
3,HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
作用:以阻塞的方式发送指定字节的数据
形参 1 :UART_HandleTypeDef 结构体类型指针变量
形参 2:指向要发送的数据地址
形参 3:要发送的数据大小,以字节为单位
形参 4:设置的超时时间,以ms单位
IO引脚复用:IO端口的输入或输出是由其它非GPIO外设控制,我们称之为复用
通用:IO端口的输入或输出是由GPIO外设控制,我们称之为通用
串口接收数据过程:
HAL_UART_Receive_IT()->以中断的方式接收一个字节数据:uint8_t g_rx_buffer[1]->在接收完成回调函数中处理接收到的数据:HAL_UART_RxCpltCallback()->接收数据引入接收数据状态变量(制定接收协议):uint16_t g_usart_rx_sta ->bit15,接收到0x0A(换行),接收完成标志;bit14,接收到0x0D(回车);bit13~0,接收到的有效字节数目:uint8_t g_usart_rx_buf[200]
串口发送数据过程:
如果收到数据,获取数据长度:uint16_t g_usart_rx_sta ->等待SR寄存器TC位置1(即等待发送完成):HAL_UART_Transmit()->发送完成,清标志->->
IWDG简介 :独立看门狗
本质:能产生系统复位信号的计数器
特性:递减的计数器;时钟由独立的RC振荡器提供(可在待机和停止模式下运行);看门狗被激活后,当递减计数器计数到0x000时产生复位
喂狗:在计数器计数到0之前,重装载计数器的值,防止复位:IWDG有什么作用
作用:主要用于检测外界电磁干扰,或硬件异常导致的程序跑飞问题
独立看门狗是异常处理的最后手段,不可依赖,应在设计时尽量避免异常的发生
IWDG溢出时间计算:
IWDG溢出时间计算公式(HAL库):Tout =(psc∗𝑟𝑙𝑟)/f𝐼𝑊𝐷𝐺
Tout:溢出时间
f𝐼𝑊𝐷𝐺:时钟源频率
psc:预分频系数
rlr:重装载值
寄存器设置分频系数的方法:"psc" =4∗2^prer
prer是IWDG_PR 的值
IWDG溢出时间计算公式(寄存器):Tout =((4∗2^prer)∗𝑟𝑙𝑟)/f𝐼𝑊𝐷𝐺
IWDG配置步骤:
1,使能IWDG,设置预分频系数和重装载值等(IWDG_PR/RL/KR):HAL_IWDG_Init()
typedef struct
{ IWDG_TypeDef *Instance; /* IWDG 寄存器基地址 */IWDG_InitTypeDef Init; /* IWDG 初始化参数 */
}IWDG_HandleTypeDef;
2,把重装载寄存器的值重载到计数器中,喂狗(IWDG_KR):HAL_IWDG_Refresh()
typedef struct
{ uint32_t Prescaler; /* 预分频系数 */ uint32_t Reload; /* 重装载值 */
} IWDG_InitTypeDef;
->->->->