GPIO  General Purpose Input/Output  

通用目的输入/输出

GPIO输出模式:给定单片机引脚电平,控制引脚输出高/低电平(LED控制、数码管控制、蜂鸣器控制)

GPIO输入模式:检测引脚电平变化(用于检测外部电平信号 按键检测、检测ADC信号)

起始信号:500ms高电平  40us低电平(GPIO输出)

接收传感器(检测DATA信号新 电平 GPIO输入)

独立按键

按键一端接到GND,另外一端接到GPIO引脚

如果按键被按下,GND会和引脚短路到一起,此时引脚呈现低电平,代表按键被按下

//按键初始化
void key_init(void)
{
	P1 |=(0x0F << 4); // P1 | 1111 0000
}

//按键检测
int key_press(void)
{
	int ret = 0;
	
	if((P1 & (1 << 4)) == 0)
	{
		ret = 1;
	}
	else if(P1 & (1 << 5) == 0)
	{
		ret = 2;
	}
	else if(P1 & (1 << 6) == 0)
	{
		ret = 3;
	}
	else if(P1 & (1 << 7) == 0)
	{
		ret = 4;
	}
	else 
	{
		ret = 0;
	}
	return ret;
}

中断

中断:CPU在处理某个任务时,被外界更为紧急的事件打断,要求CPU优先去处理 这个更为紧急的事件;处理完紧急事件后,再回到之前被打断的地方继续向下执行

中断源:打断CPU执行当前的任务源头/事件

(51单片机)中断源分类:外部中断0、外部中断1、定时器0、定时器1、串口

外部中断引脚电平变化所引发的中断

INT0(外部中断0):P3_2引脚;INT1(外部中断1):P3_3引脚

中断优先级:CPU总是先处理优先级高的中断,处理完优先级高的中断之后再处理优先级低的中断(数字越小优先级越高)

中断嵌套:CPU处理一个中断时再去嵌套另一个中断任务(最多两层嵌套)

中断处理流程(中断源->CPU过程):

中断源发出中断请求;

检查CPU是否允许中断(总开关,能够响应外部中断)及该中断源是否被屏蔽(子开关,能够产生中断)

比较中断优先级

保护现场

执行中断服务函数(回调函数)

恢复现场

中断向量表:本质是一个数组,数组中存的是中断服务函数的入口地址

中断向量:中断向量表中的标号,通过标号可以访问到对应中断服务函数

外部中断0的配置流程

1. 将外部中断0引脚拉高
2. 设置外部中断0引脚中断触发方式:下降沿触发   TCON寄存器中bit0置1  TCON |=(1<<0);
3. 将外部中断0中断打开(bit0)  允许CPU响应中断(bit7)
lE寄存器中的bit7和bit0置1
IE|=(1<<0);
IE|=(1<<7);

unsigned int g_i = 0;
//外部中断函数
void int0_handler(void) interrupt 0
{
	g_i++;
}
//外部中断初始化
void init0_init(void)
{
	//1.将外部中断0引脚拉高
	P3 |= (1 << 2);
	
	//2.配置外部中断0引脚中断触发方式;下降沿触发
	TCON |= (1 << 0);
	
	//3.允许外部中断0产生中断
	IE |= (1 << 0);
	
	//4.允许CPU响应所有中断
	IE |= (1 << 7);
}

定时器模块

定时器:实现精准的定时,外设对时序要求比较高

51单片机中的定时器:定时器0   定时器1

定时器工作模式

16位定时器/计数器,TL0、TH0全用

8位自动重装载定时器,当溢出时将TH0存放的值自动重装入TL0

13位定时器/计数器,兼容8048模式,TL0只用低5位参与分频,TH0整个8位全用

定时器配置流程

1. 赋初值:cnt = 64535

2. 打开计数器,开始计数

3. 按照固定的频率++

4. 计数器加到65535+1->溢出->CPU定时器中断请求

实例:实现1ms的精准定时   (计算其初值)

(1)晶振频率:12MHZ 11.0592MHZ(本51单片机采用的12MHZ) 

(2)51单片机实际工作频率(12分频)、固定频率:12MHZ / 12 = 1MHZ  

时间:1 / 1MHZ = 1us 1 / 0.9MHZ = 1.1us

(3)1ms定时:1ms = 1000us

计数次数:1000us / 1us = 1000

(4)定时器初值:65535 - 1000 = 64535


//定时器0服务函数
void timer0_handler(void)  interrupt 1
{
	TH0 = g_t >> 8;//手动重装载
	TL0 = g_t;
	g_t++;
	if(g_t >= 1000)
	{
		led_nor();
		g_t = 0;
	}
}

// 定时器0初始化
void timer0_init(void)
{
	//1.配置定时器0工作模式,16位定时器
	TMOD &= ~(0x0F << 0);
	TMOD |= (1 << 0);
	
	//2.设置定时器0初值
	TH0 = g_t >> 8;
	TL0 = g_t;
	
	//3.打开定时器0,开始计数
	TCON |= (1 << 4);
	
	//4.开启定时器0中断
	IE |= (1 << 1);
	
	//5.开启CPU总中断
	IE |= (1 << 7);
}

PWM周期

脉冲宽度调制:能够让引脚产生一个方波,能够让引脚周期性产生电平变化

PWM周期:一个方波所经历的周期(上升沿/下降沿到下一个上升沿/下降沿所经历的时间)

PWM占空比:在一个周期内高电平所占的比例(LCD屏幕亮度调节、LED灯亮度调节、蜂鸣器)

蜂鸣器

有源蜂鸣器:内部存在震荡源,通电后可以发出持续固定频率的声音

无源蜂鸣器:不存在震荡器,需要给定对应引脚一个高低电平产生震荡(可以输出指定频率音调


 

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐