完成一些基础实验后,继续深入,了解其特性和一些特别的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; } } }
自此,内部资源实验全部结束
每次蜜汁错误!搞个小实验也很麻烦...