51单片机汇编程序5.docx
《51单片机汇编程序5.docx》由会员分享,可在线阅读,更多相关《51单片机汇编程序5.docx(14页珍藏版)》请在冰点文库上搜索。
51单片机汇编程序5
§5.3.2 系统软件设计
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
/*IC卡信号输入输出*/
sbitscl=P1^7;
sbitsda=P1^6;
/*I/O口定义*/
sbitICOUT=P3^2;/*拔卡信号*/
sbitICIN=P3^3;/*插卡信号,与上同接卡座微动开关*/
sbitCOMM=P3^4;/*正在通信指示*/
sbitBELL=P3^5;/*蜂鸣器控制*/
sbitPWR=P1^4;/*IC卡座电源控制*/
/*波特率选择*/
sbitBAUD=P1^2;/*0:
2400;1:
4800*/
/*24c01-24c16读写驱动程序,*/
sbita0=ACC^0;/*定义ACC的位,利用ACC操作速度最快*/
sbita1=ACC^1;
sbita2=ACC^2;
sbita3=ACC^3;
sbita4=ACC^4;
sbita5=ACC^5;
sbita6=ACC^6;
sbita7=ACC^7;
/*读写数据缓冲区,24C01最多为128字节*/
ucharbuf[16];/*这里定义有效读入数据最多为16字节,用户根据需要定*/
ucharflag;/*全局标志字节*/
/*标志定义*/
sbitIC_WR=flag^0;/*IC卡在读写状态标志*/
sbitONCOMM=flag^1;/*系统与上位机在通信状态标志*/
sbitRST=flag^2;/*系统热复位标志*/
voidstart_ic(void)
{
sda=1;
scl=1;
delay
(2);
sda=0;/*scl为高状态下,sda的下降调变启动*/
delay(6);
scl=0;
delay(6);
}
voidstop_ic(void)
{
sda=0;
scl=1;
delay(6);
sda=1;/*在scl=1,sda的0到1跳变结束*/
delay(6);
scl=0;
sda=0;
}
voidack_ic(void)
{
sda=0;
delay(3);
scl=1;
delay(3);
scl=0;
sda=1;
}
/*读字节函数,无应答信号*/
unsignedcharrd24(void)
{
sda=1;
scl=1;a7=sda;scl=0;
scl=1;a6=sda;scl=0;
scl=1;a5=sda;scl=0;
scl=1;a4=sda;scl=0;
scl=1;a3=sda;scl=0;
scl=1;a2=sda;scl=0;
scl=1;a1=sda;scl=0;
scl=1;a0=sda;scl=0;
sda=1;scl=1;scl=0;
return(ACC);
}
/*写字节函数*/
voidwd24(unsignedchardd){
ACC=dd;
sda=a7;scl=1;scl=0;
sda=a6;scl=1;scl=0;
sda=a5;scl=1;scl=0;
sda=a4;scl=1;scl=0;
sda=a3;scl=1;scl=0;
sda=a2;scl=1;scl=0;
sda=a1;scl=1;scl=0;
sda=a0;scl=1;scl=0;
sda=1;scl=1;
while(sda==1);/*等待EEPROM应答*/
SCL=0;
}
/*随机地址读字节函数,address为欲读单元地址*/
ucharread_byter(ucharaddress)
{
ucharx;
start_ic();
wd24(0a0);
wd24(address);
start_ic();
wd24(0a1);
x=rd24();
stop_ic();
return(x);
}
/*从指定地址开始顺序地址读块数据,数据存入全局缓冲区buf中,n为数据字节数*/
ucharread_bytes(ucharaddress,ucharn)
{
uchara,y;
for(y=0;y{
a=read_byter(address+y);
buf[y]=a;
}
}
/**/
/*字节写入模式写函数,其中address为单元地址,dd为数据*/
voidwrite_byte(ucharaddress,uchardd)
{
start_ic();
wd24(0a0);
wd24(address);
wd24(dd);
stop_ic();
}
/*串行通讯子程序*/
/*拨特率2400,8位数据、1停止位、无校验*/
/*先用握手字节y,然后发送x个数据*/
/*待发送数据在trdata缓冲区中*/
voidcomm(ucharx,uchary)
{
uchari,a;
uintj;
while
(1)
{l1:
while(RI==0);
RI=0;
a=SBUF;
if(a!
=y)gotol1;
for(i=0;i{SBUF=trdata[i];
while(TI==0);
TI=0;
}
for(j=0;j<12500;j++);
}
}
/*主程序初始化函数*/
voidinit(void)
{
RST=0;/*系统热复位标志清除,只有拔卡才能置位*/
PWR=1;/*关闭IC卡电源*/
IC_WR=0;/*清有卡标志*/
ONCOMM=0;/*清正在通信标志*/
EX0=1;/*允许INT0中断*/
TMOD=0x20;
SCON=0x50;/*串行口工作方式,*/
TH1=0xf3;TL1=0xf3;
if(BAUD==0)
{
PCON=0x80;/*波特率设置为2400*/
}
else
{
PCON=0x00;/*波特率设置为4800*/
}
TR1=1;
EA=1;/*开放中断*/
}
/*将缓冲区数据16字节发往上位机*/
/*拨特率2400,8位数据、1停止位、无校验*/
/*待发送数据在buf缓冲区中*/
voidtransfer(void)
{
uchari;
uintj;
for(i=0;i<16;i++)
{SBUF=buf[i];
while(TI==0);
TI=0;
for(j=0;j<1000;j++);
}
}
/*接收16字节存入缓冲区*/
/*拨特率2400,8位数据、1停止位、无校验*/
/*缓冲区为buf*/
voidreceive(void)
{
uchari,a;
for(i=0;i<16;i++)
{ while(RI==0);
RI=0;
a=SBUF;
buf[i]=a;
}
}
/*将缓冲区中的n字节写入IC卡address开始的区域*/
voidwrite_ic(ucharaddress,ucharn)
{
ucharx,y;
for(y=0;y{
write_byte(address+y,buf[y]);
delay(10);/*写之间的延时时间间隔,以保证写入*/
}
}
/*拔卡中断程序,主要完成IC卡下电及读写器软复位*/
voidint_0(void)interrupt0using1
{
while(!
ICOUT);/*延时去抖*/
delay(10);
if(!
ICOUT)/*确实拔卡则进行以下处理*/
{
if(IC_WR|ONCOMM)
{
PWR=1;/*关闭IC卡电源*/
BELL=0;/*否则,则蜂鸣一声返回*/
delay(10);
BELL=1;
RST=1;/*设置热复位标志,以便热复位*/
}
}
}
/*延时函数,延时ms数由N决定,但不同的系统需要调整相应参数*/
voiddelay(ucharn)
{
uchari,j,k;
for(k=0;kfor(i=0;i<100;i++)
for(j=0;j<255;j++);
}
voidmain(void)
{
uchara;
fuwei:
init();/*系统初始化*/
while(!
ICIN);/*等待IC卡插入*/
delay(10);/*软件去抖并等待IC卡稳定*/
while(!
ICIN);/*确认IC卡插入*/
IC_WR=1;/*设置读写卡标志(有卡,以便避免带电插拔)*/
/*开始读IC卡16字节并存入缓冲区*/
PWR=0;/*IC卡上电,以便读卡*/
read_bytes(0,16);
PWR=1;/*关IC卡电源*/
/*等待与上位机建立通信联系*/
ONCOMM=1;/*设置正在通信标志*/
while(RI==0);
RI=0;
a=SBUF;
switch(a)
{case0xaa:
SBUF=0xaa;
while(!
TI);/*向上位机回送AA*/
TI=0;
transfer();/*将缓冲区数据发往上位机*/
break;
case0xbb:
SBUF=0xbb;
while(!
TI);/*向上位机回送BB*/
TI=0;
/*上位机在发送前必须适当延时,以等待下位机准备好*/
receive();/*接收数据存放在缓冲区*/
PWR=0;/*IC卡上电*/
write_ic(0,16);/*将数据写入IC卡,并回读比较*/
PWR=1;/*IC卡下电*/
break;
default:
SBUF=0xcc;/*如果握手信号不是AA、BB,则*/
while(!
TI);/*向上位机回送CC*/
TI=0;
}
ONCOMM=0;/*清正在通信标志*/
while(!
RST);
gotofuwei;/*等待拔卡中断以软复位*/
}
§5.4 上位PC机通讯接口软件
libraryMycomdll;
usesSysUtils,
Classes;
Const
COM1:
=$3f8;
COM2:
=$2f8;
Var
COM:
Word;{DLL中全局变量}
ProcedureOutb(ConstPort:
Word;ConstDbyte:
Byte);pascal;
Begin
Asm
MOVDX,Port
MOVAL,Dbyte
OUTDX,AL
End;
End;
FunctionInb(ConstPort:
Word):
Byte;pascal;
Begin
Asm
MOVDX,Port
INAL,DX
MOV@Result,AL
End;
End;
{串行口初始化,COM1、COM2可选,波特率2400、4800可选}
ProcedureCommInit(ConstPort:
Byte;ConstBaud:
String);Stdcall;
Var
BAUDL,BAUDH:
Byte;
Begin
IfPort=1then
COM:
=COM1;
Else
COM:
=COM2;
IfBAUD=’2400’then
Begin
BAUDL:
=$30;
BAUDH:
=$00;
End;
Else
Begin
BAUDL:
=$18;
BAUDH:
=$00;
End;
Outb(COM+3,$80);{设置波特率因子}
Outb(COM,BAUDL);
Outb(COM+1,BAUDH);
Outb(COM+3,$03);{8位数据,1停止位,无校验}
End;
{发送一字节}
ProcedureSendByte(ConstDbyte:
Byte);Stdcall;
Var
Status:
Byte;
Begin
Repeat
Status:
=Inb(COM+5);
Until((Statusand$20)=$20);
Outb(COM,Dbyte);
End;
FunctionReceiveByte:
Byte;Stdcall;
Var
Status,Res:
Byte;
Begin
Repeat:
Status:
=Inb(COM+5);
Until((Statusand$01)=$01);
Res:
=Inb(COM);
ReceiveByte:
=Res;
End;
{以下用EXPORT引出输出过程或函数}
ExportCommInit;
ExportSendByte;
ExportReceiveByte;
Begin
End.