一. 闪烁灯
[实验任务]
在 P1.0 端口上接一个发光二极管 L1,使 L1 在不停地一亮一灭,一亮一灭
的时间间隔为0.2秒。
[硬件电路]
与上面点亮小灯的连接完全相同。
#include<reg52.h> /*闪烁灯*/
del() /*延时0.2秒*/
{
unsigned char i,j,k;
for(i=20;i>0;i--)
for(j=20;j>0;j--)
for(k=248;k>0;k--);
}
sbit P1_0=P1^0;
main()
{
while(1)/*永远为真,一直执行下去*/
{
P1_0=0;
del();
P1_0=1;
del();
}
}
#include "reg52.h"
//#define uchar unsigned char
//#define uint unsigned int
sbit P10=P1^0;
void mDelay(unsigned int Delay)
{ unsigned int i;
for(;Delay>0;Delay--)
{ for(i=0;i<124;i++)
{;}
}
}
void main()
{ for(;;)
{ P10=!P10; //取反 P1.0
mDelay(1000); //延时1秒。如果是2000那么是2秒
}
}
------------------------------------------------------------------------------------------------------------------------------
二.广告灯的左移右移
[实验任务]
做广告灯的左移右移,八个发光二极管分别接在单片机的P3.0-P3.7接口上,输出“0”时,发光二极管亮,开始时P3.0→P3.1→P3.2→P3.3→┅→P3.7→P3.6→┅→P3.0亮,重复循环。(当然,四个输出口可以同时实现广告灯)
[硬件电路]
#include<reg52.h> /*广告灯的左移右移*/
unsigned char i;
unsigned char temp;
unsigned char a,b;
delay()//延时程序
{unsigned char m,n,s;
for(m=20;m>0;m--)
for(n=20;n>0;n--)
for(s=248;s>0;s--);
}
main()
{
while(1)
{
temp=0xfe;
P3=P2=P0=P1=temp;//直接对1/0口p3赋值,使批p3.0输出低电平。
delay();//延时
for(i=1;i<8;i++)//实现广告灯的从右到左移动
{
a=temp<<i;
b=temp>>(8-i);
P3=P2=P0=P1=a|b;
delay();
}
for(i=1;i<8;i++)//实现广告灯的从左到右移动
{
a=temp>>i;
b=temp<<(8-i);
P3=P2=P0=P1=a|b;
delay();
}
}
}
---------------------------------------------------------------------------------------------
#include "reg52.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
void mDelay(unsigned int Delay)
{ unsigned int i;
for(;Delay>0;Delay--)
{ for(i=0;i<124;i++)
{;}
}
}
void main()
{ unsigned char OutData=0xfe;
for(;;)
{
P1=OutData;
OutData=_crol_(OutData,1); // 循环左移
mDelay(1000); // 1000延时1s
}
}
-----------------------------------------------------------------------------------------
#include<reg52.h> /*广告灯的缩短*/
unsigned char i;
unsigned char temp;
unsigned char a,b;
delay()//延时程序
{unsigned char m,n,s;
for(m=20;m>0;m--)
for(n=20;n>0;n--)
for(s=248;s>0;s--);
}
main()
{
while(1)
{
temp=0xfe;
P1=temp;//直接对1/0口p3赋值,使批p3.0输出低电平。
delay();//延时
for(i=1;i<8;i++)//实现广告灯的从右到左移动
{
a=temp<<i;
b=temp>>(8-i);
P1=b;
//P1=a|b;
delay();
}
for(i=1;i<8;i++)//实现广告灯的从左到右移动
{
a=temp>>i;
b=temp<<(8-i);
P1=b;
//P1=a|b;
delay();
}
}
}
------------------------------------------------------------------------------------------------------------
三. 按键识别
[实验任务]
通过按下一次按键,使广告灯向左移动一位,直到最后一位,在向右移动。
[硬件电路]
(大家注意到这一个电路图与上一个实验的电路图只多了一个按键和一个5.1K的电阻。)
[实验原理]
从图中可以看出P2.1在按键没有按下时接的是高电平,按键按下时接的就是低电平了。所以我们只要判断P2.1的电平就可以知道按键是否被按下了。而在按键按下的过程中,由于抖动,将产生干扰,在按下的过程中,一旦有干扰过来,可能造成误触发过程,这并不是我们所想要的。因此在按键按下的时候,要把我们手上的干扰信号以及按键的机械接触等干扰信号给滤除掉,一般情况下,我们可以采用软件滤波的方法去除这些干扰信号,一般情况下,一个按键按下的时候,总是在按下的时刻存在着一定的干扰信号,按下之后就基本上进入了稳定的状态。我们在程序设计时,从按键被识别按下之后,延时5ms以上,从而避开了干扰信号区域,我们再来检测一次,看按键是否真得已经按下,若真得已经按下,这时肯定输出为低电平,若这时检测到的是高电平,证明刚才是由于干扰信号引起的误触发,CPU就认为是误触发信号而舍弃这次的按键识别过程。
[C语言源程序]
#include <reg52.h>
sbit BY1=P2^1; //定义按键的输入端
unsigned char count; //按键计数,每按一下,count 加1
unsigned char temp;
unsigned char a,b;
void delay10ms(void) //延时程序
{
unsigned char i,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
key() //按键判断程序
{
if(BY1==0) //判断是否按下键盘
{
delay10ms(); //延时,软件去干扰
if(BY1==0) //确认按键按下
{
count++; //按键计数加1
if(count==8) //计8次重新计数
{ count=0; } //将count 清零
}
while(BY1==0);//按键锁定,每按一次count 只加1.
}
}
-------------------------------------------------------------------------------------------------------------------------------------------
四.数码管动态显示
[实验任务]
P0端口接动态数码管的字形码笔段,P2端口接动态数码管的数位选择端,
动态显示“1234”字样;
[硬件电路]
注意:a接P0.0;b接P0.1;c接P0.3……
注意:4H接P2.4;3H接P2.5;2H接P2.6;1H接P2.7
[实验原理]
七段LED显示器内部由七个条形发光二极管和一个小圆点发光二极管组成,根据各管的极管的接线形式,可分成共阴极型和共阳极型。LED 数码管的 a-dp 七个发光二极管因以不同亮暗的组合就能形成不同的字形,这种组合称之为字形码。
下面给出共阴极的字形码:
TKVZ,
0 1 2 3 4 5 6 7 8 9 a b c d e f 0
0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e
1 2 3 4 5 6 7 8 9 a b c d e f
[C语言源程序]
#include <reg52.h>
code unsigned char seg7code[10]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,
0x82,0xf8,0x80,0x90}; //显示段码 数码管字跟:
//0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x40,
// 0 1 2 3 4 5 6 7 8 9 a b c d e f 0
//0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e
// 1 2 3 4 5 6 7 8 9 a b c d e f
Delay(unsigned int tc) //延时程序
{
while( tc != 0 ) //如果tc 为0 则终止延时
{
unsigned int i; //局部正整数变量 i
for(i=0; i<100; i++); //执行400 次将耗时1毫秒
tc--; //tc计数减一
}
}
void Led(int date) //显示函数
{
P2=P2&0x7f; //P2.7 输出低电平,选通千位数
P0=seg7code[date/1000]; //取出千位数,查表,输出。
Delay(8); //延时
P2=P2|0xf0; //销隐
P2=P2&0xbf; //P2.6 输出低电平,选通百位数
P0=seg7code[date%1000/100]; //取出百位数,查表,输出。
Delay(8); //延时
P2=P2|0xf0; //销隐
P2=P2&0xdf; //P2.5 输出低电平,选通十位数
P0=seg7code[date%100/10]; //取出十位数,查表,输出。
Delay(8); //延时
P2=P2|0xf0; //销隐
P2=P2&0xef;
P0=seg7code[date%10]; //取出个位数,查表,输出。
Delay(8);
P2=P2|0xf0;
}
/*
void Led(int date) //显示函数
{
qianwei=0;
P0=seg7code[date/1000]; //取出千位数,查表,输出。
qianwei=1;
baiwei=0;
P0=seg7code[date%1000/100]; //取出百位数,查表,输出。
baiwei=1;
shiwei=0;
P0=seg7code[date%100/10]; //取出十位数,查表,输出。
shiwei=1;
gewei=0;
P0=seg7code[date%10]; //取出个位数,查表,输出。
gewei=1;
}
*/
main()
{
int display_date=1234; //定义并赋值要显示的数据
while(1)
{
Led(display_date);//调用显示函数显示数据display_date
}
}
--------------------------------------------------------------------------------------------------------------------------------------------
五.4×4 矩阵式键盘识别
[实验任务]
用AT89S51的并行口P3接4×4矩阵键盘,以P3.0-P3.3作输入线,以P3.4
-P3.7作输出线;在每一个数码管上显示每个按键的“0-F”序号。
[硬件电路]
[实验原理]
每个按键有它的行值和列值 ,行值和列值的组合就是识别这个按键的编码。
矩阵的行线和列线分别通过两并行接口和CPU通信。键盘处理程序的任务是:确
定有无键按下,判断哪一个键按下,键的功能是什么;还要消除按键在闭合或断
开时的抖动。两个并行口中,一个输出扫描码,使按键逐行动态接地,另一个并
行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软
件查表,查出该键的功能。
[C语言源程序]
#include <reg52.h>
unsigned char code seg7code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e };
unsigned char k;
void delay10ms(void) //延时程序
{
unsigned char i,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
void Getch ( )
{ unsigned char X,Y,Z;
P3=0xff;
P3=0x0f; //先对P3 置数 行扫描
if(P3!=0x0f) //判断是否有键按下
{delay10ms(); //延时,软件去干扰
if(P3!=0x0f) //确认按键按下X = P3;
{
X=P3; //保存行扫描时有键按下时状态
P3=0xf0; //列扫描
Y=P3; //保存列扫描时有键按下时状态
Z=X|Y; //取出键值
switch ( Z ) //判断键值(那一个键按下)
{
case 0xee: k=0; break; //对键值赋值
case 0xde: k=1; break;
case 0xbe: k=2; break;
case 0x7e: k=3; break;
case 0xed: k=4; break;
case 0xdd: k=5; break;
case 0xbd: k=6; break;
case 0x7d: k=7; break;
case 0xeb: k=8; break;
case 0xdb: k=9; break;
case 0xbb: k=10;break;
case 0x7b: k=11;break;
case 0xe7: k=12;break;
case 0xd7: k=13;break;
case 0xb7: k=14;break;
case 0x77: k=15;break;
} } } } //请注意写程序时的格式规范,此处是为了节省纸张
void main(void)
{
while(1)
{ P3=0xff;
Getch();
P0=seg7code[k]; //查表LED输出
P2=0x0f; //输出相同的四位数据。
}
}