STM32F407ZG学习开发板(2)
- 输入输出模式
-
- 输入模式
-
- 浮空输入
- 上拉输入
- 下拉输入
- 模拟输入
- 输出模式
-
- 开漏输出
- 推挽输出
- 复用开漏输出
- 复用推挽输出
- RCC
-
- RCC_AHB1PeriphClockCmd
- RCC_AHB1PeriphResetCmd
- RCC_AHB1PeriphClockLPModeCmd
- GPIO
-
- GPIO_DeInit
- GPIO_Init
- GPIO_StructInit
- GPIO_ToggleBits
- GPIO写入函数
-
- GPIO_SetBits
- GPIO_ResetBits
- GPIO_WriteBit
- GPIO_Write
- GPIO输出实验
-
- 点亮LED
-
- 硬件原理图
-
- MCU引脚图
- LED电路图
- 按上述原理图编写main.c
- 编写延迟函数实现跑马灯
-
- Delay.h
- 初始化延迟函数的时钟
- 延时函数
- main.c改变主循环
- 蜂鸣器发声
-
- 蜂鸣器原理
输入输出模式
GPIO(general purpose input output):通用输入输出端口的简称。可以通过软件控制其输出和输入。stm32芯片的GPIO引脚与外部设备连接,实现与外部通信、控制和数据采集的功能。
输入模式
浮空输入
上拉、下拉断开,电平高低不确定,取决于外部电路。读取开关按钮。
上拉输入
高电平输入。
下拉输入
低电平输入。
模拟输入
用AD采集到IO嘴上的真实电压。可在低功耗模式下运行,达到省电的效果。
输出模式
开漏输出
只输出低电平,只有低电平具有驱动能力需要外拉才能输出高电平。可以线和,主要用于I2C和SMBUS总线。
推挽输出
可输出高低电平,具有连接数字设备的驱动能力。强大的负载能力。 输出高电平,电流输出到负载,称为灌溉电流,推;输出低电平,负载电流到芯片,称为拉电流,拉。
复用开漏输出
复用推挽和复用开漏其实很简单,在你理解了开漏和推挽的原理之后,如果你不想用单片机内部来输出,那么你可以进行复用,将输出转移到其他外设上面。
复用推挽输出
RCC
40_41xxx的stm32f4xx_rcc.h函数声明如下,AHB和APB各有两个,可以查看第一个参数的具体值范围*.c文件。 这里只举例AHB三个常用函数1。
RCC_AHB1PeriphClockCmd
使能/禁用AHB1外设时钟。 (uint32_t RCC_AHB1Periph, FunctionalState NewState) 参数:
- RCC_AHB1Periph:指定AHB1外门控时钟只能是以下值: RCC_AHB1Periph_GPIOA: GPIOA clock RCC_AHB1Periph_GPIOB: GPIOB clock RCC_AHB1Periph_GPIOC: GPIOC clock RCC_AHB1Periph_GPIOD: GPIOD clock RCC_AHB1Periph_GPIOE: GPIOE clock RCC_AHB1Periph_GPIOF: GPIOF clock RCC_AHB1Periph_GPIOG: GPIOG clock RCC_AHB1Periph_GPIOG: GPIOG clock ////这次旅行的官方是写的G,可能是H? RCC_AHB1Periph_GPIOI: GPIOI clock RCC_AHB1Periph_GPIOJ: GPIOJ clock (STM32F42xxx/43xxx devices) RCC_AHB1Periph_GPIOK: GPIOK clock (STM32F42xxx/43xxx devices) RCC_AHB1Periph_CRC: CRC clock RCC_AHB1Periph_BKPSRAM: BKPSRAM interface clock RCC_AHB1Periph_CCMDATARAMEN: CCM data RAM interface clock RCC_AHB1Periph_DMA1: DMA1 clock RCC_AHB1Periph_DMA2: DMA2 clock RCC_AHB1Periph_DMA2D: DMA2D clock (STM32F429xx/439xx devices) RCC_AHB1Periph_ETH_MAC: Ethernet MAC clock RCC_AHB1Periph_ETH_MAC_Tx: Ethernet Transmission clock RCC_AHB1Periph_ETH_MAC_Rx: Ethernet Reception clock RCC_AHB1Periph_ETH_MAC_PTP: Ethernet PTP clock RCC_AHB1Periph_OTG_HS: USB OTG HS clock RCC_AHB1Periph_OTG_HS_ULPI: USB OTG HS ULPI clock
- NewState:即使能/失能ENABLE/DISABLE
RCC_AHB1PeriphResetCmd
强制或释放AHB1外围设备复位。 (uint32_t RCC_AHB1Periph, FunctionalState NewState) 参数与上一个函数一致,第一个值范围略有不同。
RCC_AHB1PeriphClockLPModeCmd
在Low Power (Sleep)在模式下使能/关闭AHB1外设时钟。 (uint32_t RCC_AHB1Periph, FunctionalState NewState) 参数与上一个函数一致,第一个值范围略有不同。
GPIO
GPIO_DeInit
参数:(GPIO_TypeDef* GPIOx) 复位GPIOx(GPIOA到GPIOK)
GPIO_Init
参数:(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) 初始化结构GPIOx。 结构体参数如下:
typedef struct { uint32_t GPIO_Pin ; //需要配置的GPIO引脚,可以用按位或操作符选择多个引脚 GPIOMode_TypeDef GPIO_Mode ; //指定所选引脚的工作模式。 GPIOSpeed_TypeDef GPIO_Speed ; //指定所选引脚的速度。 GPIOOType_TypeDef GPIO_OType ; //指定所选引脚的操作输出类型。 GPIOPuPd_TypeDef GPIO_PuPd ; //指定所选引脚的上拉/下拉操作。 }GPIO_InitTypeDef ; typedef enum { GPIO_Mode_IN = 0x00 , /*输入*/ GPIO_Mode_OUT = 0x01 , /*输出*/ GPIO_Mode_AF = 0x02 , /*GPIO备用功能模式,复用*/ GPIO_Mode_AN = 0x03 /*GPIO模拟模式*/ }GPIOMode_TypeDef ; typedef enum { //这里也是可以使用GPIO_Speed_xxMHz的,xx可取25、50、100 GPIO_Low_Speed = 0x00 , /*!< Low speed */ GPIO_Medium_Speed = 0x01 , /*!< Medium speed */ GPIO_Fast_Speed = 0x02 , /*!< Fast speed */ GPIO_High_Speed = 0x03 /*!< High speed */ }GPIOSpeed_TypeDef ; typedef enum { GPIO_OType_PP = 0x00 , //推挽 Push Pull GPIO_OType_OD = 0x01 //开漏 Open Drain }GPIOOType_TypeDef ; typedef enum { GPIO_PuPd_NOPULL = 0x00 , //浮空 GPIO_PuPd_UP = 0x01 , //上拉 GPIO_PuPd_DOWN = 0x02 //下拉 }GPIOPuPd_TypeDef ;
GPIO_StructInit
参数:(GPIO_InitTypeDef* GPIO_InitStruct) 将结构体附默认值
GPIO_ToggleBits
参数:(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 切换指定的GPIO引脚。
GPIO写入函数
GPIO_SetBits
参数:(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 把一些bits置1
GPIO_ResetBits
参数:(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 把一些bits置0
GPIO_WriteBit
参数:(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal); 将某一位赋指定值
GPIO_Write
参数:(GPIO_TypeDef* GPIOx, uint16_t PortVal); 直接赋值该GPIO的16位
GPIO输出实验
点亮LED
硬件原理图
MCU引脚图
可知GPIOF的Pin_9和Pin_10分别接LED0和LED1
LED电路图
可知LED0和LED1置高电平时不导通,即灯灭,置低电平时导通,灯亮。
根据上述原理图编写main.c
#include "stm32f4xx.h"
int main()
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 根据原理图使能GPIOF,选择AHB1外设时钟 */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //选择输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //选择推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //根据原理图led的两个引脚为PF9和PF10
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHz
GPIO_Init(GPIOF, &GPIO_InitStructure); //初始化GPIOF
GPIO_SetBits(GPIOF, GPIO_Pin_9 | GPIO_Pin_10); //初始化引脚值为高电平,根据原理图即灯熄灭
while(1)
{
GPIO_ResetBits(GPIOF, GPIO_Pin_9 | GPIO_Pin_10); //Reset两个引脚(即置0),灯亮
}
}
编写延时函数实现跑马灯
CM4 内核的处理和CM3 一样 ,内部都包含了一个 SysTick 定时器,SysTick是一个24位的倒计数定时器,当计到0时,将从RELOAD寄存器中自动重装载定时初值。只要不把它在SysTick控制及状态寄存器中的使能位清除,就永不停息。我们就是利用STM32的内部SysTick 来实现延时的,这样既不占用中断,也不占用系统定时器。
Delay.h
#ifndef DELAY_H__
#define DELAY_H__
#include "stm32f4xx.h"
void delay_init(u8 SYSCLK); //初始化系统时钟
void delay_ms(u16 xms); //延时xms
void delay_us(u32 xus); //延时xus
#endif
初始化延时函数的时钟
void delay_init(u8 SYSCLK); 参数:(u8 SYSCLK); SYSCLK就是Systick时钟的频率。 用到misc.h中的一个函数void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource);配置系统时钟的来源,有两个参数可供选择: SysTick_CLKSource_HCLK_Div8: AHB时钟频率除以8作为系统时钟源。 SysTick_CLKSource_HCLK: 直接使用AHB作为系统时钟源。
延时函数
延时的两个函数操作类似,主要使用了以下几个寄存器: SysTick是MDK定义了的一个结构体(在core_m4.h里面),里面包含CTRL 、LOAD 、VAL 、 CALIB等4 个寄存器: 重装值寄存器,即当VAL为0时,VAL将被重装的值。 记录次数的寄存器
校准用,这里没有用到。
使能滴答定时器:SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
关闭滴答定时器:SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
SysTick_CTRL_ENABLE_Msk宏定义位1<<0,那么CTRL或等于它即把最低位置1,即打开时钟。
给LOAD赋值,清空VAL的值。 等待直到当CTRL的0位(使能位)且16位(COUNTFLAG)都为1时才停止时钟。 清空VAL的值。
STM32F4的时钟系统,如图HCLK最高168MHz,若使用HCLK除以8作为SysTick时钟源,则最高21MHz,那么每微妙所需要的时钟数为21M/s x 1us = 21,则根据24位寄存器,取值范围可以给到 (2^24 - 1) / 21 = 798915 us。ms的取值就大概在798ms。
main.c的主循环改一下即可
delay_init(168); //初始化延时函数
while(1)
{
GPIO_ResetBits(GPIOF, GPIO_Pin_9); //F9置0,F10置1
GPIO_SetBits(GPIOF, GPIO_Pin_10);
delay_ms(500);
GPIO_ResetBits(GPIOF, GPIO_Pin_10); //F9置1,F10置0
GPIO_SetBits(GPIOF, GPIO_Pin_9);
delay_ms(500);
}
蜂鸣器发声
蜂鸣器原理
由于蜂鸣器的启动电流较大,因此一般使用三极管驱动,STM32F4的引脚只作为标记使能。开发板使用的引脚为PF8。 如图使用NPN型三极管,BEEP输入高电平时导通,蜂鸣器发声。 则具体代码和控制LED类似,不再赘述。