江科大自动化协会:STM32F103C8T6入门:GPIO初始化参数配置

目录

  • 一、前言
  • 二、必要资料
  • 1、C语言类型
  • 2、片上资源/外设
  • 3、引脚定义
  • 4、系统结构
  • 三、GPIO初始化
  • 1、首先使用RCC开启GPIO的时钟
  • 2、其次使用GPIO_Init函数初始化GPIO
  • 3、最后使用输入或输出的函数控制GPIO口
  • 四、delay,oled函数的调用
  • 1、delay
  • 2、oled
  • 一、前言

    前几天系统地将32单片机学习了一下,学习的视频是bilibili的江科大自化协c8t6的教学,为了方便以后使用,在这里和b站视频联动写下一篇笔记,以便自己查阅资料和调用函数。

    二、必要资料

    1、C语言类型

  • int在51单片机中是16位的,在STM32中32位的,如果要用16位的数据要用short来表示
  • float和double都是带符号的,没有不带符号的
  • 枚举enum的使用,类似于struct结构体,只是赋值且引用是有范围限制的

  • 2、片上资源/外设

    3、引脚定义

  • 不要轻易使用PA15,PB3,PB4,他们是作为调试端口的
  • 4、系统结构


    性能:AHB>APB2>APB1(注意关注这三者里面的外设,其实后两者性能差不多)

    三、GPIO初始化

    1、首先使用RCC开启GPIO的时钟

    从APB2总线,引出RCC_APB2PeriphClockCmd(GPIO口的名字,状态),如使GPIOA 使能:

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 
    

    2、其次使用GPIO_Init函数初始化GPIO

    void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
    

    第一个参数 GPIO_TypeDef* GPIOx 通过x选定GPIO, 如:GPIOA
    第二个参数 GPIO_InitTypeDef* GPIO_InitStruct是GPIO的结构体地址 如:&GPIO_InitStructure

  • struct 关键字,定义结构体变量
    用途:数据打包,不同类型的变量打包(可以数组,数组是同一个类型打包)

  • #define 新名字 旧名字(无脑式定义)
    typedef 旧名字 新名字(定义 长变量类型名);
    因为结构体变量类型较长,所以通常用typedef更改变量类型名

    比如:

    将结构体变量 struct{…} 换一个别名叫GPIO_InitTypeDef

  • 我们把GPIO_InitTypeDef取个名字叫GPIO_InitStructure放到void GPIO_Init()上面并且在void GPIO_Init()中取地址&GPIO_InitStructure

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 
    GPIO_InitTypeDef GPIO_InitStructure
    
    void GPIO_Init(GPIOA,GPIO_InitTypeDef* GPIO_InitStruct)
    

    由上面struct{…}结构体知道GPIO_InitStructure 有三个参数分别用.引出:
    (也可以用->直接指向结构体成员即可,就不必用*取地址和.引出结构体)

    GPIO_InitStructure.GPIO_Mode
    GPIO_InitStructure.GPIO_Pin
    GPIO_InitStructure.GPIO_Speed
    

    第一个Mode有8种模式

    GPIO_Mode_AIN(Analog IN)//模拟输入 
    GPIO_Mode_IN_FLOATING  //浮空输入
    GPIO_Mode_IPD (In Pull Down) //下拉输入
    GPIO_Mode_IPU (In Pull Up) //上拉输入
    GPIO_Mode_OUT_OD(Out Open Drain) //开漏输出
    GPIO_Mode_PP_OD(Out Push Pull) //推挽输出
    GPIO_Mode_AF_OD(Atl Open Drain) //复用开漏
    GPIO_Mode_AF_PP(Atl Push Pull) //复用推挽
    

  • 开漏 高电平没有驱动能力
  • 推挽 高低电平都有驱动能力
  • 第二个GPIO_InitStructure.GPIO_Pin 的选择

    第三个GPIO_InitStructure.GPIO_Speed的选择

    我们一般选50MHz

    最后结果如下:

    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    	GPIO_InitTypeDef GPIO_InitStructure;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    

    这样我们就把GPIOA 上所有引脚都初始化好了。

    3、最后使用输入或输出的函数控制GPIO口

    ————————————————————————————————————————————————end
    这里总共涉及了RCC和GPIO两个外设

    ★常用的三个RCC外设

    void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);
    void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
    void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
    

    ★读写GPIO的8个函数

    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);
    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:
    GPIO_SetBits :  拉高引脚输出电平 //1
    GPIO_ResetBits :拉低引脚输出电平 //0

    		GPIO_ResetBits(GPIOA, GPIO_Pin_0); //将PA0口置0
    		Delay_ms(500);
    		GPIO_SetBits(GPIOA, GPIO_Pin_0);//将PA0口置1
    		Delay_ms(500);
    		GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);//Bit_RESET设置低电平
    		Delay_ms(500);
    		GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);
    		Delay_ms(500);
    		GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)0);//强制转换BitAction类型 0 1
    		GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)1);
    		Delay_ms(500);
    
    

    例2:读取GPIO上 电平操作

    GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13);//读取PB13上引脚输入 一般是接一个按键 读它的输入 即是否按下
    GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1)//读取PA1上引脚输出 一般接光敏传感器 读它的AO口输出  即是否被遮挡
    

    例3:灯的函数使用

    //灯的打开
    void LED1_ON(void)
    {
    	GPIO_ResetBits(GPIOA, GPIO_Pin_1);
    }
    //灯的熄灭
    void LED1_OFF(void)
    {
    	GPIO_SetBits(GPIOA, GPIO_Pin_1);
    }
    //灯的翻转
    void LED1_Turn(void)
    {
    	if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == 0)
    	{
    		GPIO_SetBits(GPIOA, GPIO_Pin_1);
    	}
    	else
    	{
    		GPIO_ResetBits(GPIOA, GPIO_Pin_1);
    	}
    }
    

    四、delay,oled函数的调用

    1、delay

    Delay_us();
    Delay_ms();
    Delay_s();

    Delay.h

    #ifndef __DELAY_H
    #define __DELAY_H
    
    void Delay_us(uint32_t us);
    void Delay_ms(uint32_t ms);
    void Delay_s(uint32_t s);
    
    #endif
    

    2、oled


    上述代码添加.c和.h文件后可以直接调用

    物联沃分享整理
    物联沃-IOTWORD物联网 » 江科大自动化协会:STM32F103C8T6入门:GPIO初始化参数配置

    发表评论