嵌入式-51单片机1
3.1 80C51的中断系统
3.1.1 80C51的中断系统结构
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
//控制显示什么数字
sbit duan_xuan=P2^6;
//控制哪个数码管显示
sbit wei_xuan=P2^7;
sbit d1=P1^0;
uchar code table[]={0x3f,0x06,0x5b,0x4f};
uchar num;
void delay(uint z);
void main()
{
EA=1;//开总中断
EX0=1;//开外部中断0
IT0=1;//跳变沿
wei_xuan=1;
P0=0xc0;
wei_xuan=0;
while(1)
{
for(num=0;num<4;num++)
{
d1=1;
duan_xuan=1;
P0=table[num];
duan_xuan=0;
delay(1000);
}
}
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void exter0() interrupt 0
{
d1=0;
}
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
//控制显示什么数字
sbit duan_xuan=P2^6;
//控制哪个数码管显示
sbit wei_xuan=P2^7;
sbit d1=P1^0;
uchar code table[]={0x3f,0x06,0x5b,0x4f};
uchar num tt;
void delay(uint z);
void main()
{
tt=0;
TM0D=0x01; //设置定时器0为工作方式1
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;//开总中断
ET0=1;//开定时器中断
TR0=1;//启动定时器0
wei_xuan=1;
P0=0xc0;
wei_xuan=0;
while(1)
{
if(tt==20)
{
tt=0;
num++;
d1=1;
duan_xuan=1;
P0=table[num];
duan_xuan=0;
delay(1000);
}
}
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void times0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
tt++;
}
定时器0以500ms速度进行流水灯:
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar temp,t0;
void init();
void main()
{
init();
while(1)
{
}
}
void init()
{
temp=0xfe;
//点亮第一个二极管
P1=temp;
//设置两个定时器,定时器工作方式
TMOD=0x11;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
//开总中断
EA=1;
//开定时器0中断
ET0=1;
//启动定时器
TR0=1;
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
t0++;
if(t0==10)
{
t0=1;
temp=_crol_(temp,1);
P1=temp;
}
}
减到398,流水灯停止:
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar temp,t0,t1;
uint shu;
sbit dula=P2^6;
sbit wela=P2^7;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
uchar bai,shi,ge;
uchar j,k;
void init();
void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f);
void delay(uchar i);
void main()
{
init();
while(1)
{
display(7,6,5,bai,shi,ge);
}
}
void init()
{
shu=432;
temp=0xfe;
//点亮第一个二极管
P1=temp;
//设置两个定时器,定时器工作方式
TMOD=0x11;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
//开总中断
EA=1;
//开定时器0中断
ET0=1;
//启动定时器0
TR0=1;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
//开定时器1中断
ET1=1;
//启动定时器1
TR1=1;
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
t0++;
if(t0==10)
{
t0=1;
temp=_crol_(temp,1);
P1=temp;
}
}
void timer1() interrupt 3
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
t1++;
//100ms t1*50ms
if(t1==2)
{
t1=0;
shu--;
bai=shu/100;
shi=shu%100/10;
ge=shu%10;
if(shu==398)
{
TR0=0;
TR1=0;
}
}
}
//数码管显示子程序
void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f)
{
dula=0;
P0=table[a];
dula=1;
dula=0;
wela=0;
P0=0xfe;
wela=1;
wela=0;
delay(5);
P0=table[b];
dula=1;
dula=0;
P0=0xfd;
wela=1;
wela=0;
delay(5);
P0=table[c];
dula=1;
dula=0;
P0=0xfb;
wela=1;
wela=0;
delay(5);
P0=table[d];
dula=1;
dula=0;
P0=0xf7;
wela=1;
wela=0;
delay(5);
P0=table[e];
dula=1;
dula=0;
P0=0xef;
wela=1;
wela=0;
delay(5);
P0=table[f];
dula=1;
dula=0;
P0=0xdf;
wela=1;
wela=0;
delay(5);
}
void delay(uchar i)
{
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
完整代码:
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar temp,t0,t1;
uint shu;
sbit dula=P2^6;
sbit wela=P2^7;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,
0x76,0x79,0x38,0x3f,0x00};
uchar bai,shi,ge,flag,flag1;
uchar j,k;
void init();
void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f);
void delay(uchar i);
void main()
{
init();
while(1)
{
if(flag1!=1)
{
display(7,6,5,bai,shi,ge);
}
else
{
display(16,17,18,19,19,20);
}
}
}
void init()
{
shu=432;
temp=0xfe;
//点亮第一个二极管
P1=temp;
//设置两个定时器,定时器工作方式
TMOD=0x11;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
//开总中断
EA=1;
//开定时器0中断
ET0=1;
//启动定时器0
TR0=1;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
//开定时器1中断
ET1=1;
//启动定时器1
TR1=1;
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
t0++;
if(flag!=1)
{
if(t0==10)
{
t0=0;
temp=_crol_(temp,1);
P1=temp;
}
}
else
{
//每200ms执行
if(t0%4==0)
{
P1=~P1;
}
if(t0==60)
{
TR0=0;
P1=0xff;
flag1=1;
}
}
}
void timer1() interrupt 3
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
t1++;
//100ms t1*50ms
if(t1==2)
{
t1=0;
shu--;
bai=shu/100;
shi=shu%100/10;
ge=shu%10;
if(shu==398)
{
TR0=0;
P1=0xff;
//timer0 清零
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
//重新启动定时器
TR0=1;
flag=1;
t0=0;
TR1=0;
}
}
}
//数码管显示子程序
void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f)
{
dula=0;
P0=table[a];
dula=1;
dula=0;
wela=0;
P0=0xfe;
wela=1;
wela=0;
delay(5);
P0=table[b];
dula=1;
dula=0;
P0=0xfd;
wela=1;
wela=0;
delay(5);
P0=table[c];
dula=1;
dula=0;
P0=0xfb;
wela=1;
wela=0;
delay(5);
P0=table[d];
dula=1;
dula=0;
P0=0xf7;
wela=1;
wela=0;
delay(5);
P0=table[e];
dula=1;
dula=0;
P0=0xef;
wela=1;
wela=0;
delay(5);
P0=table[f];
dula=1;
dula=0;
P0=0xdf;
wela=1;
wela=0;
delay(5);
}
void delay(uchar i)
{
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
非编码键盘有分为:独立键盘和行列式(又称为矩阵式)键盘。
按下时点亮led,松开时熄灭
#include<reg52.h>
sbit d1=P1^0;
sbit key1=P3^4;
void main()
{
//监听输入时,必须将口置位高
P3=0xff;
while(1)
{
if(key1==0)
{
d1=0;
}
else
{
d1=1;
}
}
}
按一下数字加1:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit d1=P1^0;
sbit key1=P3^4;
sbit dula=P2^6;
sbit wela=P2^7;
uchar num;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,
0x76,0x79,0x38,0x3f,0x00};
void main()
{
wela=1;
P0=0xfe;
wela=0;
P3=0xff;
num=0;
while(1)
{
if(key1==0)
{
num++;
d1=0;
if(num==10)
num=0;
}
else
{
d1=1;
}
dula=1;
P0=table[num];
dula=0;
}
}
问题:按键按下去,一直在加1,数字无法固定
独立键盘-完整的按键延时去抖动程序:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit d1=P1^0;
sbit key1=P3^4;
sbit dula=P2^6;
sbit wela=P2^7;
uchar num,j,k;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,
0x76,0x79,0x38,0x3f,0x00};
void delay(uchar i);
void main()
{
wela=1;
P0=0xfe;
wela=0;
P3=0xff;
num=0;
while(1)
{
if(key1==0)
{
//消除抖动
delay(10);
if(key1==0)
{
num++;
d1=0;
if(num==10)
num=0;
}
//松手检测,如果0,死循环
while(!key1);
delay(10);
while(!key1);
}
else
{
d1=1;
}
dula=1;
P0=table[num];
dula=0;
}
}
void delay(uchar i)
{
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
矩阵键盘:未完全实现,只能点亮一行
/*
矩阵键盘
*/
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;
sbit wela=P2^7;
unsigned char code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x00};
uchar j,k,temp,num;
void delay(uchar);
void main()
{
//初始化时段选0
dula=1;
P0=0;
dula=0;
wela=1;//位选打开
P0=0xc0;//打开所有数码管
wela=0;//位选关闭
while(1)
{
//第1行按键
P3=0xfe;//将所有口置高
temp=P3;//读取当前P3状态
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(10);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xee:
num=0;
break;
case 0xde:
num=1;
break;
case 0xbe:
num=2;
break;
case 0x7e:
num=3;
break;
}
//松手检测
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
dula=1;
P0=table[num];
dula=0;
}
}
//第2行按键
P3=0xfd;//将所有口置高 11111101
temp=P3;//读取当前P3状态
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(10);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xed:
num=4;
break;
case 0xdd:
num=5;
break;
case 0xbd:
num=6;
break;
case 0x7d:
num=7;
break;
}
dula=1;
P0=table[num];
dula=0;
}
}
//第3行按键
P3=0xfb;//将所有口置高 11111101
temp=P3;//读取当前P3状态
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(10);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xeb:
num=8;
break;
case 0xdb:
num=9;
break;
case 0xbb:
num=10;
break;
case 0x7b:
num=11;
break;
}
dula=1;
P0=table[num];
dula=0;
}
}
//第4行按键
P3=0xf7;//将所有口置高 11111101
temp=P3;//读取当前P3状态
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(10);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xe7:
num=12;
break;
case 0xd7:
num=13;
break;
case 0xb7:
num=14;
break;
case 0x77:
num=15;
break;
}
dula=1;
P0=table[num];
dula=0;
}
}
}
}
void delay(uchar i)
{
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}