独立按键原理
一般情况下,独立按键有两个引脚,其中一个通过上拉电阻接到单片机的I/O端口,另外一端接地。也就是说,平时按键没有动作的时候,输出的是高电平,如果有按下动作发生,则输出的是低电平。那么,我们在程序设计的时候,只要扫描跟按键引脚相连的I/O端口,如果发现有低电平产生,则判定该按键处于按下状态。有些时候,电路或者外围有电磁干扰,也会使单片机的I/O端口产生低电平,这种干扰信号会让单片机误认为是按键动作。所以,在扫描按键的时候应该做去抖动处理,把干扰信号过滤掉,从而获得准确的按键状态信号。
原理图:
在CT107D单片机上,首先将J5处的跳帽接到2-3引脚(即接BTN),使按键S4~S7四个按键的另外一端接地(GND)从而成为4个独立键盘。在扫描按键的过程中,发现有按键触发信号后,先做去抖动处理,当确认为按键按下时(
while (P30==0);
),待按键松开后,在数码管的最右边一位显示相应的数字:按键S7显示数字7,S6显示数字6,S5显示数字5,S4显示数字4。
独立按键扫描显示
代码:
#include <reg52.h> //引用芯片头文件
#include "intrins.h" //延时函数所需要的头文件
sbit P30 = P3^0;
sbit P31 = P3^1;
sbit P32 = P3^2;
sbit P33 = P3^3; //独立按键对应的IO口引脚定义
unsigned char button=0;
void key4(void);
void Delay10ms();
void Delay10ms();
void close_buzz(void);
void Display(long int number);
void Digital_Tube(unsigned char Position, unsigned char Typeface);
void Delay10ms() //@12.000MHz
{
unsigned char i, j;
i = 117;
j = 184;
do
{
while (--j)
;
} while (--i);
}
//Description: // 关闭外设
void close_buzz(void)
{
P2 = ((P2 & 0x1f) | 0xa0); //关闭Y5控制的全部外设
P0 = 0x00;
P2 &= 0x1f;
P2 = (P2 & 0x1f) | 0x80; //同理关闭LED
P0 = 0xff;
P2 &= 0x1f;
}
//按键扫描,利用延时函数进行了消抖
void key4(void)
{
if(P30==0)
{
Delay10ms(); //消抖
if (P30==0)
{
while (P30==0);
button= 7;
}
}
if(P31==0)
{
Delay10ms();
if (P31==0)
{
while (P31==0);
button= 6;
}
}
if(P32==0)
{
Delay10ms();
if (P32==0)
{
while (P32==0);
button= 5;
}
}
if(P33==0)
{
Delay10ms();
if (P33==0)
{
while (P33==0);
button= 4;
}
}
}
void main()
{
close_buzz(); //关闭外设
while(1)
{
key4(); //按键扫描
if(button!=0)
{
Display(button); //数码管显示对应的值
}
}
}
void Digital_Tube(unsigned char Position,unsigned char Typeface) //Position是数码管第几位(从左到右,0开始),Typeface是显示的字样
{
unsigned char Bit[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
unsigned char SMG_NoDot[19] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f,0xff}; //0-9、A-F、'-'、'.'
P2 = P2 & 0x1f | 0xc0;
P0=Bit[Position];
P2 = P2 & 0x1f | 0xe0;
P0=SMG_NoDot[Typeface];
Delay10ms();
P0=0XFF;
P2 = P2 & 0x1f ; //数码管消影
}
void Display(long int number)
{
long int i,a,b;
for(i=0;i<8;i++)
{
a=number%10;
Digital_Tube(7-i,a);
Delay10ms();
b=number/10;
if(b==0) break;
number=b;
}
}
51单片机的中断系统
中断系统简介
当中央处理机CPU正在处理某件事的时候外界发生了紧急事件请求,要求CPU暂停当前的工作,转而去处理这个紧急事件,处理完以后,再回到原来被中断的地方,继续原来的工作,这样的过程称为中断。实现这种功能的部件称为中断系统,请示CPU中断的请求源称为中断源。

中断源
STC15F2K60S2系列单片机提供了14个中断请求源,按照优先级排序它们分别是:外部中断0(INT0)、定时器0中断、外部中断1(INT1)、定时器1中断、串口1中断、A/D转换中断、低压检测(LVD)中断、CCP/PWM/PCA中断、串口2中断、SPI中断、外部中断2(INT2)、外部中断3(INT3),定时器2中断以及外部中断4(INT4)。除外部中断2(INT2)、外部中断3(INT3)、定时器2中断及外部中断4(INT4)。
4个外部中断中根据原理图我们只能使用两个外部中断源:INT0与INT1;
外部中断0(INT0)和外部中断1(INT1)既可上升沿触发,又可下降沿触发。外部中断2(INT2)、外部中断3(INT3)及外部中断4(INT4)都只能下降沿触发。(外部中断2~4的中断请求标志位被隐藏起来了,对用户不可见。)
中断优先级(中断嵌套)
当CPU正在处理一个中断源请求的时候(执行相应的中断服务程序),发生了另外一个优先级比它还高的中断源请求。如果CPU能够暂停对原来中断源的服务程序,转而去处理优先级更高的中断请求源,处理完以后,再回到原低级中断服务程序,这样的过程称为中断嵌套。

中断优先级次序如下,其中 中断序号0的优先级最高
void Int0_Routine(void) interrupt 0;
void Timer0_Rountine(void) interrupt 1;
void Int1_Routine(void) interrupt 2;
void Timer1_Rountine(void) interrupt 3;
void UART1_Routine(void) interrupt 4;
void ADC_Routine(void) interrupt 5;
void LVD_Routine(void) interrupt 6;
void PCA_Routine(void) interrupt 7;
void UART2_Routine(void) interrupt 8;
void SPI_Routine(void) interrupt 9;
void Int2_Routine(void) interrupt 10;
void Int3_Routine(void) interrupt 11;
void Timer2_Routine(void) interrupt 12;
void Int4_Routine(void) interrupt 16;
中断相关寄存器
符号 | 描述 | 地址 | 位地址及符号 | 复位值 | |||||||
MSB | LSB | ||||||||||
IE | Interrupt Enable | A8H | EA | - - | ET2 | ES | ET1 | EX1 | ET0 | EX0 | 0x00 0000B |
IP | Interrupt Priority Low | B8H | - - | - - | PT2 | PS | PT1 | PX1 | PT0 | PX0 | xx00 0000B |
IPH | Interrupt Priority High | B7H | PX3H | PX2H | PT2H | PSH | PT1H | PX1H | PT0H | PX0H | 0000,0000B |
TCON | Timer/Counter 0 and 1Control | 88H | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 | 0000 0000B |
SCON | Serial Control | 98H | SM0/FE | SM1 | SM2 | REN | TB8 | RB8 | TI | RI | 0000 0000B |
T2CON | Timer/Counter 2 Control | C8H | TF2 | EXF2 | RCLK | TCLK | EXEN2 | TR2 | C/T2 | CP/RL2 | 0000 0000B |
XICON | Auxiliary Interupt Control | C0H | PX3 | EX3 | IE3 | IT3 | PX2 | EX2 | IE2 | IT2 | 0000 0000B |
外部中断需要使用的寄存器<来自于STC89C51的开发指南>
中断控制允许寄存器IE
中断允许寄存器IE是只有打开全局开关,其它各位的开关才可以开启!!!!!!!!每个位开关赋值为1则开,赋值为0则关。
SFR name | Address | bit | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
---|---|---|---|---|---|---|---|---|---|---|
IE | A8H | name | EA | - | ET2 | ES | ET1 | EX1 | ET0 | EX0 |
EA : CPU的总中断允许控制位,EA=1,CPU开放中断,EA=0,CPU屏蔽所有的中断申请。EA的作用是使中断允许形成两级控制。即各中断源首先受EA控制;其次还受各中断源自己的中断允许控制位控制。
ET2: 定时/计数器T2的溢出中断允许位。ET2=1,允许T2中断;ET2=0,禁止T2中断。
ES : 串行口1中断允许位。ES=1,允许串行口1中断;ES=0,禁止串行口1中断。
ET1 : 定时/计数器T1的溢出中断允许位。ET1=1,允许T1中断;ET1=0,禁止T1中断。
EX1 : 外部中断1中断允许位。EX1=1,允许外部中断1中断;EX1=0,禁止外部中断1中断。
ET0 : T0的溢出中断允许位。ET0=1,允许T0中断;ET0=0禁止T0中断。
EX0 : 外部中断0中断允许位。EX0=1,允许中断;EX0=0禁止中断。
使用的两种方法:
- 整体赋值(十六进制赋值)
IE=0x81; //( 开启全局中断,打开外部中断0)
- 单独赋值
EA=1;EX0=1; //(开启全局中断,打开外部中断0)
外部中断相关的寄存器TCON
外部中断0(INT0)、外部中断1(INT1)有两种触发方式,下降沿触发方式和低电平触发方式。
请求外部中断的标志位是位于寄存器TCON中的IE0/TCON.1、IE1/TCON.3。当外部中断服务程序被响应后,中断请求标志位IE0和IE1会自动被清0。TCON寄存器中的IT0/TCON.0、IT1/TCON.2决定了外部中断0和1是低电平触发方式还是下降沿触发方式。如果ITx = 0(x = 0,1),那么系统在INTx(x = 0,1)脚探测到低电平后可产生外部中断。如果ITx = 1(x = 0,1),那么系统在INTx( x= 0,1,2,3)脚探测下降沿后可产生外部中断。
SFR name | Address | bit | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
---|---|---|---|---|---|---|---|---|---|---|
TCON | 88H | name | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
TF1: T1溢出中断标志。T1被允许计数以后,从初值开始加1计数。当产生溢出时由硬件置“1”TF1,向CPU请求中断,一直保持到CPU响应中断时,才由硬件清“0”(也可由查询软件清“0”)。
TR1: 定时器1的运行控制位。
TF0: T0溢出中断标志。T0被允许计数以后,从初值开始加1计数,当产生溢出时,由硬件置“1”TF0,向CPU请求中断,一直保持CPU响应该中断时,才由硬件清0(也可由查询软件清0)。
TR0: 定时器0的运行控制位。
IE1: 外部中断1请求源(INT1/P3.3)标志。IE1=1,外部中断向CPU请求中断,当CPU响应该中断时由硬件清“0”IE1。
IT1: 外部中断1中断源类型选择位。IT1=0,INT1/P3.3引脚上的低电平信号可触发外部中断1。IT1=1,外部中断1为下降沿触发方式。
IE0: 外部中断0请求源(INT0/P3.2)标志。IE0=1外部中断0向CPU请求中断,当CPU响应外部中断时,由硬件清“0”IE0(边沿触发方式)。
IT0: 外部中断0中断源类型选择位。IT0=0,INT0/P3.2引脚上的低电平可触发外部中断0。IT0=1,外部中断0为下降沿触发方式。
中断处理函数的编写
- 中断初始化函数
初始化函数就是一个普通的函数,将总中断控制寄存器以及我们需要的中断源进行初始化。
例如外部中断0的初始化函数:
void Init_INT0() //外部中断0,对应按键S5
{
IT0 = 1; //外部中断0触发方式控制位(0:低电平触发;1:下降沿触发)
EX0 = 1; //外部中断0使能开启
EA = 1; // 总中断使能开启
}
- 中断服务函数
注意!!:
- 中断函数没有返回值,也不能带参数。
- 函数名后面要跟一个关键字interrupt,说明这是一个中断服务函数。
- 在关键字interrupt后面要跟上中断号,说明这个中断服务函数是为那个中断服务的。
中断服务函数的格式为:
void 函数名() interrupt 中断号
{
----函数体----
}
例如在中断函数中进行数值的自增:
void SeviceINT0() interrupt 0
{
date++;
}
外部中断0显示按键被按次数
代码:
#include <reg52.h> //引用芯片头文件
#include "intrins.h" //延时函数所需要的头文件
unsigned char date = 0;
void working();
void Delay500us();
void Delay50ms();
void Init_INT0();
void close_buzz(void);
void Display(long int number);
void Digital_Tube(unsigned char Position, unsigned char Typeface);
void Delay500us() //@12.000MHz
{
unsigned char i, j;
i = 6;
j = 211;
do
{
while (--j)
;
} while (--i);
}
//Description: // 关闭外设
void close_buzz(void)
{
P2 = ((P2 & 0x1f) | 0xa0); //关闭Y5控制的全部外设
P0 = 0x00;
P2 &= 0x1f;
P2 = (P2 & 0x1f) | 0x80; //同理关闭LED
P0 = 0xff;
P2 &= 0x1f;
}
void Digital_Tube(unsigned char Position,unsigned char Typeface) //Position是数码管第几位(从左到右,0开始),Typeface是显示的字样
{
unsigned char Bit[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
unsigned char SMG_NoDot[19] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f,0xff}; //0-9、A-F、'-'、'.'
P2 = P2 & 0x1f | 0xc0;
P0=Bit[Position];
P2 = P2 & 0x1f | 0xe0;
P0=SMG_NoDot[Typeface];
Delay500us();
P0=0XFF;
P2 = P2 & 0x1f ; //数码管消影
}
void Display(long int number)
{
long int i, a, b;
for (i = 0; i < 8; i++)
{
a = number % 10;
Digital_Tube(7 - i, a);
b = number / 10;
if (b == 0)
break;
number = b;
}
}
void main()
{
close_buzz();
Init_INT0();
while (1)
{
Display(date);
}
}
/*===============初始化==================*/
void Init_INT0() //外部中断0,对应按键S5
{
IT0 = 1; //外部中断0触发方式控制位(0:低电平触发;1:下降沿触发)
EX0 = 1; //外部中断0使能开启
EA = 1; // 总中断使能开启
}
/*============中断服务函数===============*/
void SeviceINT0() interrupt 0
{
date++;
}
最后
以上就是高高书包最近收集整理的关于蓝桥杯单片机之独立按键+外部中断的全部内容,更多相关蓝桥杯单片机之独立按键+外部中断内容请搜索靠谱客的其他文章。
发表评论 取消回复