用外部中断0和外部中断1实现:1个七段LED数码管显示值加1和减1#include <REGX51.H>#define LED_SELECT P2#define LED_DATA P0unsigned char code LEDMAP[] =/**< 共阳极显示代码*/{0xc0, 0xf9, 0xa4, 0xb0, 0x99,0x92, 0x82, 0xf8, 0x80, 0x90,};void Delay(unsigned int t);main(void){unsigned char i;LED_SELECT = 0xfe;TCON = 0x05;//*使得IT0和IT1为1*/ LED_DA TA = LEDMAP[0];while(1){ if(IE0){IE0 = 0;//*必须先置零才能工作*/if(i<9){LED_DA TA = LEDMAP[i+1];Delay(20000);//*必须延迟,否则肉眼看不到变化**/i++;}else //*当i=9时*/{LED_DATA = LEDMAP[i-9];Delay(20000);i=0;}}if(IE1){IE1 = 0; //*必须先置零才能工作*/if(i>0){LED_DA TA = LEDMAP[i-1];Delay(20000);i--;}else //*当i=0时*/{LED_DA TA = LEDMAP[i+9];Delay(20000);i=9;}}}}void Delay(unsigned int t){for (t; t>0; t--) ;}实现1位七段LED数码管显示值定时自动加一#include <REGX51.H>#define LED_SELECT P2#define LED_DATA P0unsigned char code LEDMAP[] = /**< 共阳极显示代码*/{0xc0, 0xf9, 0xa4, 0xb0, 0x99,0x92, 0x82, 0xf8, 0x80, 0x90,};void Delay(unsigned int t);main(void){unsigned char i;while(1){for(i = 0; i < 10; i++){LED_SELECT = 0xfe;/**< 关闭7个,保留1个七段码显示器*/LED_DA TA = LEDMAP[i];/**< 送显示代码*/Delay(20000);}}}void Delay(unsigned int t){for (t; t>0; t--) ; 用计数器1的工作方式2实现每数3个脉冲LED亮灭变化#include <REGX51.H>#define LED0 P1_0main(void){TMOD = 0x60;TL0 = 256 - 3;TH0 = 256 - 3;TR1 = 1;IE = 0x88;while(1);}Counter0() interrupt 3{LED0 = !LED0;}用计数器0的工作方式2实现每数5个脉冲LED亮灭变化#include <REGX51.H>#define LED0 P1_0main(void){TMOD = 0x06;TL0 = 256 - 5;TH0 = 256 - 5;TR0 = 1;IE = 0x82;while(1);}Counter0() interrupt 1{LED0 = !LED0;}无源蜂鸣器发出简单的音乐#include <REGX51.H>Unsigned char code Song[] = {5,3,5,3,5,6,5,3,6,5,1,1,2,3,5,3,2,0,3,5,5,5,6,5, 3,5,5,6,5,7,6,5,1,5,3,2,1,2,3,5,5,2,3}; unsigned char code Tone[] = {0,115,102,91,86,77,68,61};#define BUZZER P3_0void Delay(unsigned char t);void main(void){unsigned char i,j;while(1){/** 循环播放Song */for(i = 0; i < 40; i++){for(j = 0; j < 100; j++){BUZZER = 0;Delay(Tone[Song[i]]);BUZZER = 1;Delay(Tone[Song[i]]);//一吸一合才能发生}for(j = 0; j < 100; j++){BUZZER = 1;Delay(250 - Tone[Song[i]]);Delay(250 - Tone[Song[i]]);}}}}void Delay(unsigned char t){for (t; t>0; t--) ;} 七段数码管快速移动显示9#include <REGX51.H>#define LED_SELECT P2#define LED_DA TA P0unsigned char code LEDMAP[] = /**< 共阳极显示代码*/{0xc0, 0xf9, 0xa4, 0xb0, 0x99,0x92, 0x82, 0xf8, 0x80, 0x90,};unsigned char code LED[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f, };void Delay(unsigned int t);main(void){unsigned char i;while(1){for(i = 0; i < 8; i++){LED_SELECT =LED[i] ;/**< 关闭7个,保留1个七段码显示器*/LED_DA TA = LEDMAP[9];/**< 送显示代码*/Delay(20);}}}void Delay(unsigned int t){for (t; t>0; t--) ;}定时器实现每隔1秒LED亮灭变化用定时器1工作方式2、定时时间改为0.5秒实现#include <REGX51.H>#define LED0 P1_0main(void){TMOD = 0x20;TL0 = 256-100;TH0 = 256-100;TR1 = 1;IE = 0x88;//*书p158,EA(总开关)为1,ET1(定时中断1)为1。
0x88*//while(1);}Timer1() interrupt 3 //3代表TF1的优先级最高,p159{static unsigned int count_1s = 0;TH0 = 256-100;TL0 = 256-100;count_1s++;if(count_1s >=5000){count_1s =0;LED0 =!LED0;}}TMOD(89H):GATE C//T M1 M0 GA TE C//T M1 M0 默认:0x00其中:C//T:定时计数选择M1-0: 工作方式选择GATE:启动方式设定0:软件启动(常用)1:外部中断启动* 工作方式1: TL0和TH0组成16位的定时器* TCON(88H):TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 默认:0x00其中:IT0(IT1):0: 外部中断0(1)的申请信号为电平触发(低电平有效)1: 外部中断0(1)的申请信号为脉冲触发(下降沿有效)IE0(IE1):有外部中断0(1)申请信号时自动置“1”;调用外部中断0(1)函数后,自动清”0”TR0(TR1):1: 启动定时计数器0(1);0: 关闭定时计数器0(1)TF0(TF1):定时计数器0(1)溢出时自动置“1”;调用定时计数中断0(1)函数后,自动清”0”* IE(0A8H):EA / / ES ET1 EX1 ET0 EX0 默认:0x00其中:EA: 总中断开关(1:开;0:关)ES ET1 EX1 ET0 EX0:4-0号中断开关* 0-4号中断分别为:外部中断0 定时中断0 外部中断1 定时中断1 串行中断其他:- IP(0B8H):/ / / PS PT1 PX1 PT0 PX0默认:0x00其中:0:低优先级;1:高优先级同级别优先顺序:0-4- 中断引脚P3.0-P3.5: RXD TXD INT0 INT1 T0 T1 - 定时器0(1)工作方式1工作原理TL0、TH0 (TL1、TH1)组成16位大存储单元,启动定时计数器0(1)后,大存储单元内容自动加1(定时器每隔1个机器周期加1;计数器每数1个脉冲加1 )当大存储单元溢出时,TF0(TF1)自动置“1”- 定时中断函数调用过程: 需完全理解当定时计数中断0(1)开关打开时,如果TF0(TF1)为“1”,则自动调用定时计数中断0(1)函数,并自动清IE0(IE1)利用定时器实现每隔1秒LED亮灭变化#include <REGX51.H>#define LED0 P1_0main(void){TMOD = 0x01;TL0 = (65536 - 50000)%256;TH0 = (65536 - 50000)/256;TR0 = 1;IE = 0x82;while(1);}/*** 定时中断0的中断函数*/Timer0() interrupt 1{static unsigned char count_1s = 0;TH0 = (65536 - 50000)/256;TL0 = (65536 - 50000)%256;count_1s++;if(count_1s >= 20){count_1s =0;LED0 =!LED0;}} 定时器实现每隔1秒LED亮灭变化改成方式二#include <REGX51.H>#define LED0 P1_0main(void){TMOD = 0x02;//*p176 m1=1 m0=0时是方式二*// TL0 = 256-100;TH0 = 256-100;TR0 = 1;IE = 0x82;while(1);}Timer0() interrupt 1//*方式二依旧用timer0*//{static unsigned int count_1s = 0;//*char 范围到256,而10000超过256,得用int ,为两个字节,共65536,char为一个字节,共256*//TH0 = 256-100;TL0 = 256-100;count_1s++;if(count_1s >= 10000)//* 100*10000*1微秒=1秒*//{count_1s =0;LED0 =!LED0;}}显示12345678#include <REGX51.H>#define LED_SELECT P2#define LED_DATA P0unsigned char code LEDMAP[] =/**< 共阳极显示代码*/{0xc0, 0xf9, 0xa4, 0xb0, 0x99,0x92, 0x82, 0xf8, 0x80, 0x90,};void Delay(unsigned int t);main(void){unsigned char i;while(1){for(i = 0; i < 8; i++){LED_SELECT = 0xff;LED_DA TA = LEDMAP[i+1];LED_SELECT = ~(1 << i);Delay(90);}}}void Delay(unsigned int t){for (t; t>0; t--) ;} 用外部中断实现发光二极管的闪烁(查询法)#include <REGX51.H>#define LED0 P1_0main(void){TCON = 0x01;while(1){if(IE0){IE0 = 0;/**< 对于查询法,需人工清零*/LED0 = ~LED0;}}}TCON(88H):TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 默认:0x00其中:IT0(IT1):0: 外部中断0(1)的申请信号为电平触发(低电平有效)1: 外部中断0(1)的申请信号为脉冲触发(下降沿有效)IE0(IE1):有外部中断0(1)申请信号时自动置“1”;外部中断0(1)函数执行后,自动清”0”外部中断实现发光二极管的闪烁#include <REGX51.H>#define LED0 P1_0main(){TCON = 0x01;/**< 外部中断0设为下降沿触发* */ IE = 0x81;/**< 打开外部中断0* */while(1);}/** 外部中断0的中断函数*/XINT0() interrupt 0/**< 0号中断函数* */{ LED0 = ~LED0;}TCON(88H):TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 默认:0x00其中:IT0(IT1):0: 外部中断0(1)的申请信号为电平触发(低电平有效)1: 外部中断0(1)的申请信号为脉冲触发(下降沿有效)IE0(IE1):有外部中断0(1)申请信号时自动置“1”;调用外部中断0(1)函数后,自动清”0”* IE(0A8H):EA / / ES ET1 EX1 ET0 EX0 默认:0x00其中:EA: 总中断开关(1:开;0:关)ES ET1 EX1 ET0 EX0:4-0号中断开关* 外部中断函数调用过程(需完全理解):当外部中断0(1)开关打开时,如果IE0(IE1)为“1”,则自动调用外部中断0(1)函数,并自动清IE0(IE1)* 0-4号中断分别为:外部中断0 定时中断0 外部中断1 定时中断1 串行中断其他:- IP(0B8H):/ / / PS PT1 PX1 PT0 PX0默认:0x00其中:0:低优先级;1:高优先级同级别优先顺序:0-4- 中断引脚P3.0-P3.5: RXD TXD INT0 INT1 T0 T1 */ 实现1位七段LED数码管显示值定时自动加一#include <REGX51.H>#define LED_SELECT P2#define LED_DA TA P0unsigned char code LEDMAP[] =/**< 共阳极显示代码*/{0xc0, 0xf9, 0xa4, 0xb0, 0x99,0x92, 0x82, 0xf8, 0x80, 0x90,};void Delay(unsigned int t);main(void){unsigned char i;while(1){for(i = 0; i < 10; i++){LED_SELECT = 0xfe;/**< 关闭7个,保留1个七段码显示器*/LED_DA TA = LEDMAP[i];/**< 送显示代码*/Delay(20000);}}}void Delay(unsigned int t){for (t; t>0; t--) ;}光标循环转动(按键控制方向)#include <REGX51.H>#define LED_SELECT P2#define LED_DATA P0#define KEY_PIN P3typedef enum{NULL, KEY_S17, KEY_S18}TYPEDEF_KEY;unsigned char CursorPosition = 0;unsigned char code LEDMAP[] =/**< 共阳极光标显示代码*/ {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, };#define GO_OUT 0xff /**< 熄灭*/ unsigned char code DA TA_ADJ[] =/**< 光标位置转换为显示数据*/ {0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, };unsigned char LEDBuffer[8];/**< 显示缓冲区*/unsigned char code SELECT_ADJ[] =/**< 光标位置转换为数据管位号*/ {7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, };TYPEDEF_KEY GetKey(void);void Delay(unsigned int t);main(void){unsigned char i = 0;TYPEDEF_KEY key = NULL;bit direction = 0;while(1){LED_SELECT = 0xff;LED_DA TA=LEDMAP[DATA_ADJ[CursorP osition]];LED_SELECT=~(1<<SELECT_ADJ[Cu rsorPosition]);Delay(10000);key = GetKey();if(key == KEY_S17){direction = 1;}if(key == KEY_S18){direction = 0;}/** 光标移动*/if(direction == 1){CursorPosition++;if(CursorPosition > 19){CursorPosition = 0;}}if(direction == 0){ if(CursorPosition == 0){CursorPosition = 19;}else{CursorPosition--;}}}}void Delay(unsigned int t){ for (t; t>0; t--) ; }/**得到按键值*/TYPEDEF_KEY GetKey(void){TYPEDEF_KEY key = NULL;if(~KEY_PIN & 0X08){key = KEY_S18;}else if(~KEY_PIN & 0X04){key = KEY_S17;}else{return(NULL);}while( ~KEY_PIN & 0x0c)//等待键抬起{Delay(1000);}return(key);}按键,在数码管上显示该按键的键值#include <REGX51.H>#define KEYBOARD P1#define LED_SELECT P2#define LED_DATA P0unsigned char code LEDMAP[] =/**< 共阳极显示代码*/{0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0xff};#define GO_OUT 10 /* 熄灭的显示代码*/ unsigned char LEDBuf[8]; /*显示缓冲区*/ unsigned char TestKey(unsigned char outkey); unsigned char GetKey(void);void Delay(unsigned int t);void Display(unsigned char * buf, unsigned char number);main(void){unsigned char key;unsigned char i;/*最低2位7SEGLED显示:00,其余全部熄灭*/LEDBuf[7] = 0;LEDBuf[6] = 0;for(i = 0; i < 6; i++){LEDBuf[i] = GO_OUT;}while(1){key = GetKey();if(key != 0xff){LEDBuf[7] = key % 10; /** 取余*/LEDBuf[6] = key / 10; /** 取商*/}Display(LEDBuf, 8);}}void Delay(unsigned int t){ for (t; t>0; t--) ; }void Display(unsigned char * buf, unsigned char number){unsigned char i;for (i = 0; i < number; i++){LED_SELECT = 0xff;/** 关所有LED (防止出现闪烁现象*/LED_DATA = LEDMAP[*(buf + i)];/**< 送数据的显示代码*/LED_SELECT = ~(1<<i);/**< 显示某1位数码管,其余关闭*/Delay(90);/**< 延时约1ms */}}/**检测是否有键按下*/unsigned char TestKey(unsigned char outkey) {KEYBOARD = outkey;Delay(20);if( ~KEYBOARD & 0x01 ){return(1);}else if( ~KEYBOARD & 0x02 ){return(2);}else if( ~KEYBOARD & 0x04 ){return(3);}else if( ~KEYBOARD & 0x08 ){return(4);}else{return(0);}}/**得到按键值*/unsigned char GetKey(void){unsigned char i;unsigned char outkey;unsigned char keyNO;unsigned char rowNO;if(TestKey(0x0f))/**< 高4位全送0,检测是否有键按下*/ {Display(LEDBuf, 8);/**< 延时16ms,(用于去抖动)*/Display(LEDBuf, 8);if(TestKey(0x0f))/**< 高4位全送0,检测是否有键按下*/ {outkey = 0x80;for(i = 0;i < 4;i++){rowNO = TestKey(~outkey);/**< 高4位送1个0,扫描按键*/if(rowNO){keyNO = i + (rowNO - 1)* 4;/**< 计算按键值*/break;}outkey >>=1;/**< 扫描下一列*/}while(TestKey(0x0f))/**< 等待按键抬起*/{Display(LEDBuf, 8);}return(keyNO);/**< 返回键值*/}}return(0xff);/**< 如果没有按键按下,返回0xff */}电子钟功能(软件延时)#include <REGX51.H>#define LED_SELECT P2#define LED_DATA P0unsigned char code LEDMAP[] =/**< 共阳极显示代码*/{0xc0, 0xf9, 0xa4, 0xb0, 0x99, /**< 0-4 */ 0x92, 0x82, 0xf8, 0x80, 0x90, /**< 5-9 */ 0xbf, 0xff, /**< -, 灭*/};enum {CHAR_DEC = 10, GO_OUT}; unsigned char LEDBuffer[8];/**< 显示缓冲区*/unsigned char Second = 0;unsigned char Minute = 0;unsigned char Hour = 0;unsigned char Count_10ms = 0;void Show(void);void ReflashTime(void);void Delay(unsigned int t);void Display(unsigned char * buf, unsigned char number);main(void){ while(1){Show();Delay(54);/**延时,使每次循环时间约为10ms */ Count_10ms ++;if(Count_10ms > 99){Count_10ms = 0;ReflashTime();}}}/**界面显示*/void Show(void){LEDBuffer[7] = Second % 10;//秒个位送显示缓冲区LEDBuffer[6] = Second / 10;//秒十位送显示缓冲区LEDBuffer[4] = Minute % 10;LEDBuffer[3] = Minute / 10;LEDBuffer[1] = Hour % 10;LEDBuffer[0] = Hour / 10;if(Count_10ms < 50){LEDBuffer[5] = CHAR_DEC;LEDBuffer[2] = CHAR_DEC;}else{LEDBuffer[5] = GO_OUT;LEDBuffer[2] = GO_OUT;}Display(LEDBuffer,8);}/**更新时间*/void ReflashTime(void){Second++;if(Second > 59){Second = 0;Minute ++;if(Minute > 59){Minute = 0;看ram----sp 看rom----pc Hour ++;if(Hour > 23){Hour = 0;}}}}void Delay(unsigned int t){ for (t; t>0; t--) ;}/*动态显示数码管为共阴极*/void Display(unsigned char * buf, unsignedchar number){unsigned char i;for (i = 0; i < number; i++){LED_SELECT = 0xff;/**关所有LED(防止出现闪烁现象)*/LED_DATA = LEDMAP[*(buf + i)];/**< 送数据的显示代码*/LED_SELECT = ~(1<<i);/*显示某1位数码管,其余关闭*/Delay(90); /**< 延时约1ms */}}。