https://www.bilibili.com/video/BV1th411z7sn/?vd_source=f54cfc94beeedd5e844858ca231119f6
GOIO的使用:
操作stm32的GPIO:
-
1、使用RCC开启GPIO的时钟(APB2是高速时钟,APB1是低速时钟)
-
2、使用GPIO_Init函数初始化GPIO
-
3、使用输出或输入函数控制GPIO口
GPIO库函数各项功能
-
void GPIO_DeInit(GPIO_TypeDef* GPIOx);
参数可以写GPIOA、GPIOB等等,调用这个函数后,所指定的GPIO外设就会被复位。
-
void GPIO_AFIODeInit(void);
可以复位AFIO外设。
-
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
作用:用结构体来初始化GPIO口。
需要先定义一个结构体变量,然后再给结构体赋值,最后调用该函数,函数内部就会自动读取结构体的值,然后自动把外设的各个参数配置好,这种Init函数在STM32中基本所有的外设都有,一般初始化外设都使用该函数来完成
-
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
该函数可以把结构体变量赋一个默认值。
GPIO读取函数
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
GPIO写入函数
-
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
把指定的端口设定成高电平
-
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
把指定的端口设定成低电平
-
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
根据第三个参数的值设置指定端口
-
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
可同时对16个端口进行写入操作
GPIO8种工作模式
GPIO_Mode_AIN = 0x0,(模拟输入)
GPIO_Mode_IN_FLOATING = 0x04,(浮空输入)
GPIO_Mode_IPD = 0x28,(In Pull Down↓下拉输入)
GPIO_Mode_IPU = 0x48,(In Pull Up 上拉输入)
GPIO_Mode_Out_OD = 0x14,(Out Open Drain 开漏输出)
GPIO_Mode_Out_PP = 0x10,(Out Push Push 推挽输出【点灯】)
GPIO_Mode_AF_OD = 0x1C,(Atl Open Drain 复用开漏)
GPIO_Mode_AF_PP = 0x18(Atl Open Pull 复用推挽)
void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);
用来进行引脚重映射,第一个参数可选择要重映射的方式,第二个参数是新的状态
EXTI外部中断
外部中断整体结构图
第一步:配置RCC,打开涉及到的外设时钟
第二步:配置GPIO,选择端口为输入模式
第三步:配置AFIO,选择我们用的这一路GPIO,连接到后面的EXTI
第四步:配置EXTI,选择边沿触发方式,比如上升沿、下降沿或者双边沿;还有选择触发响应方式,如中断响应和事件响应
第五步:配置NVIC,给中断选择一个合适的优先级
最后:通过NVIC,外部中断信号就能进入CPU了
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
用来配置AFIO的数据选择器,来选择我们想要的中断引脚
EXTI所有库函数各项功能
void EXTI_DeInit(void);
调用该函数可以把EXTI的配置都清除,恢复成上电默认的状态
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
根据该结构体里的参数配置EXTI外设
void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);
把参数传递的结构体变量赋一个默认值
前三个函数,基本所有外设都有,像是库函数的模版函数,基本每个外设都需要这些类型的函数。
void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);
用来软件触发外部中断,调用该函数,参数给一个指定的中断线,就能软件触发一次外部中断。
剩下的四个函数,也是库函数的模版函数,很多模块都有这四个函数。(因为在外设运行的过程中,会产生一些状态标志位,比如外部中断来了,会有一个挂起寄存器置了一个标志位,对于其他外设,比如串口收到数据,会置标志位,定时器时间到,也会置标志位,这些标志位都是放在状态寄存器的,当程序想要看这些标志位时,就可以用到以下四个函数)
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);
可以获取指定的标志位是否被置一了
void EXTI_ClearFlag(uint32_t EXTI_Line);
clearflag可以对置1的标志位进行清除
以上两个用于主程序查看和清除标志位
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
用于中断函数查看和清除标志位
第五部配置NVIC
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
中断分组,参数是中断分组的方式
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
根据结构体里面指定的参数初始化NVIC
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);
设置中断向量表
void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);
系统低功耗配置
外部中断信号从GPIO到AFIO,再到EXTI,再到NVIC, 最终通向CPU,这样才能让主程序跳转到中断程序执行
定时器
1、定时器基本定时的功能
(定一个时间,让定时器每隔这个时间产生一个中断来实现每隔一个固定时间执行一段程序的目的)用途:时钟、秒表、程序算法
(1)定时器定时中断:定时器使用内部时钟定了一个1秒钟的时间,每隔一秒申请一下中断,然后在中断函数里执行Num++,最后在OLED上显示Num。
步骤:
第一步:RCC开启时钟
第二步:选择时基单元的时钟源
第三步:配置时基单元(预分频器、自动重装器、技术模式)
第四步:配置输出中断控制,允许更新中断输出到NVIC
第五步:配置NVIC,在NVIC中打开定时器中断的通道,并分配一个优先级
第六步:运行控制
(2)定时器外部时钟
2、定时器输出比较的功能
用途:产生PWM波形,用于驱动电机
第一步:RCC开启时钟,把我们要用的TIM外设和GPIO外设的时钟打开
第二步:配置时基单元,包括时钟源选择
第三步:配置输出比较单元,包括CCR的值、输出比较模式、极性选择、输出使能这些参数
第四步:配置GPIO,把PWM对应的GPIO口,初始化为复用推挽输出的配置
第五步:运行控制,启动计数器,输出PWM
void TIM_OC1Init 用结构体来初始化输出比较单元的
void TIM_CtrlPWMOutputs 仅高级定时器使用,在使用高级定时器输出PWM时需要调用这个函数,使能主输出,否则PWM将不能正常输出