stm32f4开发笔记
初始化
GPIO配置
配置流程
通常为:
1.GPIOx口时钟使能
如:RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
2.配置初始化结构体,见下
3.初始化GPIO口
GPIO_InitTypeDef结构体分析
源码:
typedef struct
{
uint32_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
This parameter can be any value of @ref GPIO_pins_define */
GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins.
This parameter can be a value of @ref GPIOMode_TypeDef */
GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
This parameter can be a value of @ref GPIOSpeed_TypeDef */
GPIOOType_TypeDef GPIO_OType; /*!< Specifies the operating output type for the selected pins.
This parameter can be a value of @ref GPIOOType_TypeDef */
GPIOPuPd_TypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for the selected pins.
This parameter can be a value of @ref GPIOPuPd_TypeDef */
}GPIO_InitTypeDef;
这里可说的不多,基本上通过字面意思和查找相应的结构体定义都能理解,这里着重说一下GPIO_OType和GPIO_PuPd。
先看GPIO_OType:
typedef enum
{
GPIO_OType_PP = 0x00,
GPIO_OType_OD = 0x01
}GPIOOType_TypeDef;
OD,开漏输出就是不输出电压,低电平时接地,高电平时不接地。如果外接上拉电阻,则在输出高电平时电压会拉到上拉电阻的电源电压。这种方式适合在连接的外设电压比单片机电压低的时候。
PP,推挽输出就是单片机引脚可以直接输出高电平电压。低电平时接地,高电平时输出单片机电源电压。这种方式可以不接上拉电阻。但如果输出端可能会接地的话,这个时候输出高电平可能引发单片机运行不稳定,甚至可能烧坏引脚。
GPIO_PuPd:
typedef enum
{
GPIO_PuPd_NOPULL = 0x00,
GPIO_PuPd_UP = 0x01,
GPIO_PuPd_DOWN = 0x02
}GPIOPuPd_TypeDef;
两点:1,输入信号有三种,低电平、高电平和不确定信号,上拉/下拉可以简单的理解为把不确定信号变为高/低电平信号。2,当外设电压高于板子电压时,可以使外设开漏输出,同时GPIO接上拉电阻,此时外设输出的高电平电压就会等于上拉电阻电源电压,就能正常读取高低电平信号。
Tips:矩阵键盘,4输入4输出,输入端通常为推挽输出,输入端通常接上拉电阻,毕竟电压一样。
pwm配置
输出频率的计算
以stm32f4为例:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
{ /* 可能TIM1 有不同的默认值,但是结构体的默认值一定是0呀.. */
TIM_TimeBaseInitTypeDef r1 = {
.TIM_Prescaler = 99,
// .TIM_CounterMode = TIM_CounterMode_Up,
.TIM_Period = motor_pwm_arr // 1M/motor_pwm_arr
// , .TIM_ClockDivision = TIM_CKD_DIV1
};
TIM_TimeBaseInit(TIM1, &r1);
}
这是配置pwm的部分代码,当然这还不足以让我完成频率的计算,至少,我们还需要知道APB2上的TIM1的输入频率。
首先,通过查看system_stm32f4xx.c文件,我们可以看到不同型号板子的时钟配置,以stm32f411xx为例。
*=============================================================================
* Supported STM32F411xx/STM32F410xx devices
*-----------------------------------------------------------------------------
* System Clock source | PLL (HSI)
*-----------------------------------------------------------------------------
* SYSCLK(Hz) | 100000000
*-----------------------------------------------------------------------------
* HCLK(Hz) | 100000000
*-----------------------------------------------------------------------------
* AHB Prescaler | 1
*-----------------------------------------------------------------------------
* APB1 Prescaler | 2
*-----------------------------------------------------------------------------
* APB2 Prescaler | 1
*-----------------------------------------------------------------------------
* HSI Frequency(Hz) | 16000000
*-----------------------------------------------------------------------------
* PLL_M | 16
*-----------------------------------------------------------------------------
* PLL_N | 400
*-----------------------------------------------------------------------------
* PLL_P | 4
*-----------------------------------------------------------------------------
* PLL_Q | 7
*-----------------------------------------------------------------------------
* PLLI2S_N | NA
*-----------------------------------------------------------------------------
* PLLI2S_R | NA
*-----------------------------------------------------------------------------
* I2S input clock | NA
*-----------------------------------------------------------------------------
* VDD(V) | 3.3
*-----------------------------------------------------------------------------
* Main regulator output voltage | Scale1 mode
*-----------------------------------------------------------------------------
* Flash Latency(WS) | 3
*-----------------------------------------------------------------------------
* Prefetch Buffer | ON
*-----------------------------------------------------------------------------
* Instruction cache | ON
*-----------------------------------------------------------------------------
* Data cache | ON
*-----------------------------------------------------------------------------
* Require 48MHz for USB OTG FS, | Disabled
* SDIO and RNG clock |
*-----------------------------------------------------------------------------
*=============================================================================
若APBx的的预分频系数为1,则定时器的时钟输入频率等于APBx的频率,否则为时钟输入频率的两倍,,我们可以看到stm32f411xx的APB2预分频系数为1,故TIM1的时钟输入频率等于APB2的时钟频率。
我们查看时钟树可以看到APBx是挂在AHB1上的。
通过查看stm32f411re数据手册的block diagram可以看到AHB1为100MHz,而APB2的预分频系数为1,故APB2的输出时钟频率为100MHz,由此得到TIM1的输入时钟频率为100MHz。
pwm输出频率计算公式如下:
pwm输出频率 = 定时器输入频率 / (预分频系数 + 1) / (定时器计数值 + 1)
根据需要设置预分频系数(TIM_Prescaler)和定时器计数值(TIM_Period)即可,定时器计数值最大为0xFFFF,以上述代码为例,我们需要的pwm输出频率为400Hz,100MHz / 100 / 2500 正好400Hz。
占空比的计算
占空比的计算则较为简单,以TIM1的通道1为例,有
占空比 = TIM1->CCR1 / (定时器计数值 + 1)
中断相关
中断请求服务函数
中断标志位、状态、类型判断清除等
定时器中断状态判断函数 :
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT)
参数1:定时器 参数2:中断类型
外部中断标志位判断函数 :
ITStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx)
参数1:定时器
定时器中断标志位清除函数:
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG)
参数1:定时器 参数2:中断标志位
注:两函数源码几乎是一样的,效果相同,可能是为了保持代码风格一致性
外部中断状态判断函数 :
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)
参数1:外部中断线
外部中断标志位判断函数 :
ITStatus EXTI_GetFlagStatus(uint32_t EXTI_Line)
参数1:外部中断线
后者只判断标志位,前者既看标志位也看外部中断屏蔽寄存器EXT_IMR。
外部中断标志位清除函数:
void EXTI_ClearITPendingBit(uint32_t EXTI_Line)
void EXTI_ClearFlag(uint32_t EXTI_Line)
参数1:外部中断线
注:两函数源码几乎是一样的,效果相同,可能是为了保持代码风格一致性
其他
特殊函数
assert
assert宏的原型定义在<assert.h>
中,如果expression为false,则终止程序执行,原型:
#include <assert.h>
void assert( int expression );
上一篇: ORB_SLAM2安装以及使用说明
下一篇: FreeRTOS在STM32F4上移植