Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5787207
  • 博文数量: 409
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 8273
  • 用 户 组: 普通用户
  • 注册时间: 2013-10-23 19:15
个人简介

qq:78080458 学习交流群:150633458

文章分类

全部博文(409)

文章存档

2019年(127)

2018年(130)

2016年(20)

2015年(60)

2014年(41)

2013年(31)

分类: 嵌入式

2016-07-05 10:46:21

    GPIO,翻译过来就是通用输入输出。我想对于输入输出,大家应该很清楚它们的意义。最常用的输出功能莫过于led,而最常用的输入功能莫过于key。

    要想使用STM32的GPIO功能,首先要明确这一功能由谁来支配。你应该了解到对于STM32单片机来说,有一部本功能是由Cortex内核来决定的,而另一部分功能则由STM32芯片自己决定 。翻开Cortex内核手册你会看到,GPIO功能是有芯片自己来决定的。



●由手册到流程

    打开stm32手册,定位到GPIO这一章,不是手册的所有内容都要读,也不是GPIO这一章的所有内容都要读。每一章的开始都有一个功能介绍,也许依据这个介绍就已经可以操作你要的功能了。。。


1、功能概述

    其实由上面的介绍已经可以总结出GPIO的基本配置过程:模式选择、输出设置、输出速度、上拉下拉。想在具体一点?直接跳转到寄存器详解


2、寄存器详解

GPIOx_MODER(模式选择)

    这是一个32位的寄存器,分为16组,也就是说2位控制一个IO引脚(STM32的每一个IO口恰好是16个管脚)。可以看到每一个IO管脚都有4种功能,目前我们使用的是前两种最简单的功能。另外,请注意它的复位值


GPIOx_OTYPER(输出类型)


    这里可以设置输出模式,对于输出又分为两种:推挽和开漏。(GPIO是16位的,因此这个寄存器的高16位系统保留了)


GPIOx_OSPEEDR(输出速度)


    输出功能无非是要驱动某一个外部器件,因此输出速度可以根据外部连接电路来设置


GPIOx_PUPDR(上拉下拉)


    配置IO上拉或者下拉,分为16组,2位控制一个管脚


GPIOx_IDR(端口数据输入)


GPIOx_ODR(端口数据输出)


    不管是数据的输入还是输出,永远都是16位的,因此这两个寄存器的高16位都是系统保留的。


3、GPIO初始化流程

    1)打开GPIO时钟(每一个模块使用的时候,必须先打开对应时钟)

    2)选择输入输出模式

    3)设置输出类型(如果是输出模式)

    4)设置输出速度(如果是输出模式)

    5)选择上拉或下拉



●由流程到代码(以led为例子)


1、直接操作寄存器

void led_init()
{

    //打开GPIOA时钟

    RCC->AHB1ENR |= 1;

    //设置PA6位输出模式
    GPIOA->MODER |= 1<<(6*2);
    //设置推挽输出
    GPIOA->OTYPER &= ~(1<<6);
    //设置输出速度50MHz
    GPIOx->OSPEEDR |= 2<<(6*2);
    //设置上拉
    GPIOA->PUPDR |=1<<(6*2);
}
void led_on()
{
    GPIOA->ODR &= ~(1<<6);
}
void led_off()
{
    GPIOA->ODR |= 1<<6;
}


2、库函数

    操作库函数,需要找到对应的库函数源文件,以及头文件。在库函数中,初始化使用结构体,结构体的定义在头文件中

void myled_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    //打开时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);    
    //选择管脚
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    //选择为输出模式
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    //推挽输出
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    //输出速度100MHz
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    //上拉
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

//开灯

void led_on()
{
   GPIO_ResetBits(GPIOA,  GPIO_Pin_6);
}

//关灯

void led_off()
{
    GPIO_SetBits(GPIOA,  GPIO_Pin_6);

}

阅读(7277) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~