山东大学单片机硬件实验.doc
单片机原理与应用实验文档存放目录:一、 实验题目:实验 1:按键声光报警实验 实验 5:8255 并行 I/O 扩展及交通信号灯控制实验 实验 7:7279 键盘扫描及动态 LED 显示实验二、 实验要求实验1:本实验联系静态按键识别,发光二极管驱动,要求利用外部硬件中断,按键按下一次产生一次外部中断,在中断服务程序中计数器加 1,同时,通过发光二极管的闪烁和蜂鸣器响的次数,指示计数器的当前值。当计数到10 时,再次按键将重新从 1 开始计。实验2:本实验利用 8255 实现可编程的并行 IO 扩展功能,并利用其完成交通灯控制。实验要求红灯常亮 30S,绿灯常亮 25S 后闪烁 5S。使用静态数码管显示绿灯常亮倒计时。本实验中的东西方向信号灯同步控制,南北方向信号灯同步控制,即:东西方向上同种颜色的灯同时亮或灭,南北方向上同种颜色的灯同时亮或灭。实验3:本实验利用 7279 进行键盘扫描及动态 LED 数码管显示控制。当按下某个按键时所按按键对应的字符显示在最右端 LED 数码管上,如果再次按下一个按键2,则原来显示的内容往左移 1 位,将新按下的按键2,的字符显示在最右端,依次类推显示0F。三、 实验过程及结果记录(截图) 实验1 实验2 实验3 四、 实验源程序 实验1 #include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit bell=P31; /P3.1口位赋值给铃声sbit led=P30; /P3.0口位赋值给灯sbit key0=P32; /P3.2口位赋值给按键uint count;void delay(uint count) /延时1ms uint x,y; for(x=count;x>0;x-) for(y=110;y>0;y-); void show(uint count) uint i;for(i=0;i<=count;i+)led=0;bell=0; /灯亮,铃响delay(500); /延时0.5sled=1;bell=1; /灯灭,铃不响delay(500);void s_timer0() interrupt 0 using 0EA=0; /屏蔽所有中断请求show(count); /调用子程序count+;delay(50);if(count>=10)count=0; EA=1; /开放中断/*主程序*/void main() EA=1; /开放中断EX0=1; /允许外部中断0中断IT0=0; /外部中断0为电平触发方式while(1); /循环执行 实验2 #include<reg51.h>#include<stdio.h>#include <absacc.h>#define uchar unsigned char#define uint unsigned int#define PA XBYTE0x7FFC/CS-A15#define COM XBYTE0x7FFFsbit P30=P30;sbit P31=P31;uint temp,shi,ge,t;uchar a;void xianshi(uint temp);void delay();void delays();void init_8255();void init_8255()COM=0x80; / c = out, a = out,b = outvoid delay() /延时500MS子程序 uint i,j; for( i=500;i>0;i-) for(j=120;j>0;j-);void delays() /延时1S子程序 uint i,j; for(i=1000;i>0;i-) for(j=120;j>0;j-);/*主程序*/void main() init_8255(); TMOD=0x01; /设定工作模式1 EA=1; /开放中断 ET0=1; /允许T0中断 TF0=0; /定时器0溢出标志位 while(1) a=0x26; /变量a赋初值 for(temp=25;temp>19;temp-) /绿灯倒计时25s a=a-1; PA=0x69; /东西绿灯亮 xianshi(a); /调用数码管显示子程序 delays(); /延时1s a=0x1a; /变量a赋值 for(temp=19;temp>9;temp-) /倒计时 a=a-1; PA=0x69; /东西绿灯亮 xianshi(a); delays(); a=0x0a; for(temp=9;temp>0;temp-) a=a-1; PA=0x69; xianshi(a); delays(); for(t=5;t>0;t-) /绿灯闪烁5s a=0; /当计时值为0时闪烁xianshi(a); PA=0xeb; /东西绿灯灭 delay(); /延时0.5s PA=0x69; /东西绿灯亮 delay(); /延时0.5s a=0x26; for(temp=25;temp>19;temp-) /绿灯倒计时25s a=a-1; PA=0x96; /南北绿灯亮 xianshi(a); delays(); a=0x1a; for(temp=19;temp>9;temp-) a=a-1; PA=0x96; xianshi(a); delays(); a=0x0a; for(temp=9;temp>0;temp-) a=a-1; PA=0x96; xianshi(a); delays(); for(t=5;t>0;t-) /绿灯闪烁5s a=0; /当计时值为0时闪烁xianshi(a); PA=0xbe; /南北绿灯灭 delay(); /延时0.5s PA=0x96; /南北绿灯亮 delay(); /延时0.5s void xianshi(uint a) /显示子程序 SCON=0x00; /工作模式0 SBUF=a; /将变量a的值送给缓存寄存器 while(!TI) /等待发送是否完成 TI=0; /中断标志位清零 实验3 #include<reg51.h>#include<stdio.h>sbit CS=P10;/ cs at P1.0sbit CLK=P11; / clk 连接于 P1.1sbit DATA=P12; / dat 连接于 P1.2sbit KEY=P13; / key 连接于 P1.3/* HD7279A 指令*/#define RESET 0xa4 / 复位指令#define RL 0xa1 /左移指令#define DECODE1 0xc8 /译码方式1#define READ 0x15 /读键盘指令/*长延时子程序*/void ldelay() /25us unsigned char a,b; for(b=1;b>0;b-) for(a=20;a>0;a-);/*短延时子程序*/void sdelay() unsigned char a; for(a=3;a>0;a-);void send(unsigned char out) / 发送一个字节unsigned char i;CS=0; /芯片使能ldelay(); /长延时for(i=0;i<8;i+) /分8次移入数据if(out&0x80) /先传高位DATA=1;else DATA=0;CLK=1;sdelay();CLK=0;sdelay();out=out<<1; /数据左移DATA=0;void write(unsigned char command,unsigned char dat)send(command);send(dat);unsigned char receive() /接收一个字节unsigned char i,inbyte;ldelay(); /长延时for(i=0;i<8;i+) /分8次读入数据 高位在前CLK=1;sdelay();inbyte=inbyte<<1;if(DATA)inbyte=inbyte|0x01; /数据左移CLK=0;sdelay();DATA=0;return inbyte;/*键盘扫描子程序*/unsigned char keyscan()unsigned char key;if(!KEY) /检测P1.3是否口为低电平send(READ);key=receive(); /将接收到的数赋给keyswitch(key) /按键编码case 0x1b:return 0x00;break;case 0x13:return 0x01;break;case 0x0b:return 0x02;break;case 0x03:return 0x03;break;case 0x1a:return 0x04;break;case 0x12:return 0x05;break;case 0x0a:return 0x06;break;case 0x02:return 0x07;break;case 0x19:return 0x08;break;case 0x11:return 0x09;break;case 0x09:return 0x0a;break;case 0x01:return 0x0b;break;case 0x18:return 0x0c;break;case 0x10:return 0x0d;break;case 0x08:return 0x0e;break;case 0x000:return 0x0f;break;return 0xff;/*主程序*/void main()unsigned char i,key;send(RESET);while(1)if(!KEY) /检测P1.3是否口为低电平key=keyscan(); /将键盘扫描所得值赋给keysend(RL);write(DECODE1,key); while(!KEY); /当P1.3口为低电平,循环执行