单片机测试程序.docx
《单片机测试程序.docx》由会员分享,可在线阅读,更多相关《单片机测试程序.docx(44页珍藏版)》请在冰豆网上搜索。
单片机测试程序
实习步骤
本单片机最小系统是以AT89S51单片机为控制核心,由驱动芯片ZLG7289与16键的键盘矩阵实现对两个4位一体共阴数码管LED的驱动显示,由LCD1602实现液晶显示,再通过电平转换芯片MAX232并连接到232接口实现串口通信,系统还包含有蜂鸣器,USB及适配器供电接口,JTAG程序下载接口,总线扩展等。
首先,用protel99se软件制作硬件电路原理图及绘制PCB板;其次,安装焊接单片机最小系统开发板及下载线,并且进行电路调试;再次,在KeiluVision2软件环境下调试单片机汇编程序或C语言程序,用单片机下载软件ISPLAY或STC-ISPV31实现程序下载,从而用编程实现最小系统的基本功能;最后,编写综合程序以实现系统功能的综合以及拓展功能,其中串口通信用到电脑自带的超级终端或AccessPort软件。
单片机最小系统板焊接
首先对照元件清单和电路图,检查器件是否完整,型号﹑规格﹑安装是否正确。
然后将各器件根据焊接规则焊接到电路板上,其中对于器件的摆放方向和位置需十分注意。
先焊发热器件电阻和较低的电容,再焊较大的器件,焊接JTAG线,JTAG线里面的芯片电阻,电阻电容均为贴片封装,焊接时需小心谨慎,对于各条线引的焊接也需谨慎,按照其对应的顺序进行焊接,焊接结束后,自行组装。
检查已经焊好的电路板和JTAG下载线是否无误:
⑴先用万用表检查电路板焊接是否都正确。
⑵当检查没有短路,断路,虚焊,漏焊等错误后,给电路板供电,看二极管是否亮,是否有器件过热,有可能二极管或三极管会在焊接的过程中被烧坏,那样的话就要重新焊器件。
⑶再用Keil软件给板子拷正确的程序,检查是否能按功能正常工作。
单片机系统的硬件调试和软件调试是不能分开的,许多硬件错误是在软件调试中被发现和纠正的。
软件设计
在Keil软件环境下对照相关资料编写单片机最小系统开发板的有用程序,使设计好的程序编译无误,得到hex格式文件,用程序下载软件加载到单片机芯片中,实现仿真电路,在板上得出效果。
设计工具:
电脑,Keil软件,Isplay软件,STC-ISPV31软件
蜂鸣器调试
主要是检验程序能否下载到芯片,蜂鸣器能正常工作,掌握程序的编译下载到芯片的方法。
⑴在Keil环境中用C语言编写简单是蜂鸣器程序或音乐播放程序。
⑵对Keil软件和程序下载软件进行相关配置设置。
⑶将编译产生的hex文件下载到芯片,检测其工作是否正常,若工作不正常,则从软件及硬件两方面进行检查。
有用的报警声程序见附录4
串口通信调试
实现计算机与单片机之间相互通讯功能
⑴将编写的串口调试程序经过编译,下载到单片机。
⑵串口实现功能为在计算机上能显示单片机的输出。
检测串口是否能正常工作,此阶段需用到串口软件及串口线。
若不能正常工作,则需从软件和硬件两方面进行检查。
⑶正确功能为在电脑超级终端不停显示输出内容,与预期相同,工作正常。
液晶显示调试
保证液晶屏LCD能正常工作,输出效果有所扩展。
⑴在编写程序前,认真阅读LCD液晶屏资料,掌握LCD1602及1602液晶模块数据手册(中文)中的液晶的使用和编程方法,了解其工作时序,及各个指令及初始化。
⑵对照电路图中LCD连接情况,编写LCD1602移动显示程序,经编译下载至单片机,检测输出,若无输出,则调整电位器,若仍无输出则从软件及硬件两方面进行检查,找出错误原因,直至液晶屏能正常工作。
⑶在程序编写时应时刻注意各个指令间的延时控制。
以保证液晶屏呈现效果移动循环显示,液晶屏工作正常。
之后也可用LCD做数字钟,这将在综合程序里被用到,液晶移屏显示程序见附录6
数码管及键盘控制调试
保证数码管能正常显示,以及按键能控制数码管的显示.
⑴在编写程序前,应认真阅读LED和ZLG7289A资料,了解和掌握其工作时序,及各个指令及初始化,在程序编写时应时刻注意各个指令间的延时控制。
⑵对照电路图中ZLG7289模块的连接情况,编写程序,经过编译,然后下载到单片机,检测展现效果,是否与程序预期相同。
⑶实现效果逐个闪烁,逐个消隐,键盘控制改变数据并移动,与预期相同,工作状态正常。
﹑再利用单片机内部时钟中断,编写数码管时钟程序,使数码管能够实现计时功能,键盘能够控制时分秒。
系统综合功能设计
综合单片机开发板上的各个功能模块,以实现一个完整的系统功能:
⑴根据前面对各模块功能的理解和程序编写,结合各个模块实现一个整体系统,把各模块功能综合起来。
⑵设计一综合系统,使数码管实现数字钟且可右移﹑闪烁,液晶屏实现时间、日期的显示且可移屏,键盘能够控制系统,蜂鸣器与键盘且可整点报时,可实现串口通信功能。
鸣器调试程序
本程序根据蜂鸣器与单片机P3.3口相连设计,可以验证单片机及下载功能的正确.
#include
#include
sbitbuz=P3^3;
unsignedcharflag;
voiddelayms(unsignedcharms)
/*延时子程序*/
{
unsignedchari;
while(ms--)
{
for(i=0;i<120;i++);
}
}
/*主程序*/
main()
{
TMOD=0x01;
flag=0x00;
TH0=0x00;
TL0=0xff;
TR0=1;
IE=0x82;
while
(1)
{
flag++;
delayms
(1);
}
}
/*中断控制*/
voidtimer0()interrupt1using1
{
TH0=0xfe;
TL0=frq;
buz=~buz;
}
串口通信调试程序(单片机到PC机)
此为串口通信程序,可在电脑上的超级终端显示相关语句,实现单片机与电脑的相互通信。
遇到的问题:
在进行单片机传信息到电脑终端时,可是利用宏文件,直接调用printf.但是在实际的运用中占用大量的空间资源,而且容易出现错误,让程序的工作不正常,因此我们改用字节的传送,利用串口一个字节一个字节的传送,这样就大大增加了程序的可读性。
#include/*specialfunctionregisterdeclarations*/
/*fortheintended8051derivative*/
#include/*prototypedeclarationsforI/Ofunctions*/
#ifdefMONITOR51/*DebuggingwithMonitor-51needs*/
charcodereserve[3]_at_0x23;/*spaceforserialinterruptif*/
#endif/*StopExectionwithSerialIntr.isenabled*/
/*------------------------------------------------
ThemainCfunction.Programexecutionstarts
hereafterstackinitialization.
------------------------------------------------*/
voidmain(void){
/*------------------------------------------------
Setuptheserialportfor1200baudat12MHz.
------------------------------------------------*/
#ifndefMONITOR51
SCON=0x50;/*SCON:
mode1,8-bitUART,enablercvr*/
TMOD|=0x20;/*TMOD:
timer1,mode2,8-bitreload*/
TH1=0xe6;/*TH1:
reloadvaluefor1200baud@12MHz*/
TR1=1;/*TR1:
timer1run*/
TI=1;/*TI:
setTItosendfirstcharofUART*/
#endif
/*------------------------------------------------
Notethatanembeddedprogramneverexits(because
thereisnooperatingsystemtoreturnto).It
mustloopandexecuteforever.
------------------------------------------------*/
while
(1){
printf("liujinglong\n");/*Print"liujinglong"*/
}
}
串口通信调试程序(PC机到单片机)
#include
#include
#include<1602.h>
#defineucharunsignedchar
#defineuintunsignedint
UchardataReceiveBuffer[16]={0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0x20,0x20,0x20,0x20,0x20,0x20,0x20};//设置16字节的串行通信接收缓冲区
uchardataBufferPointer=0;//串行通信接收缓冲区指针,初始为0
bitdataOnReceive=0;//串行通信接收事件标志位
voidSend(uchardatadat);
/*以下为串行通信接收中断处理函数*/
voidserialport(void)interrupt4using2
{
uchardatac,i;
if(RI)
{
c=SBUF;//读取接收到的数据
if(BufferPointer<16)
{
ReceiveBuffer[BufferPointer]=c;//将接收到的数据存入接收缓冲区
BufferPointer++;
}
else
{
for(i=0;i<15;i++)
{
ReceiveBuffer[i]=ReceiveBuffer[i+1];//将缓冲区数据左移
}
ReceiveBuffer[15]=c;//将接收到的数据存入接收缓冲区
}
RI=0;//清空接收标志
Send(c);//发送接收到的数据,以便回显
OnReceive=1;//接收事标志位置1
}
}
/*以下为串口初始化函数*/
voidInitserialport(void)
{
TMOD=0x20;
SCON=0x50;
TH1=0xe6;/*TH1:
reloadvaluefor1200baud@16MHz*/
ES=1;//允许串口中断
EA=1;
TR1=1;/*TR1:
timer1run*/
}
voidSend(uchardatadat)
{
SBUF=dat;
while(TI==0);
TI=0;
}
voidmain(void)//主函数
{
uchardatai;
LcdReset();//初始化LCD
Initserialport();//初始化串口
DisplayListChar(0,0,"ReceiveData:
",13);
while
(1)
{
if(OnReceive)
{
for(i=0;i<16;i++)//接收显示
{
DispOneChar(i,1,ReceiveBuffer[i]);
}
OnReceive=0;
}
}
}
液晶移屏显示程序
实现LCD1602的基本显示功能,以及使其能够实现移屏功能。
#include
#defineucharunsignedchar
#defineuintunsignedint
ucharcodedispcode1[]={"happynewyear!
!
"};
ucharcodedispcode2[]={"thankseveryday!
"};
sbitRS=P2^0;
sbitRW=P2^1;
sbitE=P2^2;
voiddelay(uintt)
{
uintk,l;
for(k=t;k>0;k--)
for(l=0;l<=10;l++);
}
voidwcom()
{
RS=0;RW=0;E=0;delay(1000);E=1;
}
voidwdata()
{
RS=1;RW=0;E=0;delay(1000);E=1;
}
voidinit()//初始化子程序
{
//uinti;
//for(i=0;i<20;i++)
P0=0x38;wcom();//指令码设置16×2显示,8位数据接口
P0=0x0c;wcom();//开显示,不显示光标,不闪烁光标
P0=0x06;wcom();//读或写一个字符后地址累加器加一,光标加一
P0=0x01;wcom();//清屏
}
voidmain()//主函数显示
{
uchari;
init();
P0=0x80;
wcom();
for(i=0;i<=15;i++)
{
P0=dispcode1[i];
wdata();
}
P0=0xC0;
wcom();
for(i=0;i<=15;i++)
{
P0=dispcode2[i];
wdata();
}
for(i=0;i<=40;i++)
{
P0=0x1c;
wcom();
delay(100);
}
}
ZLG7289控制键盘及数码管显示程序
本程序根据ZLG7289芯片资料,来实现其对数码管和键盘的控制。
首先在数码管上显示0-7八位数,然后循环左右各移八次,再分别左移右移各两次,而后实现闪烁﹑消隐功能,再是按键时可以在数码管显示按键值,如没有按键则显示时钟,而且可用键盘对时钟的时分秒进行校对。
#include
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
/*端口定义*/
sbitCS=P1^0;
sbitCLK=P1^1;
sbitDIO=P1^2;
sbitKEY=P3^2;
//需要在INT区把KEY用跳线冒跳到INT0,其余四个跳到VCC
//这样,P3^2就相当于直接连接到key
bdataucharcom_data;//定义8位数据data
sbitmos_bit=com_data^7;
sbitlow_bit=com_data^0;
/*变量定义*/
ucharhalf_hign;
ucharhalf_low;
ucharsl,sh,ml,mh,hh,hl;
ucharsecond=0;
ucharminute=0;
ucharhour=12;
uints_cnt,key;
/*延时子程序*/
voiddelay_8us()
{
uchari;
for(i=0;i<1;i++){;}
}
voiddelay_50us()
{
uchari;
for(i=0;i<6;i++){;}
}
voiddelay_50ms()
{
uchari,j;
for(j=0;j<50;j++)
for(i=0;i<125;i++){;}
}
voiddelay_1s()
{
uchari=20;
while(i--)
delay_50ms();
}
voiddelay_2s()
{
uchari=40;
while(i--)
delay_50ms();
}
voiddelay_5s()
{
uchari=100;
while(i--)
delay_50ms();
}
/*发送单字节指令*/
voidsend(ucharsebuf)
{
uchari;
com_data=sebuf;
CLK=0;
CS=0;
delay_50us();
for(i=0;i<8;i++)
{
delay_8us();
DIO=mos_bit;
CLK=1;
delay_8us();
com_data=com_data<<1;
CLK=0;
}
DIO=0;
}
/*接收数据*/
ucharreceive(void)
{
uchari,rebuf;
CLK=1;
delay_50us();
for(i=0;i<8;i++)
{
com_data=com_data<<1;
low_bit=DIO;
CLK=1;
delay_8us();
CLK=0;
delay_8us();
}
rebuf=com_data;
DIO=1;
CS=1;
returnrebuf;
}
/*复位*/
voidreset(void)
{
DIO=1;
delay_50ms();
send(0xa4);
CS=1;
}
/*7289数码管显示,addr为显示位置范围0~7,dat为现实内容*/
voiddisplay(ucharaddr,uchardat)
{
if(addr<0||addr>7)
return;
send(0xc8+addr);
delay_50us();
send(dat);
CS=1;
}
/*功能:
执行ZLG7289纯指令参数:
cmd:
命令字*/
voidZLG(uchart)
{
CS=0;
delay_50us();
send(t);
CS=1;
delay_50us();
}
/*发送双字节命令*/
voidsendcommand(ucharaddr,uchardat)
{
send(addr);
delay_50us();
send(dat);
CS=1;
}
/*获取键盘的位置码*/
uchargetkeycode(uchardat)
{
ucharkey;
switch(dat)
{
case0x00:
key=0x00;break;
case0x01:
key=0x01;break;
case0x02:
key=0x02;break;
case0x03:
key=0x03;break;
case0x04:
key=0x04;break;
case0x05:
key=0x05;break;
case0x06:
key=0x06;break;
case0x07:
key=0x07;break;
case0x08:
key=0x08;break;
case0x09:
key=0x09;break;
case0x0a:
key=0x10;break;
case0x0b:
key=0x11;break;
case0x0c:
key=0x12;break;
case0x0d:
key=0x13;break;
case0x0e:
key=0x14;break;
case0x0f:
key=0x15;break;
default:
key=0xee;break;
}
returnkey;
}
/*7289按键指令*/
ZLG7289_Key()
{
ucharkey,dat;
send(0x15);
delay_50us();
dat=receive();
delay_50us();
key=getkeycode(dat);
}
/*按键设定时分加一*/
voidSet_time(void)//设定时间
{if(key==0x00)//按键0,控制时
{
delay_50ms();
if(key==0x00)
{
hour++;
if(hour==24)
{
hour=0;
}
hl=hour%10;
hh=hour/10;
}
}
if(key==0x01)//按键1,控制分
{
delay_50ms();
if(key==0x01)
{
minute++;
if(minute==60)
{
minute=0;
}
ml=minute%10;
mh=minute/10;
}
}
if(key==0x02)//按键2,控制秒
{
delay_50ms();
if(key==0x02)
{
second++;
if(second==60)
{
second=0;
}
sl=second%10;
sh=second/10;
}
}
hh=hour/10;hl=hour%10;
mh=minute/10;ml=minute%10;
sh=second/10;sl=second%10;
}
/*定时器中断初始化*/
voidInit(void)//初始化子程序
{
IP=0x02;
EX0=1;
TMOD=0x02;//0.25ms
TH0=0x06;
TL0=0x06;
EA=1;
ET0=1;
TR0=1;
}
/*中断控制*/
voidservice_int0()interrupt0
{
EX0=0;
TR0=0;
key=ZLG7289_Key();
Set_time();
delay_1s();
EX0=1;
TR0=1;
}
/*中断控