嵌入式学习-STC-GPIO

记录每次学习的过程,总结学习的内容,希望能给到自己和别人帮助。

嵌入式学习-STC-GPIO

通用型之输入输出
GPIO(英语:General-purpose input/output),通用型之输入输出的简称,功能类似8051的P0—P3,其接脚可以供使用者由程控自由使用,PIN脚依现实考量可作为通用输入(GPI)或通用输出(GPO)或通用输入与输出(GPIO),如当clk generator, chip select等。
既然一个引脚可以用于输入、输出或其他特殊功能,那么一定有寄存器用来选择这些功能。对于输入,一定可以通过读取某个寄存器来确定引脚电位的高低;对于输出,一定可以通过写入某个寄存器来让这个引脚输出高电位或者低电位;对于其他特殊功能,则有另外的寄存器来控制它们。

设置工作模式

● 最多可达 60 个 GPIO: P0.0P07、P1.0 P1,7 (无P1.2) 、P2.0 P2,7、P3.0 P3,7、P4.0 P47、P5.0P5.4.
● P6.0P6.7、P7.0P7.7所有的 GPIO 均支持如下 4 种模式: 准双向口模式、强推挽输出模式、开漏输出模式、高阻输入模式
● 除 P3.0 和 P3.1 外,其余所有 IO 口上电后的状态均为高阻输入状态,用户在使用 IO口时必须先设置IO口模式。另外每个 IO口均可独立使能内部 4K 上拉电阻

io工作模式的设置可以通过烧录软件进行生成
在这里插入图片描述
在这里插入图片描述
寄存器编程:直接使用寄存器
库函数编程:使用各种已经封装好的库函数进行操作

关键字(sfr/sbit)

sfr和sbit和关键字:
● 在 C51 中,sfr 和 sbit 是两个关键字,它们可以用来定义特殊功能寄存器 (SFR) 和位 (Bit)。
● SFR (Special Function Register) 即特殊功能寄存器,是单片机内部特定功能模块所对应的寄存器。例如,端口寄存器、定时器/计数器寄存器、串行口寄存器等。这些寄存器通过 sfr 关键字来定义。
● Bit 是指特定寄存器中的某一位。在 C51 中,可以用 sbit 关键字来定义一个 Bit。
● sfr 和 sbit 可以在程序中用来对单片机的特定功能寄存器和位进行访问和控制,使用起来比直接操作寄存器更加方便和直观。
示例: STC8H.H中对端口和引脚的定义
在这里插入图片描述

IO四种工作模式

IO配置示例代码

P5M1 &= ~0x08,	P5M0 &= ~0x08; //准双向口
P5M1 &= ~0x08,	P5M0 |=  0x08; //推挽输出
P5M1 |=  0x08,	P5M0 &= ~0x08; //高阻输入
P5M1 |=  0x08,	P5M0 |=  0x08; //开漏输出

IO口的工作模式:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
扩展:如何外接上拉电阻
在这里插入图片描述

IO配置有三种方式:

1.配置PnM1和PnM0

第一种是直接配置PnM1和PnM0:(比较底层和难写)
例如:控制P5端口的3号引脚,也就是P53这个引脚。
● P5表示的是5号端口
● 0x08表示的是3号引脚,对应二进制 0000 1000

P5M1 &= ~0x08,	P5M0 &= ~0x08; //准双向口
P5M1 &= ~0x08,	P5M0 |=  0x08; //推挽输出
P5M1 |=  0x08,	P5M0 &= ~0x08; //高阻输入
P5M1 |=  0x08,	P5M0 |=  0x08; //开漏输出

2.结构体配置

第二种是 结构体配置方式:(比较常用)
这种方式就是通过结构体定义,配置成员变量的方式,如果是修改端口和引脚,只需要修改 Pin和Inilize的参数的P端口
根据GPIO.h可以找到结构体声明代码
其中199-203是结构体的代码,205行是配置函数,表明需要的形参列表
在这里插入图片描述
代码层,3-5是结构体定义和赋值,7行是根据函数格式进行传参

void	GPIO_config(void)
{
	GPIO_InitTypeDef	GPIO_InitStructure;		//结构定义
	GPIO_InitStructure.Pin  = GPIO_Pin_3;		//指定要初始化的IO,
	GPIO_InitStructure.Mode = GPIO_PullUp;		//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
	
  GPIO_Inilize(GPIO_P5,&GPIO_InitStructure);	//初始化
}

例如修改成 需要初始化4.3和4.4

void	GPIO_config(void)
{
	GPIO_InitTypeDef	GPIO_InitStructure;		//结构定义
	GPIO_InitStructure.Pin  = GPIO_Pin_4 | GPIO_Pin_3;		//指定要初始化的IO,
	GPIO_InitStructure.Mode = GPIO_PullUp;		//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
	GPIO_Inilize(GPIO_P4,&GPIO_InitStructure);	//初始化
}

3.库函数配置

第三种是 库函数配置:(比较方便)
通过GPIO.h可以得到端口模式设置,方法名(Pin引脚)
使用方法:初始化P5端口的3号引脚,也就是P53这个引脚,让其IO工作模式设定为准双向口

    P5_MODE_IO_PU(GPIO_Pin_3); //方法(引脚号)

在这里插入图片描述
在这里插入图片描述

库函数

库函数是一组已经封装好的程序,提供给开发者调用使用。这些函数通常是由语言的开发者或第三方库编写的,实现了一些通用的功能,如IO、PWM、串口、Timer等,可以让开发者无需重复编写这些功能,而是直接调用库函数即可。这样可以提高开发效率、减少重复代码的编写、降低程序出错的可能性,并且可以让代码更加易于维护和扩展。许多编程语言都有自带的库函数,同时也可以通过引入第三方库来扩展其功能。

面向库函数和面向寄存器开发

  1. 简化编程难度:使用库函数可以使编程更加简单,减少编程错误的可能性。
  2. 提高可读性:库函数名字通常比寄存器名称更加直观,更容易理解。
  3. 节省时间:使用库函数可以节省编程时间,因为库函数已经被编写和测试过,可以直接调用使用,而无需重新编写和测试代码。
  4. 更加可移植:使用库函数可以增加代码的可移植性,因为库函数已经被开发和测试过,可以在不同的硬件平台上使用,而无需进行大量的修改。
  5. 更加安全:使用库函数可以减少编程错误,例如溢出、死循环等问题,从而使程序更加安全可靠。
    当然,在某些情况下,使用寄存器操作可能更加高效,例如在对时间要求比较高的嵌入式系统中,需要最大程度地减少代码运行时间。因此,要根据实际情况来选择使用库函数还是直接寄存器操作。

库函数举例

Delay.c:
延时
在这里插入图片描述
Type_def.h:
重命名一些关键字
在这里插入图片描述

常用库函数

a. Config.h Type_def.h(常用)
b. GPIO.hGPIO.c(IO口)
c. Delay.hDelay.c(延时)
d. UART.hUART.cUART_Isr.c(串口)
e. NVIC.c NVIC.h(中断)
f. Switch.h
a的两个是基本必须的头文件

delay模块延时

1.拷贝库函数中Delay.c和Delay.h到工程
2.引用头文件Delay.h

#include "Delay.h"

3.进行延时操作

delay_ms(250); // 延时250毫秒, 这里只支持1~255ms

//如果是想延时一秒,可以使用四次delay_ms(250);

凡心所向,素履以往,生如逆旅,一苇以航。

  • 17
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值