for(j=0;j<100;j++);
}
voidwr_com(ucharcom)//写指令
{delay1ms
(1);
RS=0;
RW=0;
EN=0;
P0=com;
delay1ms
(1);
EN=1;
delay1ms
(1);
EN=0;
}
voidwr_dat(uchardat)//写数据
{delay1ms
(1);;
RS=1;
RW=0;
EN=0;
P0=dat;
delay1ms
(1);
EN=1;
delay1ms
(1);
EN=0;
}
voidlcd_init()//初始化设置
{
delay1ms(15);
wr_com(0x38);
delay1ms(5);
wr_com(0x08);
delay1ms(5);
wr_com(0x01);
delay1ms(5);
wr_com(0x06);
delay1ms(5);
wr_com(0x0c);
delay1ms(5);
}
voidxianshi()//LCD1602显示函数(显示第一行的固定文字)
{
uinti;
for(i=0;i<14;i++)
{
wr_com(0x80+i);
wr_dat(s1[i]);
}
}
voidflag_xianshi()//显示当前LED的状态(跟按键是否按下有关)
{
uintj;
if(flag==1)
{
for(j=0;j<8;j++)
{
wr_com(0xc0+j);
wr_dat(s2[j]);
}
}
elseif(flag==0)
{
for(j=0;j<8;j++)
{
wr_com(0xc0+j);
wr_dat(s3[j]);
}
}
}
voidkey()//键盘扫描函数
{
if(key1==0)//按键按下
{
delay(5);
while(key1!
=1);//检测按键是否放开
i++;//用来计算按的次数
if(i%2==1)//当按的是奇数下,点亮LED
{
temp=0;
flag=1;
}
Else//偶数下,LED熄灭
{
temp=1;
i=0;//清零I(可有可无)
flag=0;
}
}
}
voidinit()//中断初始化
{
TMOD=0x20;
TH1=0xfd;//设置波特率为9600
TL1=0xfd;
SCON=0x40;//设置串口方式1,只发送不接收
PCON=0x00;//SMOD=0
ES=1;//允许串口中断
EA=1;//开总中断
TR1=1;//启动定时器T1
}
voidmain()
{
lcd_init();//先初始化1602显示函数
init();//中断初始化
xianshi();//在这里调用显示函数的原因是因为1602第一行为固定显示,所以可以不用参与循环
while
(1)
{
key();//检测是否有按键按下
flag_xianshi();//显示LED状态
SBUF=temp;//temp的数据送给串行口发送
while(TI==0);//等待数据,也可以说是检测数据是否发送完
TI=0;//已发送完,就清零T1
}
}
(2)从机程序
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitled=P2^0;
voidinit()//中断初始化
{
TMOD=0x20;
TH1=0xfd;//设置波特率为9600
TL1=0xfd;
SCON=0x40;//设置串口方式1,只发送不接收
PCON=0x00;//SMOD=0
ES=1;//允许串口中断
EA=1;//开总中断
TR1=1;//启动定时器T1
}
voidmain()
{
init();
while
(1)
{
while(RI==0);//等待数据,也可以用来判断数据是否接收完毕
RI=0;//数据接收完毕,清零RI
led=SBUF;//数据直接送给IO口,控制LED的亮灭
}
}
四.实物展示
实物图
PCB
五.元件汇总
元件名
数量
单位
AT89C51
2
片
103蓝白电位器
1
个
40脚芯片底座
2
个
20脚排针
5
条
轻触开关
6
个
220Ω电阻
10
个
2K电阻
2
个
红色LED
8
个
11.0592MHz晶振
2
个
LCD1602
1
个
22PF瓷片电容
4
个
10uf电解电容
2
个
103排阻
2
条
杜邦线
2
条
单面覆铜板
1
片
六.心得体会
这次单片机实训收获还是有的!
本来没打算做双机通信的,但是其他的题目都已经有接触了,所以后来还是选了一个以前没接触过的东西玩玩,毕竟能学到东西才是王道!
没想到,瞎猫碰到死耗子了,以为双机通信很难,结果却是所有实训题目里面最简单的。
真是有够意外的。
很顺利的在第一天就把仿真和程序给搞定了,这个跟有扎实的程序思维是密不可分的。
然后接下来解释调试了。
。
本打算直接用实验室的单片机学习板进行调试的。
后来发现,太麻烦了,还是自己做块板吧,反正时间多着呢。
周二搞定原理图,周二晚上搞定PCB,整个过程有条不紊的进行的。
好了,本以为本次实训能完美收场的,结果是我想太多了。
周三整天都是在帮同学,指导程序啊,知道原理图,别人的完成了自己的到是落下了。
制版过程浪费太多时间了,终于在周四做好了板。
因为实训只剩最后一天了,我还没开始焊元器件,以及调试。
我开始有些着急了。
人越急,就越容易出错。
就因为这个小小的错误,我让我调试付出了太多时间。
所以,做事千万要沉得住气,别急慢慢来。
下面,讲讲我调试遇到的麻烦吧。
第一次调试,当板接上电源,整个板完全没反应,LCD1602没亮。
用万用表检测了所有的线路,没有出现断路现象,均连接正常,LCD1602就是不亮,在继续查资料,后来终于发现问题所在,原来是背光没连接电源。
所以直接用跳线将LCD1602最后两个引脚A,K脸上VCC和GND。
LCD1602搞定,终于可以亮了,本以为成功了一半,但是后来才知道,还远远没有结束。
第二次调试,接好LCD1602的A,K。
分别给主机,和从机烧入程序。
1602没有显示字符,按键,按下,LED没有反应。
问题出现,继续找原因。
刚开始以为是程序问题,原理图的连接,和程序的IO口声明出现了错误,后来经过检测,程序没问题,IO口声明也没问题。
那最有可能是单片机的系统没工作。
用万用表检测了单片机引脚与排针的连接,均是正常的,检查复位电路,振荡电路,终于找到了问题所在,原来我把振荡电路的两个瓷片电容的数值焊错了。
本来要22PF的瓷片电容,我换成了103瓷片电容,好吧,问题发现,从新换上22PF的电容。
第三次调试,整个系统还是不能工作,把前两次的工作从新做了一遍,还是没发现问题。
当时时间已经过了1礼拜,差点跪了。
。
太折磨人了。
后来在看PCB时,无意间让我看到了一目,下面附图:
可能这样看不是很明显,好我们放大看看:
这下看清楚了吧!
!
坑爹啊~~!
!
我竟然没有还有一条线没连到GND,我靠还有一条线躲在那里啊!
!
这就是我辛辛苦苦排查的原因的,竟然是忘了连一天GND。
所以说:
画板需谨慎,注意看看那些线没连的,电路板的每条线都是关键!
!
元器件参数要认真看,本来都是不必要的问题,却因为我的粗心大意,浪费了那么多时间,可惜啊~!
!
以上就是我这次实训的体会了,说多了都是泪和累啊!
七.参考文献
【1】单片机原理及应用—C51编程+Proteus仿真主编:
张毅刚出版社:
高等教育出版社
【2】AltiumDesigner电子设计应用教程主编:
高歌出版社:
清华大学出版社