c语言T1中断程序编写步骤,用51单片机中断编写的4x4键盘程序

当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

用51单片机中断编写的4x4键盘程序

作者:未知   来源:山涧一溪流   点击数:…  更新时间:2014年06月22日   【字体:大 中 小】

应用查询扫描编写键盘程序,由于要给按键去抖动,程序变得比较复杂和冗长(详见2013年9月29日博文《MSP430和AT89C51单片机4x4键盘C程序》),如果用中断编写,设置中断响应在下降沿时执行中断,则程序编写不用去抖动判断,所以相比较要简单很多!下面用汇编和C语言两种方式编写4X4键盘程序!

一、汇编程序

ORG 0000H

LJMP MAIN

ORG 0003h

Ljmp ZD0

ORG 000Bh

LJMP TZD0

ORG 0013h

Ljmp ZD1

ORG 001Bh

LJMP TZD1

ORG 0040H

MAIN: Mov TMOD,#66h

MOV TH0,#0ffh

MOV TL0,#0ffh

MOV TH1,#0ffh

MOV TL1,#0ffh

SETB EA

SETB ET0

SETB TR0

SETB ET1

SETB TR1

SETB IT0

SETB IT1

SETB EX0

SETB EX1

xh:      mov P1,#0feh

Lcall Delay

mov P1,#0fdh

Lcall Delay

mov P1,#0fbh

Lcall Delay

mov P1,#0f7h

Lcall Delay

SJMP xh

ZD0:  JNB P1.0,dat1

JNB P1.1,dat2

JNB P1.2,dat3

JNB P1.3,dat4

dat1: mov P2,#06h  ;1

sjmp ZD0R

dat2: mov P2,#5bh  ;2

sjmp ZD0R

dat3: mov P2,#4fh  ;3

sjmp ZD0R

dat4: mov P2,#66h  ;4

ZD0R: reti

ZD1:  JNB P1.0,dat5

JNB P1.1,dat6

JNB P1.2,dat7

JNB P1.3,dat8

dat5: mov P2,#6dh  ;5 0110

sjmp ZD1R

dat6: mov P2,#7dh  ;6

sjmp ZD1R

dat7: mov P2,#07h  ;7

sjmp ZD1R

dat8: mov P2,#7fh  ;8

ZD1R: reti

TZD0: JNB P1.0,dat9

JNB P1.1,dat0

JNB P1.2,dat10

JNB P1.3,dat11

dat9:   mov P2,#6fh  ;9

sjmp ZD0R

dat0:   mov P2,#3fh  ;0

sjmp ZD0R

dat10: mov P2,#77h  ;A

sjmp ZD0R

dat11: mov P2,#7ch  ;B

TZD0R:reti

TZD1: JNB P1.0,dat12

JNB P1.1,dat13

JNB P1.2,dat14

JNB P1.3,dat15

dat12: mov P2,#39h  ;C

sjmp TZD1R

dat13:mov P2,#5eh  ;D

sjmp TZD1R

dat14:mov P2,#79h  ;E

sjmp TZD1R

dat15:mov P2,#71h  ;F

TZD1R:reti

Delay:mov r7,#10d

djnz r7,$

ret

end

462215553131556.jpg

二、C语言程序(扫描P1)

#include"reg51.h"

int yu[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

int i,j,k,time,temp,dat;

void delay(time)

{

while(time--)

for(i=0;i<120;i++);

}

void main()

{

P2=0x40;

TMOD=0x66;  //设定定时计数器T0、T1为方式2计数模式

TH0=0xFF;

TL0=0xFF;

TH1=0xFF;

TL1=0xFF;

IE=0x8F;    //开总中断和定时计数器两个中断,两个外中断

IT0=1;

IT1=1;      //设置外中断为下降沿触发

TR0=1;

TR1=1;       //打开定时计数器开始计数

while(1)

{

P1=0xfe;

delay(1);

P1=0xfd;

delay(1);

P1=0xfb;

delay(1);

P1=0xf7;

delay(1);

}

}

void intsvr0(void) interrupt 0  using 1

{

temp=P1;

switch(temp)

{

case 0xfe:key=0;break;

case 0xfd:key=1;break;

case 0xfb:key=2;break;

case 0xf7:key=3;break;

default:break;

}

P2=yu[dat];

}

void timer0(void) interrupt 1 using 1

{

temp=P1;

if(temp==0xfe)  dat=4;

if(temp==0xfd) dat=5;

if(temp==0xfb) dat=6;

if(temp==0xf7) dat=7;  P2=yu[dat];

}

void intsvr1(void) interrupt 2 using 1

{

temp=P1;

if(temp==0xfe) dat=8;

if(temp==0xfd) dat=9;

if(temp==0xfb) dat=10;

if(temp==0xf7) dat=11;

P2=yu[dat];

}

void timer1(void) interrupt 3 using 1

{

int dat;

temp=P1;

switch(temp)

{

case 0xfe:key=12;break;

case 0xfd:key=13;break;

case 0xfb:key=14;break;

case 0xf7:key=15;break;

default:break;

}

P2=yu[dat];}/*************************************************************/

三、C语言(扫描P3的P3.0、P3.1、P3.6、P3.7)

从这个程序也可以看出51单片机I/O口没有方向性,输入输出都可读写,而且在一个寄存器中。注意该程序对应电路图与上图的区别。

e79ee32f6c9e05083437f376bf2f41ba.png

#include"reg51.h"

sbit pp0=P3^0;

sbit pp1=P3^1;

sbit pp2=P3^6;

sbit pp3=P3^7;

int yu[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

int i,j,k,time,temp,dat;

void delay(time)

{

while(time--)

for(i=0;i<120;i++);

}

void main()

{

P2=0x40;

TMOD=0x66;  //设定定时计数器T0、T1为方式2计数模式

TH0=0xFF;

TL0=0xFF;

TH1=0xFF;

TL1=0xFF;

IE=0x8F;    //开总中断和定时计数器两个中断,两个外中断

IT0=1;

IT1=1;      //设置外中断为下降沿触发

TR0=1;

TR1=1;       //打开定时计数器开始计数

while(1)

{

pp0=0;

delay(5);

pp0=1;

pp1=0;

delay(5);

pp1=1;

pp2=0;

delay(5);

pp2=1;

pp3=0;

delay(5);

pp3=1;

/*以上可用下列这段代替

P3=0xfe;

delay(5);

P3=0xfd;

delay(5);

P3=0xbf;

delay(5);

P3=0x7f;

delay(5);*/

}

}

void intsvr0(void) interrupt 0  using 1

{

temp=P3;

switch(temp)

{

case 0xfa:dat=0;break;

case 0xf9:dat=1;break;

case 0xbb:dat=2;break;

case 0x7b:dat=3;break;

default: break;

}

P2=yu[dat];

}

void timer0(void) interrupt 1 using 1

{

temp=P3;

if(temp==0xee) dat=8;

if(temp==0xed) dat=9;

if(temp==0xaf) dat=10;

if(temp==0x6f) dat=11;

P2=yu[dat];

}

void intsvr1(void) interrupt 2 using 3

{

temp=P3;

if(temp==0xf6) dat=4;

if(temp==0xf5) dat=5;

if(temp==0xb7) dat=6;

if(temp==0x77) dat=7;

P2=yu[dat];

}

void timer1(void) interrupt 3 using 1

{

int dat;

temp=P3;

switch(temp)

{

case 0xde:dat=12;break;

case 0xdd:dat=13;break;

case 0x9f:dat=14;break;

case 0x5f:dat=15;break;

default: break;

}

P2=yu[dat];

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值