单片机应用技术0730 《C51单片机应用技术项目化教程》思考与习题详解Word文件下载.docx
《单片机应用技术0730 《C51单片机应用技术项目化教程》思考与习题详解Word文件下载.docx》由会员分享,可在线阅读,更多相关《单片机应用技术0730 《C51单片机应用技术项目化教程》思考与习题详解Word文件下载.docx(143页珍藏版)》请在冰豆网上搜索。
while
(1)
scan_num=0xfe;
//扫描初始值
for(i=0;
i<
8;
i++)//左移显示
P0=scan_num;
//送显示
P2=scan_num;
scan_num<
<
=1;
//左移一位
scan_num|=0x01;
//最低位补"
1"
delayms(300);
//延时300ms
//关闭LED显示
//延时300ms
scan_num=0x7f;
i++)//右移显示
scan_num>
>
//右移一位
scan_num|=0x80;
//最高位补"
1.6.2LED灯精确定时闪烁
【控制要求】在单片机的P0.0端口上接一个发光二极管L1,使L1不停地一亮一灭,一亮一灭的时间间隔为1s(要求利用定时器T0实现精确的1s定时),循环往复。
at89x51.h>
//reg51.h
sbitL1=P0^0;
unsignedchartime;
//软计数器
voidtime0(void);
//函数声明
time=20;
TH0=0x4c;
//定时50ms
TL0=0x00;
TMOD=0x01;
IE=0x82;
TR0=1;
//timer0run
while
(1)//等待中断
{L1=0;
//中断函数
voidtime0(void)interrupt1
time--;
if(time==0)
L1=~L1;
项目2设计数码管显示系统
2.6.1数码管字幕显示
【控制要求】用8位数码管显示从右向左移动显示“--HELLO—”。
//*************************************************************
数码管字幕移动显示
用8位数码管显示从右向左移动显示“--HELLO—”
//MCU:
AT89S52晶振:
11.0592MHz
//51芯片管脚定义头文件
#defineucharunsignedchar
#defineuintunsignedint
//--HELLO--
uchardisplay[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xBF,0xBF,0x89,0x86,0xC7,0xC7,0xC0,0xBF,0xBF,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
ucharshift,j=0;
charcodereserve[3]_at_0x3b;
//********************************************************
//ms延时子函数
voiddelayms(uintms)
uchart;
{for(t=0;
t<
t++);
//*******************************************************
//函数名称:
显示函数
//函数功能:
显示
voidledplay(void)
uchari;
shift=0xfe;
for(i=8;
i>
0;
i--)
P0=display[i+j];
P2=shift;
shift=(shift<
1)|0x01;
delayms
(1);
主函数
voidmain()
uchark;
P0=0xFF;
P2=0xFF;
for(j=0;
j<
17;
j++)
for(k=0;
125;
k++)
ledplay();
2.6.2数码管左移右移显示
P0端口接动态数码管的字形码笔段,P2端口接动态数码管的数位选择端,P1.0接一个开关,当开关接高电平时,显示“12345678”字样;
当开关接低电平时,显示“87654321”字样。
【硬件设计】
主控模块采用ATMEL公司生产的AT89S52单片机。
选用8段共阳极数码管,数码管的a、b、c、d、e、f、g、dp段分别与单片机P0口的P0.0、P0.1、P0.2、P0.3、P0.4、P0.5、P0.6、P0.7相连,用来控制显示数字的形状。
数码管的公共使能端COM连接三极管C8550的集电极,三极管C8550主要用于信号的放大,以驱动数码管工作。
三极管8550的基极通过限流电阻接到单片机P2口的P2.0,通过控制三极管C8550的基极电平来打开或关闭数码管的显示,起到“使能”作用。
三极管C8550的集电极接+5V电源。
动态数码显示模块与单片机的接口电路如图2-9所示。
图2-9动态数码显示模块与单片机的接口电路
【软件设计】
//*****************************************************
动态数码显示
当开关接高电平时,显示“12345678”;
//当开关接低电平时,显示“87654321”。
//******************************************************
reg51.h>
unsignedcharcodetable1[]={0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80};
unsignedcharcodetable2[]={0x80,0xf8,0x82,0x92,0x99,0xb0,0xa4,0xf9};
unsignedchari;
unsignedchart1,t2;
unsignedchartemp;
sbitK1=P1^0;
temp=0xfe;
for(i=0;
8;
i++)
if(K1==1){P0=table1[i];
else{P0=table2[i];
P2=temp;
temp=(temp<
1)|0x01;
for(t1=0;
t1<
4;
t1++)
{for(t2=0;
t2<
200;
t2++);
项目3设计按键识别系统
3.6.1多路开关状态指示
【控制要求】单片机AT89S52的P0.0~P0.3连接4个发光二极管L1~L4,P1.0~P1.3连接4个按钮开关K1~K4,编程将开关的状态反映到发光二极管上:
开关闭合,对应的灯亮;
开关断开,对应的灯灭。
AT89X51.H>
sbitK1=P1^0;
sbitLED1=P0^0;
sbitK2=P1^1;
sbitLED2=P0^1;
sbitK3=P1^2;
sbitLED3=P0^2;
sbitK4=P1^3;
sbitLED4=P0^3;
if(K1==0){LED1=0;
}//灯1亮
else{LED1=1;
}//灯1灭
if(K2==0){LED2=0;
}//灯2亮
else{LED2=1;
}//灯2灭
if(K3==0){LED3=0;
}//灯3亮
else{LED3=1;
}//灯3灭
if(K4==0){LED4=0;
}//灯4亮
else{LED4=1;
}//灯4灭
3.6.2一键多功能按键识别技术
【控制要求】开关K1接在P1.0管脚上,在AT89S51单片机的P0端口接有四个发光二极管,上电的时候,L1接在P0.0管脚上的发光二极管在闪烁,当每一次按下开关K1的时候,L2接在P0.1管脚上的发光二极管在闪烁,再按下开关K1的时候,L3接在P0.2管脚上的发光二极管在闪烁,再按下开关K1的时候,L4接在P0.3管脚上的发光二极管在闪烁,再按下开关K1的时候,又轮到L1在闪烁了,如此轮流下去。
reg51.H>
unsignedcharID;
voiddelay10ms(void)
unsignedchari,j;
for(i=20;
for(j=248;
j>
j--);
voiddelay02s(void)
{delay10ms();
if(P1_0==0)
delay10ms();
ID++;
if(ID==4){ID=0;
while(P1_0==0);
switch(ID)
case0:
P0_0=~P0_0;
delay02s();
break;
case1:
P0_1=~P0_1;
case2:
P0_2=~P0_2;
case3:
P0_3=~P0_3;
项目4设计报警器系统
4.6.1外部中断计数
【控制要求】利用单片机的外部中断功能进行计数,然后将计数值输出到数码管上显示。
按下K5键,计数值加1(外部中断0);
按下K6键,计数值减1(外部中断1);
采用3位数码管显示,最大计数值255。
//************************************************************
INT0、INT1中断计数
//功能:
通过连接在INT0和INT1的按键K5与K6实现程序
//对外部中断次数进行计//数,计数值显示在7段数码管上。
//INT0(K5):
计数值递增
//INT1(K6):
计数值递减
unsignedcharcodeLEDData[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff};
//段码
unsignedchardatadisplay[3];
//显示缓存单元
unsignedcharcodescan_bit[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
//位码
unsignedcharcount;
//计数单元
charcodereserve[3]_at_0x3b;
{for(k=0;
//数据处理与显示函数
voiddisp_count()
unsignedcharn,temp;
temp=count;
//数据处理
for(n=0;
n<
n++)
display[n]=temp%10;
temp=temp/10;
display[2]=temp;
//百位数据
//高位为0,不显示
for(n=2;
n>
n--)
if(display[n]==0)display[n]=0x0a;
elsebreak;
3;
P0=LEDData[display[n]];
//显示段码
P2=scan_bit[n];
//输出位码
//关闭显示
P1=0xff;
IT0=0;
//低电平触发;
如IT0=1为下降沿触发
IT1=0;
EA=1;
//总中断允许
EX1=1;
//开启INT1中断
EX0=1;
//开启INT0中断
disp_count();
//数码管显示
//INT0中断函数(加计数)
voidINT0_ISR(void)interrupt0
unsignedcharx;
EX0=0;
//关闭INT0中断
count++;
//计数值加1
//用显示程序进行延时
for(x=0;
x<
70;
x++)
{disp_count();
//INT1中断函数(减计数)
voidINT1_ISR(void)interrupt2
EX1=0;
//关闭INT1中断
count--;
//计数值减1
for(x=0;
{disp_count();
4.6.2产生“叮咚”门铃声
【控制要求】当按下开关SP1(接P1.4)时,单片机产生“叮咚”声,从蜂鸣器(接P3.7)输出。
sbitP1_4=P1^4;
sbitP3_7=P3^7;
unsignedchart5hz;
unsignedchart7hz;
unsignedinttcnt;
bitstop;
bitflag;
TMOD=0x02;
//00000010—方式2
TH0=0x06;
TL0=0x06;
ET0=1;
if(P1_4==0)
for(i=10;
t5hz=0;
t7hz=0;
tcnt=0;
flag=0;
stop=0;
while(stop==0);
//中断程序
voidt0(void)interrupt1using0
tcnt++;
if(tcnt==200)
if(flag==0)
flag=~flag;
else
stop=1;
TR0=0;
t7hz++;
if(t7hz==3)
P3_7=~P3_7;
t5hz++;
if(t5hz==4)
4.6.3演奏音乐
【控制要求】演唱“两只老虎”:
单片机的P3.7外接扬声器,利用定时/计数器与中断唱出音乐“两只老虎”,其乐谱如下:
|1231|1231|345-|345-|
|565431|565431|151-|151-|
sbitloudspeaker=P3^7;
//音阶musical_scale
uintcodemusical_scale[]={64580,64684,64777,64820,64898,64968,65030,
64260,65058};
//(65536-x)1us=1912us/2x=65536-856=64580
//乐谱music_score
//0x14,0x24,0x34,0x14;
//0x14,0x24,0x34,0x14
//0x34,0x44,0x58
//0x52,,0x62,0x52,0x42,0x34,0x14
//0x52,,0x62,0x52,0x42,0