学习笔记二:GPIO口操作流水灯、蜂鸣器、按键

2019-07-20 09:02发布

本帖最后由 随风飘动 于 2018-3-24 15:25 编辑

这部分只是我的一个总结,大部分的内容我还是从原子哥的教学里摘录以及网上查询资料得来的,不是很规范,当作自己总结一下,总归是一份记忆,不喜勿喷
一、STM32 GPIO口的特性
STM32分成A、B、C、D、E、F、G7个组,每一组0---15  16个IO口   所以总共有16*7=112个IO口
功能:1、普通的输入输出功能(高低电平)  2、复用功能

GPIO口的输入输出有8种模式
4种输入模式:
       输入浮空
       输入上拉
       输入下拉
       模拟输入
4种输出模式:
       推挽输出:可以输出高电平,也可以输出低电平
       开漏输出:只能输出低电平,如果想输出高电平需要外接一个上啦电阻(一般不用)
       复用推挽输出
       复用开漏输出

二、按键、蜂鸣器、流水灯
对于蜂鸣器,灯,GPIO口的配置应该是输出
对于按键,GPIO口的配置位输入

三、编程
首先要使能IO的时钟,查看硬件原理图再哪个GPIO口,具体再哪个时钟线下,看手册,贴上去,省的每次翻
QQ图片20180323152120.jpg
LED0---PF9   LED1---PF10
BEEP---PF8
KEY0---PE4  KEY1---PE3  KEY2---PE2
都是在AHB2 168MHZ下

编程:库函数版本(原子哥写的很详细,反正我自己写的差不多)
肯定需要stm32f4xx_gpio.c&stm32f4xx_gpio.h的库函数,以及时钟使能stm32f4xx_rcc.h,
自己再手打一份
<led.h>
LED_Init(void)
{
   //初始化GPIO的结构体
   GPIO_InitTypeDef GPIO_InitStructure;
   //打开PF的外设时钟使能
   RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOF,ENABLE);
  //初始化相关设置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOF, &GPIO_InitStructure);
}

LED_Switch(char val)
{
    if(val==ON)
    {
      GPIO_ResetBits(GPIOF,GPIO_Pin_9 | GPIO_Pin_10);
     }
    if(val==OFF)
    {
      GPIO_SetBits(GPIOF,GPIO_Pin_9 | GPIO_Pin_10);
     }
     if(val==LOOP)
    {
       while(1)
      {
      GPIO_ResetBits(GPIOF,GPIO_Pin_9 | GPIO_Pin_10);
      delay_ms(100);
      GPIO_SetBits(GPIOF,GPIO_Pin_9 | GPIO_Pin_10);
      delay_ms(100);
       }
     }   
}
蜂鸣器和这个相似,就不写上去了,

<key.c>
KEY_Init()
{
   //初始化GPIO的结构体
   GPIO_InitTypeDef GPIO_InitStructure;
   //打开PE的外设时钟使能
   RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOE,ENABLE);
  //初始化相关的配置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;-
  GPIO_Init(GPIOE, &GPIO_InitStructure);

}
#define KEY0                 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4) //PE4
#define KEY1                 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3) //PE3
#define KEY2                 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2) //PE2

接下来就是按下按键做什么事情,这个就自己随意了。。


GPIO需要初始化的部分。
typedef struct
{
  uint32_t GPIO_Pin//指定要初始化的端口
  GPIOMode_TypeDef GPIO_Mode;//端口模式
  GPIOSpeed_TypeDef GPIO_Speed;//速度
  GPIOOType_TypeDef GPIO_OType; //输出类型
  GPIOPuPd_TypeDef GPIO_PuPd;//上拉或者下拉
}GPIO_InitTypeDef;


!!!GPIO比较重要和经常使用的几个函数!!!
1个初始化函数:
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
2个读取输入电平函数:
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
2个读取输出电平函数:
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
4个设置输出电平函数:
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);//这个也不太常用

1个复用功能函数:
void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)

编程:寄存器版本,灯晚上下班回去总结周六时间加加油

寄存器版本:
<led.h>
void LED_INIT()
{
    //打开PF的外设时钟使能
    RCC->AHB1ENR |=(1<<5);
   //配置相关的寄存器
   //配置模式寄存器
   GPIOF->MODER&=~(3<<(9*2));
   GPIOF->MODER|=MODE<<(9*2);
   //配置输出类型位推完输出  
}
#define LED1_ON GPIOF->ODR &=~(1<<9);
#define LED1_OFF GPIOF->ODR |=(1<<9);
寄存器版本需要查看参考手册,同事对位运算要熟练操作,弄懂了我觉得还是很简单的。按键蜂鸣器的我就不贴了,原理是一样的



友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。