完成一些基础实验后,继续深入,了解其特性和一些特别的IO口控制技巧,(删除线)不深不浅、不大不小,又沉又重又便宜又实惠又太贵的AIPC。
一.外部中断
关于外部中断,有如下信息;
1.AT89s51的中断源信息:
外部中断int0-中断标志IE0
定时计数器0 T0-中断标志IF0
外部中断int1-中断标志IE1
定时计数器1 T1-中断标志IF1
2.中断请求的开放和关闭
AT89s51的中断允许寄存器IE
特点:8为,可位寻址,复位内容为00H
作用:控制中断源申请的开放和关闭
3.IE寄存器信息
EA | -- | -- | ES | ET1 |EX1 |ET0 |EX0
EX0:外部中断0请求允许位
ET0:定时计数0中断请求允许位
EX1:外部中断1请求允许位
ET1:定时计数1中断请求允许位
ES:串行口中断请求允许位
EA:中断请求允许总控制位
4.外部中断源
外部中断0:端口引脚为12(P3.2),引脚符号为INT0^
外部中断1:端口引脚为13(P3.3),引脚符号为INT1^
5.外部中断请求方式
负边沿出发,IT0=1
低电平触发,IT1=0
实验:使用外部中断1(独立开关)实现led灯亮灭
#include <reg51.h>
sbit key = P3^2;
sbit led1 = P1^0;
int count ;
int time_counter ;
void Delay_ms(unsigned int xms)
{
unsigned int i , j ;
for(i = xms ;i>0 ;i--)
for(j = 118; j>0 ;j--);
}
void main()
{
TCON |= 0x01; // ϽµÑØÓÐЧ
IE = 0x81; // IE= 1000 0001
}
void ext_int0() interrupt 0
{
Delay_ms(100);
if(key == 0)
{
led1 = ~led1 ;
}
Delay_ms(10);
while(!key);
}
二.综合运用:制作码表
这次为利用单片机系统的综合实验
首先进行需求分析
1.可以计时
2.码表有最小显示市场
3.有最大计数时间
4.可以存储时间
5.按键实现 开始复位存储回县
构成
1.51单片机最小系统(包括电源复位电路晶振电路下载器和单片机ic)
2.显示电路
3.按键电路
接下来对数码管分位、io口设计和按键功能指定。
程序设计
1.定义端口(LED显示端口,定义按键输入端口)
2.硬件资源的初始化(初始化定时计数器,初始化显示器,初始化按键)
3.功能初始化
码表工作状态划分 : a等待b计数c存储
4.等待状态(在此回显数据)
5.计数状态
6.存贮状态
一些需求:
等待状态,回显可以,定时器不工作
计数状态,定时器工作,LED激活计数
存储状态,一种暂态,存储5个
代码段:
#include <reg52.h>
/*快速定义*/
typedef unsigned char u8;
typedef unsigned int u16;
/*快速定义*/
sbit LED0 = P2^3;
sbit LED1 = P2^2;
sbit LED2 = P2^1;
sbit LED3 = P2^0;
sbit start = P3^2;
sbit out = P3^3;
sbit reset = P3^4 ;
sbit save = P3^5 ;
/*中间全局变量*/
u8 run_flag; //新建计数工作标志位
u8 temp[5][8];
u8 counter;
u8 n10ms,nsec,nmin;
unsigned code leddata[]={
0xC0, //"0"
0xF9, //"1"
0xA4, //"2"
0xB0, //"3"
0x99, //"4"
0x92, //"5"
0x82, //"6"
0xF8, //"7"
0x80, //"8"
0x90, //"9"
0x88, //"A"
0x83, //"B"
0xC6, //"C"
0xA1, //"D"
0x86, //"E"
0x8E, //"F"
0x89, //"H"
0xC7, //"L"
0xC8, //"n"
0xC1, //"u"
0x8C, //"P"
0xA3, //"o"
0xBF, //"-"
0xFF, //熄灭
0xA4 //自定义
};
void Delay_ms(unsigned int xms)
{
unsigned int i , j ;
for(i = xms ;i>0 ;i--)
for(j = 118; j>0 ;j--);
}
void display_led(unsigned char Num, unsigned char Data)
{ switch(Num)
{ case 0:
LED0=0;
P0=leddata[Data];
Delay_ms(2);
LED0=1; Delay_ms(2);
break;
case 1:
LED1=0;
P0=leddata[Data];
Delay_ms(2);
LED1=1; Delay_ms(2);
break;
case 2:
LED2=0;
P0=leddata[Data];
Delay_ms(2);
LED2=1; Delay_ms(2);
break;
case 3:
LED3=0;
P0=leddata[Data];
Delay_ms(2);
LED3=1; Delay_ms(2);
break;
}
}
void display(u8 which_bit,u8 which_number)
{
u8 x,y;
x = which_number/10;
y = which_number%10;
if(which_bit==1)
{
display_led(0,y);
}
if(which_bit==2)
{
display_led(1,y);
Delay_ms(1);
display_led(2,x);
Delay_ms(1);
}
if(which_bit==3)
{
display_led(3,y);
}
}
void reflash()
{
display(1,n10ms);
display(2,nsec);
display(3,nmin);
}
void keyscan()
{
if(start == 0)
{
Delay_ms(5);
if(start == 0)
{
run_flag =~run_flag ;
}
while(!start);
}
if(reset == 0)
{
Delay_ms(5);
if(reset == 0 && run_flag==0)
{
n10ms=0;
nmin=0;
nsec=0;
counter=0;
}
while(!reset);
}
if(save == 0)
{
Delay_ms(5);
if(save == 0 && counter < 5)
{
temp[counter][0]=n10ms;
temp[counter][2]=nmin;
temp[counter][1]=nsec;
counter++;
}
while(!save);
}
if(run_flag)
{
TR0 = 1; //开始计数
}
else if(!run_flag)
{
TR0 = 0;
if(out == 0)
{
Delay_ms(5);
if (out == 0)
{
counter --;
n10ms = temp[counter][0];
nsec = temp[counter][1];
nmin = temp[counter][2];
}while(!out);
}
}}
void main()
{
TMOD =0x01 ; //定时T0
TH0 =(65535 - 10000) / 256 ; //10ms
TL0 =(65535 - 10000) % 256 ;
EA = 1 ; //开放总中断
ET0 = 1 ;//开放定时器0的溢出中断
// TR0 = 1 ;//开始计时
while(1)
{
keyscan();
reflash();
}
}
void t0_server() interrupt 1
{
TH0 =(65535 - 10000) / 256 ;
TL0 =(65535 - 10000) % 256 ;
n10ms++;
if(n10ms>=100)
{
n10ms=0;
nsec++;
if(nsec>=60)
{
nsec=0;
nmin++;
if(nmin>=10)
nmin=0;
}
}
}
自此,内部资源实验全部结束
每次蜜汁错误!搞个小实验也很麻烦...