#define SBUF 0x3f8#define baudL 0x3f8
#define baudH 0x3f9#define LineCtrl 0x3fb
#define ModemCtrl 0x3fc
#define LineStatus 0x3fd
#define LINE 6
#define WIDTH 48
#include <dos.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>unsigned char rev(unsigned char c)  //倒置
{
unsigned char i,val=0,ini=1; for (i=0; i<8; i++){
if (c&0x80) val+=ini;
c<<=1; ini*=2;
}
// val=0xff-val;
return val;
}void send_data(unsigned char ch)
{
while((inportb(LineStatus)&0x60)!=0x60);
outportb(LineCtrl,0x3b); //8-data,1-stop,9th bit=0
outportb(SBUF,rev(ch));
}void send_addr(unsigned char ch)
{
while((inportb(LineStatus)&0x60)!=0x60);
outportb(LineCtrl,0x2b); //8-data,1-stop,9th bit=1(SEND address)
outportb(SBUF,ch);
}void send_order_para(unsigned char ch)
{
while((inportb(LineStatus)&0x60)!=0x60);
outportb(LineCtrl,0x3b); //8-data,1-stop,9th bit=0
outportb(SBUF,ch);
}unsigned char ones(unsigned char ch)
{
unsigned char i,res=0; for (i=0; i<4; i++)
{
if (ch&1) res++;
ch>>=1;
}
res&=1; return res;
}
unsigned char verify(unsigned char addr,unsigned char order)  //生成一个addr 和order的校验码
{
unsigned char check,ch; check=addr^order; check=check^(check<<4);
check&=0xf0; ch=(addr&0xf0)>>4; check=check+ones(ch);
ch=addr&0x0f;       check=check+ones(ch)*2;
ch=(order&0xf0)>>4; check=check+ones(ch)*4;
ch=order&0x0f; check=check+ones(ch)*8; return check;
}void main()
{
unsigned char address=0x01,order=0x01, check,checkback,ch;
int i,j;
unsigned char TempChar;
FILE *fp; outportb(LineCtrl,0x80);
outportb(baudL,0x02);
outportb(baudH,0x00); //baud-rate=57.6k
/*
波特率改成57.6k
*/ outportb(ModemCtrl,0x00); //dis-connect SOUT and SIN in computer outportb(LineCtrl,0x2b); //8-data,1-stop,9th bit=1(SEND address) if (inportb(LineStatus)&1)
  inportb(SBUF); order=0x01;       //命令0x01为发送整屏数据
send_addr(address);
send_order_para(order);
check=verify(address,order);
send_order_para(check); while(!(inportb(LineStatus)&1));
//等待单片机应答。这里需要处理一下、不能死等,否则在单片机未上电等情况下会死机
checkback=inportb(SBUF); if (checkback!=check)
exit(1); //NO ACK or Wrong ACK
//出口引向何处也需要重新处理 check=0x00;
for (i=0; i<48; i++)
for (j=0; j<96; j++)
{
TempChar=0x55;
send_data(TempChar);//msg_dz[i][j]);
ch=rev(TempChar);
check=check+ch;//msg_dz[i][j]);
printf("check= %d ,checkback= %d \n",&check,&checkback);
// send_data(0x55);//msg_dz[i][j]);
// check+=rev(0x55);//msg_dz[i][j]);
}
while(!(inportb(LineStatus)&1));
   checkback=inportb(SBUF); if (checkback!=check)
exit(1); //NO ACK or Wrong ACK order=0x02;   //0x02为显示命令
send_addr(address);
send_order_para(order);
check=verify(address,order);
send_order_para(check); while(!(inportb(LineStatus)&1));
checkback=inportb(SBUF); if (checkback!=check) //check
exit(1); //NO ACK or Wrong ACK}pc同单片机用rs485方式来连接

解决方案 »

  1.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}
    const
      SBUF=$3f8;
      baudL=$3f8;
      baudH=$3f9;
      LineCtrl=$3fb;
      ModemCtrl=$3fc;
      LineStatus=$3fd;
    function rev(c:byte):byte;  //倒置
    var
     i,val,ini:byte;
    begin
    val:=0;
    ini:=1;
    i:=0;
    repeat
    if(c and $80)<>0 then  val:=val+ini;
     c:=c shl 1;
     ini:=ini *2;
    inc(i);
    until i>=8;
    result:=val;
    end;function InPortB(LePort:WORD):BYTE;//此代码win2000不适用
    VAR
      Valeur : BYTE;
    begin
      asm
        PUSH DX
        MOV  DX, LePort
        IN   AL, DX
        MOV  Valeur, AL
        POP  DX
      end;
      InPortB := Valeur;
    end;
    Procedure OutPortB(LePort:WORD;Value:BYTE); ASSEMBLER;//此代码win2000不适用
    ASM
      PUSH  DX
      MOV   DX, LePort
      MOV   AL, Value
      OUT   DX, AL
      POP   DX
    END;Procedure send_data(ch:byte);
    begin
    while((inportb(LineStatus)and $60)<>$60)do;
    outportb(LineCtrl,$3b); //8-data,1-stop,9th bit:=0
    outportb(SBUF,rev(ch));
    end;Procedure send_addr(ch:byte);
    begin
    while((inportb(LineStatus)and $60)<>$60)do;
    outportb(LineCtrl,$2b); //8-data,1-stop,9th bit:=1(SEND address)
    outportb(SBUF,ch);
    end;Procedure send_order_para(ch:byte);
    begin
    while((inportb(LineStatus)and $60)<>$60)do;
    outportb(LineCtrl,$3b); //8-data,1-stop,9th bit:=0
    outportb(SBUF,ch);
    end;function ones(ch:byte):BYTE;
    var
    i,res:byte;
    begin
    i:=0;
    res:=0;
    repeat
    if(ch and 1)<>0 then inc(res);
    ch:=ch shr 1;
    inc(i);
    until i>=4;
     res:=res and 1;
    result:=res;
    end;
    function verify(addr:byte;order:byte):BYTE;  //生成一个addr 和order的校验码
    var
    ch,check:byte;
    begin
     check:=addr xor order;
     check:=check xor (check shl 4);
     check:=check and $f0;
     ch:=(addr and $f0) shr 4;
     check:=check+ones(ch);
     ch:=addr and $0f;
     check:=check+ones(ch)*2;
     ch:=(order and $f0)shr 4;
     check:=check+ones(ch)*4;
     ch:=order and $0f;
     check:=check+ones(ch)*8;
     result:=check;
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    //此处最好换成线程的形式,要不可能会造成假死的现象var
    address,order,TempChar:byte;
    check,checkback,ch:byte;
    i,j:integer;
    begin
     address:=$01;
     order:=$1;
     outportb(LineCtrl,$80);
     outportb(baudL,$02);
      outportb(baudH,$00); //baud-rate:=57.6k
      outportb(ModemCtrl,$00); //dis-connect SOUT and SIN in computer
      outportb(LineCtrl,$2b); //8-data,1-stop,9th bit:=1(SEND address)
      if ((inportb(LineStatus) and 1)=1)then  inportb(SBUF);
      order:=$01;       //命令0x01为发送整屏数据
      send_addr(address);
      send_order_para(order);
      check:=verify(address,order);
      send_order_para(check);
      while((inportb(LineStatus) and 1)=0)do;
    //等待单片机应答。这里需要处理一下、不能死等,否则在单片机未上电等情况下会死机
    checkback:=inportb(SBUF); if (checkback<>check)then exit;
    //出口引向何处也需要重新处理
    check:=$00;
    i:=0;
    repeat
       j:=0;
        repeat
           TempChar:=$55;
           send_data(TempChar);//msg_dz[i][j]);
           ch:=rev(TempChar);
           check:=check+ch;//msg_dz[i][j]);
           showmessage(format('heck:= %d ,checkback:= %d \n',[check,checkback]));
           inc(j);
        until j>=96;
       inc(i);
    until i>=48;
     while((inportb(LineStatus)and 1)=0)do;
     checkback:=inportb(SBUF);
     if(checkback<>check)then exit; //NO ACK or Wrong ACK
     order:=$02;   //0x02为显示命令
     send_addr(address);
     send_order_para(order);
     check:=verify(address,order);
     send_order_para(check);
     while((inportb(LineStatus)and 1)=0)do;
     checkback:=inportb(SBUF);
     if(checkback<>check)then exit; //NO ACK or Wrong ACK
    end;end.
    //上述代码未调试,:),到时就自己看这办了