一、GPIO(以STM32F103ZET6为例)

 1.1GPIO概述

1.1.1 GPIO的概念

GPIO:标准输入输出端口,每个GPIO端口上至多含有16个GPIO引脚。端口的命名方式为GPIOA、GPIOB、GPIOC......,每个端口上引脚的命名方式为 PA0、PA1、PA2........

1.1.2 GPIO的特性

参考中文数据手册

根据数据手册中列出的每个I/O端口的特定硬件特征,GPIO端口的每个位可以由软件分别配置为多种模式

输入模式——浮空输入 | 上拉输入 | 下拉输入 | 模拟输入

输出模式——开漏输出 | 推挽输出

复用模式——推挽复用 | 开漏复用

每个GPIO引脚都可以通过软件配置成各种模式

·输入/输出以主控芯片的角度考虑数据信息的流通方向,若芯片需要从外部通过GPIO引脚获取某些数据,此时该引脚应当是输入。若芯片需要通过某个引脚向外部电路输出一个信号(输出信号、控制模块),此时该引脚应当是输出。

若一个引脚的连接对象是LED灯,那么此时该引脚功能是为了控制LED灯,信号的流通方向就应当是芯片到LED灯,则应配置为输出。

若一个引脚的连接对象是按键,该引脚功能是为了判断按键是否按下,此时信号是由按键流向芯片。则应当配置为输入。

·浮空/上拉/下拉:这三者的区别主要是在引脚的外部电路没有提供具体信号时,此时的默认电平。若为上拉输入,则默认高电平,下拉输入,默认低电平,浮空输入,以外部电路为准。

·模拟输入:模拟输入下,芯片得到的是一个模拟量数据(引脚检测到的电压值)。一般和ADC有关。

·推挽/开漏:GPIO引脚内部有两个连接起来的MOS管,在推挽模式下,我们可以主动的输出高电平或低电平,即两个MOS管都可以正常导通。在开漏模式下,只能主动的输出低电平而无法输出高电平(MOS管无法导通)。

相对于推挽模式,开漏模式有自己特有的应用场景。如,推挽模式下高电平的上限由芯片决定,而开漏模式下,可以选择在外部接上拉电阻提供高电平,此时可以增强GPIO引脚的驱动能力。开漏模式下可以实现线与功能。

·通用输出/复用输出:通用输出模式下,芯片直接操作数据寄存器,使GPIO引脚输出指定电平。复用输出是指,若通信对象与芯片进行信息交流时,传输的信息较为复杂,要求符合某种时序,那么此时可以将GPIO引脚复用给芯片的某种外设,帮助实现这种时序。

1.2 GPIO寄存器

       寄存器是一个真实存在在芯片内部的存储器,用于存储一些控制信号或信息。每个寄存器都有自己的地址,我们可以通过他们的地址来找到这些寄存器,并通过对指定寄存器写入数据来实现指定的功能。在这个过程中要求我们必须找到对应的寄存器,并确定应该对寄存器如何操作。

1.2.1端口配置低寄存器

输出模式下的速度,指的是引脚电平的翻转速度

 1.2.2端口配置高寄存器

与端口配置低寄存器的区别在于所操作的引脚不同

1.2.3端口输入数据寄存器

若此时需要判断 PC4的电平是高还是低,若为高打印 h 若为低打印l

if(GPIOC->IDR & (1<<4))

printf(“h”);

else

    printf(“l”);

1.2.4端口输出数据寄存器

使PB2输出低电平

GPIOB->ODR &= ~(1<<2);

1.2.5 端口位设置/清除寄存器

1.3 代码实战(以STM32F103ZET6为例)

1.3.1点亮LED(寄存器版本)

初始化部分

将PB5设置为通用推挽输出

默认输出高电平(熄灭状态)

使用部分

想点亮等时输出低电平

int main(void)

{

//初始化部分

//使能GPIOB

RCC->APB2ENR |= (1<<3);//时钟激活

//将PB5设置为通用推挽输出


GPIOB->CRL  &= ~(1<<23);

GPIOB->CRL  &= ~(1<<22);

GPIOB->CRL  |=  (1<<21);

GPIOB->CRL  &= ~(1<<20);



//默认输出高电平(熄灭状态)

GPIOB->ODR |= (1<<5);

while(1)//while(1)中是程序运行时实际执行的代码

{

//使用部分

//想点亮等时输出低电平

GPIOB->ODR &= ~(1<<5);

}

return 0;

}

1.3.2 时钟开启

在使用相应的外设资源前要先让时钟总线为其提供时钟频率

查看芯片数据手册

寄存器需要在RCC章节寻

想要使能GPIOB端口 只需要

RCC->APB2ENR |= (1<<3);

1.3.4源代码(寄存器编写)

LED.c

#include "main.h"

//初始化led
 void led_init(void)
 {
	RCC->APB2ENR |=(1<<3);//RCC寄存器开启,使能GPIOB
	RCC->APB2ENR |=(1<<2);//RCC寄存器开启,使能GPIOA(A:1<<2;B:1<<3;C:1<<4;D:1<<5;E:1<<6)
	RCC->APB2ENR |=(1<<6);//RCC寄存器开启,使能GPIOE
	//将PB5设置为通用推挽输出;
	GPIOB->CRL &=~(1<<20);
  GPIOB->CRL |=(1<<21);
	GPIOB->CRL &=~(1<<22);
	GPIOB->CRL &=~(1<<23);	
	//将PA5设置为通用推挽输出;
	GPIOA->CRL &=~(1<<20);
  GPIOA->CRL |=(1<<21);
	GPIOA->CRL &=~(1<<22);
	GPIOA->CRL &=~(1<<23);
	
	//将PA6设置为通用推挽输出;
	GPIOA->CRL &=~(1<<24);
  GPIOA->CRL |=(1<<25);
	GPIOA->CRL &=~(1<<26);
	GPIOA->CRL &=~(1<<27);
	
	//将PE5设置为通用推挽输出;
	GPIOE->CRL &=~(1<<20);
  GPIOE->CRL |=(1<<21);
	GPIOE->CRL &=~(1<<22);
	GPIOE->CRL &=~(1<<23);
	
	//默认输出高电平(熄灭状态)
	GPIOB->ODR |=(1<<5);
	GPIOA->ODR |=(1<<5);
	GPIOA->ODR |=(1<<6);
	GPIOE->ODR |=(1<<5);
 }

LED.h

#ifndef LED_H_
#define LED_H_

#include "stm32f10x.h"

#define led1_on GPIOB->ODR &=~(1<<5)
#define led1_off GPIOB->ODR |=(1<<5)

#define led2_on GPIOA->ODR &=~(1<<5)
#define led2_off GPIOA->ODR |=(1<<5)

#define led3_on GPIOE->ODR &=~(1<<5)
#define led3_off GPIOE->ODR |=(1<<5)

#define led4_on GPIOA->ODR &=~(1<<6)
#define led4_off 	GPIOA->ODR |=(1<<6);


void led_init(void);

#endif

main.h

#ifndef __MAIN_H
#define __MAIN_H

#include "stm32f10x.h"
 
#include "led.h" 
#include "BEEP.h"
#endif

main.c

#include "main.h"
//#include "led.h"

void delay(unsigned int i)
{
	while(i--);
}

int main(void)
{	
	led_init();//LED初始化
	//beep_init();
	while(1)
	{
	  led1_on;
		led2_on;
		led3_on;
		led4_on;
		delay(0xFFFFF);	
	  led1_off;
   
		led3_off;
	
		delay(0xFFFFF);
		
    GPIOB->ODR &=~(1<<8);
		delay(0xFFFFF);
		GPIOB->ODR |=(1<<8);
		delay(0xFFFFF);
		
		
	}
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值