实验一
如图1-1所示,利用AT89C51单片机的P1口外接8个发光二极管,实现流水灯效果。
图1-1 实验一仿真电路图
#include unsigned char LEDTAB[]= { 0xFE,0xFD,0xFB,0xF7,,0xEF,0xDF,0xBF,0x7F }; void Delay(void) { unsigned char i,j,k; for(i=10;i>0;i--) for(j=100;j>0;j--) for(k=200;k>0;k--); } void main(void) { unsigned char i; while(1) { for(i=0;i P1=LEDTAB[i]; Delay(); } } } 实验二 1、 如图2-1所示,利用AT89C51单片机的P2端口外接一位共阴LED数码管,实现在LED数码管上轮流显示0~9。 图2-1 数码管显示实验内容1仿真电路图 #include unsigned char SEGTAB[]= { 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F }; void Delay(void) { unsigned char i,j,k; for(i=10;i>0;i--) for(j=100;j>0;j--) for(k=200;k>0;k--); } void main(void) { unsigned char i; while (1) { for(i=0;i Delay();} } } 2、 如图2-2所示,利用AT89C51单片机的P2和P0端口分别驱动2位共阴LED数码管的笔段和位选段(动态显示接法),利用动态显示原理实现LED数码管上显示00~99的自动计数加1数值。 图2-2数码管显示实验内容2仿真电路图 #include unsigned char SEGTAB[]= { 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F }; unsigned char DIGTAB[]= { 0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F }; unsigned char LEDBuffer[2]; unsigned char LEDPointer; void Delay(void) { unsigned char i,j; for(i=10;i>0;i--) for(j=100;j>0;j--); } void main(void) { unsigned char Cnt=0; unsigned char msCnt=0; while(1) { P2=SEGTAB[LEDBuffer[LEDPointer]]; P0=DIGTAB[LEDPointer]; if (++LEDPointer==sizeof(LEDBuffer))LEDPointer=0; Delay(); if (++msCnt==200) { msCnt=0; if(++Cnt==100)Cnt=0; LEDBuffer[0]=Cnt%10; LEDBuffer[1]=Cnt/10; } } } 实验三 如图3-1所示,利用AT89C51单片机的P3口外接一个4X4矩阵键盘,矩阵键盘的4根行线分别连接在P3.0~P3.3引脚上,4根列线分别连接在P3.4~P3.7引脚上。AT89C51单片机的P2驱动一个8位共阴LED数码管,实现在矩阵键盘的16个按键识别,并将对应的按键编号显示在LED数码管上。 图3-1 矩阵键盘实验内容1仿真原理图 #include unsigned char SEGTAB[] = { 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71, }; unsigned char KEYTAB[] = { 0xEE,0xED,0xEB,0xE7, 0xDE,0xDD,0xDB,0xD7, 0xBE,0xBD,0xBB,0xB7, 0x7E,0x7D,0x7B,0x77, }; void Delay10mS(void) { unsigned char i,j; for(i=10;i>0;i--) for(j=100;j>0;j--); } void main(void) { unsigned char KeyValue; unsigned char i,temp; while (1) { P3=0xF0; if(0xF0!=(P3&0xF0)) { Delay10mS(); if(0xF0!=(P3&0xF0)) { temp=P3&0xF0; P3=0x0F; temp|=(P3&0x0F); for (i=0;i if(KEYTAB[i]==temp) { KeyValue=i; P2=SEGTAB[KeyValue]; i=sizeof(KEYTAB)+3; } } } while(0x0F!=(P3&0x0F)); } } } 实验四 1、 如图4-1所示,利用AT89C51单片机的P3.2引脚外接一个轻触按钮“BUTTON”,用中断方式实现按键计数加1,并通过由P2和P0端口驱动的两个共阴LED数码管显示00~99的计数值。其中P2端口驱动显示数字的十位数,P0端口驱动显示数字的个位数。 图4-1 实验内容1仿真电路图 #include unsigned char SEGTAB[] = { 0x3F,0x06,0x5B,0x4F, 0x66,0x6D,0x7D,0x07, 0x7F,0x6F,0x77,0x7C, 0x39,0x5E,0x79,0x71, }; unsigned char KeyCnt=0; void main(void) { P2=SEGTAB[KeyCnt/10]; P0=SEGTAB[KeyCnt%10]; IT0=1; EX0=1; EA=1; while(1) { ; } } void INT0_ISR(void) interrupt 0 { if(0==P3_2) { if(++KeyCnt==100)KeyCnt=0; P2=SEGTAB[KeyCnt/10]; P0=SEGTAB[KeyCnt%10]; } } 2、 如图4-2所示,利用AT89C51单片机的P1端口外接8个LED发光二极管,实现流水灯,流水灯的速度为0.2~1秒之间可调,步进为0.2s,由外接在P3.2和P3.3引脚上的两个轻触开关实现调慢和调快功能(用中断方式实现按键功能),速度的档位通过P2端口外接的一个8位共阴LED数码管显示。 #include unsigned char LEDTAB[] = { 0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F, }; unsigned char SEGTAB[] = { 0x3F,0x06,0x5B,0x4F,0x66,0X6D,0x7D,0x07,0x7F,0x6F, }; void Delay10mS(unsigned char t) { unsigned char i,j; do { for(i=100;i>0;i--) for(j=100;j>0;j--); } while(--t); } unsigned char Speed = 20; void main(void) { unsigned char i; P2=SEGTAB[Speed/20]; IT0=1; EX0=1; IT1=1; EX1=1; EA=1; while(1) { for(i=0;i P0=LEDTAB[i]; Delay10mS(Speed); } } } void INT0_ISR(void) interrupt 0 { if(0==P3_2) { Speed+=20; if(Speed>100)Speed=100; P2=SEGTAB[Speed/20]; } } void INT1_ISR(void) interrupt 2 { if(0==P3_3) { Speed-=20; if(Speed<20)Speed=20; P2=SEGTAB[Speed/20]; } } 实验五 1、 如图5-1所示,利用AT89C51单片机的定时器T0产生1KHz的方波信号由P3.7引脚输出,通过连接到“OSCILLOSCOPE”虚拟示波器上查看显示的波形图。 #include void main(void) { TMOD |= 0x01; TH0=(65536-500)/256; TL0=(65536-500)%256; TR0=1; while(1) { if(1==TF0) { TF0=0; TH0=(65536-500)/256; TL0=(65536-500)%256; P3_7=~P3_7; } } } 2、 如图5-2所示,利用AT89C51单片机的定时器T0产生1ms的动态数码管显示扫描时间,驱动接在P2和P0端口上的4位共阴LED数码管,其中P2用于驱动共阴LED数码管的笔段A~H,P0用于驱动共阴LED数码管的位选端;采用定时器T0的溢出中断实现1ms定时。数码上显示自己的班号和学号的后2位数字,显示方式为“X-YY”,X为班号,YY为学号。并且显示的“-”闪烁频率为0.5秒。 #include unsigned char SEGTAB[] = { 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F, }; unsigned char DIGTAB[] = { 0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F, }; unsigned char LEDBuffer[2]; unsigned char LEDPointer; void Delay(void) { unsigned char i,j; for(i=10;i>0;i--) for(j=100;j>0;j--); } void INT0_ISR(void) interrupt 0 { if(0==P3_2) { P2=SEGTAB[LEDBuffer[LEDPointer]]; P0=DIGTAB[LEDPointer]; } } void main(void) { unsigned char Cnt=99; unsigned char msCnt=0; LEDBuffer[0]=Cnt%10; LEDBuffer[1]=Cnt/10; IT0=1; EX0=1; EA=1; while(1) { P2=SEGTAB[LEDBuffer[LEDPointer]]; P0=DIGTAB[LEDPointer]; if (++LEDPointer==sizeof(LEDBuffer))LEDPointer=0; Delay(); if (++msCnt==200) { msCnt=0; if(--Cnt==(-1))Cnt=99; LEDBuffer[0]=Cnt%10; LEDBuffer[1]=Cnt/10; } } } 实验六 1、实验内容1 如图6-1,利用AT89C51单片机的P3.0(RXD)和P3.1(TXD)外接一个74HC164(串/并转换芯片)驱动1个8位共阴LED数码管,实现0~9的轮流显示, #include unsigned char SEGTAB[] = { 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F, }; void Delay(void) { unsigned char i,j,k; for(i=10;i>0;i--) for(j=100;j>0;j--) for(k=100;k>0;k--); } void main (void) { unsigned char i; SCON=0x00; while(1) { for(i=0;i SBUF=SEGTAB[i]; while(0==TI); TI=0; Delay(); } } } 2、实验内容2 如图6-2,在U1(AT89C51)和U2(AT89C51)的P1端口分别接一个8位共阴LED数码管,P3.2引脚上分别接有一个轻触开关。U1的P3.0(RXD)连接到U2的P3.1(TXD),U1的P3.1(TXD)连接到U2的P3.0(RXD),通过串行口进行双机通信,实现在U1上按下按键实现计数加1,通过U2的LED数码管显示,同样U2上按下按键实现计数加1, 通过U1的LED数码管显示,双机通信的波特率为9600。 #include unsigned char SEGTAB[] = { 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F, }; void main(void) { unsigned char KeyCnt = 0; PCON |= 0x80; SCON = 0x50; TH1 = 0xFD; TL1 = 0xFD; TR1 = 1; ES = 1; EA = 1; while(1) { if(0 == P3_2) { if(++KeyCnt == 10)KeyCnt = 0; SBUF = KeyCnt; while(0 == TI); TI = 0; while(0 == P3_2); } } } void Serial_ISR(void) interrupt 4 { unsigned char temp; if(1 == RI) { RI = 0; temp = SBUF; P1 = SEGTAB[temp]; } } 因篇幅问题不能全部显示,请点此查看更多更全内容