嵌入式-51单片机1

3.1 80C51的中断系统
3.1.1 80C51的中断系统结构
嵌入式-51单片机1
嵌入式-51单片机1
嵌入式-51单片机1
嵌入式-51单片机1
嵌入式-51单片机1
嵌入式-51单片机1
嵌入式-51单片机1
嵌入式-51单片机1

#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;
}

嵌入式-51单片机1
嵌入式-51单片机1
嵌入式-51单片机1
嵌入式-51单片机1
嵌入式-51单片机1
嵌入式-51单片机1
嵌入式-51单片机1

#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++;
}

嵌入式-51单片机1

定时器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--);
}

嵌入式-51单片机1
非编码键盘有分为:独立键盘和行列式(又称为矩阵式)键盘。

嵌入式-51单片机1
嵌入式-51单片机1

按下时点亮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;
		}	
	}
}

嵌入式-51单片机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--);
}

嵌入式-51单片机1
嵌入式-51单片机1

矩阵键盘:未完全实现,只能点亮一行
/*
矩阵键盘
*/
#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--);
}