Chinaunix首页 | 论坛 | 博客
  • 博客访问: 180357
  • 博文数量: 43
  • 博客积分: 2510
  • 博客等级: 少校
  • 技术积分: 560
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-12 20:48
文章分类

全部博文(43)

文章存档

2013年(1)

2011年(1)

2010年(4)

2009年(25)

2008年(12)

我的朋友

分类: LINUX

2008-12-08 16:27:01

我们PC/104系统只能装DOS,并且只有串口。平时调试很不方便,需要将电脑里的程序写到软盘,然后
再通过软盘复制到开发装置。可怜软驱还不争气,到现在已经坏了好多软盘了。而且调试间和办公室离得比较远。到了调试间软盘读不出来,很郁闷。

    这些天任务不是很重,就利用现有资源把串口程序整理了一下。做了一个DOS下的文件传送程序。在短距离下调试通过,不过长距离或者现场干扰较大的话,就不能保证传送的正确了。毕竟程序里没有校验文件功能,等以后再加吧。以后还要加一个传送整个文件夹的功能。
   抛砖引玉。

 接收程序:
 #include
#include
#include
#include
#include
#include
#define RXD 0   //接收
#define TXD 0    //发送
#define LSB 0     //波特率调节低8位
#define MSB 1     //波特率调节高8位
#define IER 1    // 中断起用寄存器
#define IIR 2    //中断标识寄存器
#define LCR 3    //线路控制寄存器
#define MCR 4   //调制解调器控制寄存器
#define LSR 5   //线路状态寄存器
#define MSR 6   //调制解调器状态寄存器
#define IERV 1
#define OUT2 0x08
#define ERTS 2
#define EDTR 1
#define EMPTY 0X20
#define READY 0X30
#define ICREG 0X20
#define IMASKREG 0X21
#define EOI 0X20
#define WAITCOUNT 5000
#define BUFFLEN 2048      //用于存储字符的数组的界
#define ALTE 0X12
#define ALTQ 0X10
#define SER_BAUD_1200  96  
#define SER_BAUD_2400  48
#define SER_BAUD_9600  0x0C
#define SER_BAUD_19200  6
#define SER_STOP_1      0     /*/ 1 stop bit per character*/
#define SER_STOP_2      4     /*/ 2 stop bits per character*/
#define SER_BITS_5      0     /*/ send 5 bit characters*/
#define SER_BITS_6      1     /*/ send 6 bit characters*/
#define SER_BITS_7      2     /*/ send 7 bit characters*/
#define SER_BITS_8      3     /*/ send 8 bit characters*/
#define SER_PARITY_NONE 0     /*/ no parity*/
#define SER_PARITY_ODD  8     /*/ odd parity*/
#define SER_PARITY_EVEN 24    /*/ even parity*/
int port;
int ComNum;
unsigned portaddr;
unsigned portf;
unsigned int baudtable[]={0x180,0xc0,0x60,0x30,0x18,0x0c,0x06};
unsigned char paritytable[]={0x08,0x18,0x00,0x28,0x38};
unsigned char buffer[BUFFLEN];//recv buf
int buffin=0;
int buffout=0;
int incount=0;
int outcount=0;
void interrupt(*vect_com)(...);

void putb(unsigned char ch)//write a char to the recvbuf 将中断得到的数据写到缓冲区
 {
 int temp;
 temp=buffin;
 if(++buffin==BUFFLEN)
  buffin=0;
 if(buffin!=buffout)
  {buffer[buffin]=ch;
  //      printf("bufferin[%d]=%c",buffer[buffin]);
  //     getch();
  }
 else
  buffin=temp;
 };
unsigned char getb()//read a char from the recvbuf
 {
 if(buffout!=buffin)
  {
  if(++buffout==BUFFLEN)
   buffout=0;
  //printf("bufferout[%d]=%c",buffout,buffer[buffout]);
  return(buffer[buffout]);
  }
 else
  return(0xff);
 };
/*unsigned char sender( unsigned char ch)
 {

 outportb(portaddr2+TXD,ch);
 printf("\nsender outportdata=%c\n",ch);
 outcount++;
 return(1);
 
 };
*/
void interrupt receiver(...)
 {
 unsigned char ch;
 ch=inportb(portaddr+RXD);
 putb(ch);
 incount++;   //记录接收了多少个数据。
 outportb(ICREG,EOI);
 };
void SerInit(int baud,int configuration)
 {
 disable();
 outportb(portaddr+LCR,0x80);
 outportb(portaddr+LSB,baud);
 outportb(portaddr+MSB,0x00);
 outportb(portaddr+LCR,configuration);
 enable();
 };
void SerOpen(void)
 {
 vect_com=getvect(portf+8);
 disable();
 inportb(portaddr+RXD);
 inportb(portaddr+MSR);
 inportb(portaddr+LSR);
 inportb(portaddr+IIR);
 outportb(portaddr+IER,IERV);
 outportb(portaddr+MCR,OUT2|ERTS|EDTR);
 outportb(IMASKREG,inportb(IMASKREG)&(~(1< setvect(portf+8,receiver);
 enable();
 };
void SerClose(void)
 {
 disable();
 outportb(portaddr+IER,0);
 outportb(portaddr+MCR,0);
 outportb(IMASKREG,inportb(IMASKREG)|(1< enable();
 setvect(portf+8,vect_com);
 };
void Getportaddr(int port)
 {
         switch (port)
         {
          case 0: portaddr=0x3F8; break;
         case 1: portaddr=0x2F8; break;
   case 2: portaddr=0x3E8; break;
   case 3: portaddr=0x2E8; break;
         }
 portf=(port==0)?4:3;
 };

void Int()
{
 unsigned char key,key2;
 port=ComNum-1;
 if(peek(0x40,port*2)==0)
 {
  printf("have no special com .\n");
  exit(1);
 }
 else
 {
  printf("The used port is :COM%d\n",ComNum);
 };
 Getportaddr(port);                     // 得到串口地址
 SerInit(SER_BAUD_9600,SER_PARITY_EVEN| SER_BITS_8 | SER_STOP_1);                                    //初始化串口,设置波特率等
 SerOpen();
 do
 {

  if(kbhit())
  {
    key2=getch();
    if(key2==27){  break;}

  };
  key=getb();
  if(key!=0xff)
  {
      printf("%x\t",key);
      FILE *fp;
      fp=fopen("C:\\Receivedata.dat","ab");   //可选择接收数据的存放文件路径和文件名
      if(fp==NULL)  printf("File open error!");
    //  fputc(key,fp);
      fwrite(&key,sizeof(unsigned char),1,fp);
                  fclose(fp);

  }

 }while (key2!=27);
 SerClose();


// printf("%d char has been received\n",incount);
// printf("%d char has been sended\n",outcount);
// printf("\nsum=%d \n",sum);
}

void main()//com1 receive
{
 printf("Please input the receive COMnum:(1~4)\n");
       cin>>ComNum;
 printf("the current com set is:9600,even, data bits 8, stop 1,");
 Int();

 printf("\n\nOVER\n");
 exit(0);
};

---------------
发送文件程序

#include
#include
#include
#include
#include
#include
#ifdef __cplusplus
    #define __CPPARGS ...
#else
    #define __CPPARGS
#endif
#define SER_RBF        0  
#define SER_THR        0  
#define SER_IER        1   
#define SER_IIR        2   
#define SER_LCR        3  
#define SER_MCR        4   
#define SER_LSR        5   
#define SER_MSR        6   
#define SER_DLL        0   
#define SER_DLH        1   

#define SER_BAUD_1200  96  
#define SER_BAUD_2400  48
#define SER_BAUD_9600  12
#define SER_BAUD_19200  6
#define SER_GP02        8    
#define COM_1           0x3F8
#define COM_2           0x2F8 /*/ base port address of port 1*/
#define COM_3           0x3E8
#define COM_4           0x2E8
#define SER_STOP_1      0     /*/ 1 stop bit per character*/
#define SER_STOP_2      4     /*/ 2 stop bits per character*/
#define SER_BITS_5      0     /*/ send 5 bit characters*/
#define SER_BITS_6      1     /*/ send 6 bit characters*/
#define SER_BITS_7      2     /*/ send 7 bit characters*/
#define SER_BITS_8      3     /*/ send 8 bit characters*/
#define SER_PARITY_NONE 0     /*/ no parity*/
#define SER_PARITY_ODD  8     /*/ odd parity*/
#define SER_PARITY_EVEN 24    /*/ even parity*/
#define SER_DIV_LATCH_ON 128  /*/ used to turn reg 0,1 into divisor latch*/
#define PIC_IMR    0x21   /*/ pics interrupt mask reg.*/
#define PIC_ICR    0x20   /*/ pics interupt control reg.*/
#define INT_SER_PORT_0    0x0C  /*/ port 0 interrupt com 1 & 3*/
#define INT_SER_PORT_1    0x0B  /*/ port 0 interrupt com 2 & 4*/
#define SERIAL_BUFF_SIZE 128    /*/ current size of circulating receive buffer*/

void interrupt far (*Old_Isr)(__CPPARGS);  /*/ holds old com port interrupt handler*/

char ser_buffer[SERIAL_BUFF_SIZE];  /*/ the receive buffer*/

int ser_end = -1,ser_start=-1;      /*/ indexes into receive buffer*/
int ser_ch, char_ready=0;           /*/ current character and ready flag*/
int old_int_mask;                   /*/ the old interrupt mask on the PIC*/
int open_port;                      /*/ the currently open port*/
int serial_lock = 0;                /*/ serial ISR semaphore so the buffer*/
        /*/ isnt altered will it is being written*/
                                    /*/ to by the ISR*/


/*-------------写串口-----------------*/ 
void interrupt far Serial_Isr(__CPPARGS)
{
serial_lock = 1;
ser_ch = inp(open_port + SER_RBF);
if (++ser_end > SERIAL_BUFF_SIZE-1)
    ser_end = 0;
ser_buffer[ser_end] = ser_ch;

++char_ready;
outp(PIC_ICR,0x20);
serial_lock = 0;

}


int Ready_Serial()
{
return(char_ready);

}

/*--------------读串口--------------*/

int Serial_Read()
{
int ch;
while(serial_lock){}
if (ser_end != ser_start)
   {
   if (++ser_start > SERIAL_BUFF_SIZE-1)
       ser_start = 0;
   ch = ser_buffer[ser_start];
   printf("%x",ch);
  if (char_ready > 0)
       --char_ready;
   return(ch);

   }
else
   return(0);

}

/*--------------写串口-----------------*/
Serial_Write(char ch)
{
while(!(inp(open_port + SER_LSR) & 0x20)){}
asm cli
outp(open_port + SER_THR, ch);
asm sti
}

/*-----------初始化串口---------------*/
Open_Serial(int port_base, int baud, int configuration)
{
open_port = port_base;
disable();
outp(port_base + SER_LCR, SER_DIV_LATCH_ON);
outp(port_base + SER_DLL, baud);
outp(port_base + SER_DLH, 0);
outp(port_base + SER_LCR, configuration);
outp(port_base + SER_MCR, SER_GP02);
outp(port_base + SER_IER, 1);
if (port_base == COM_1 || port_base==COM_3)
   {
   Old_Isr = _dos_getvect(INT_SER_PORT_0);
   _dos_setvect(INT_SER_PORT_0, Serial_Isr);
   printf("\nOpening Communications Channel Com Port #1/3...\n");

   }
else
   {
   Old_Isr = _dos_getvect(INT_SER_PORT_1);
   _dos_setvect(INT_SER_PORT_1, Serial_Isr);
   printf("\nOpening Communications Channel Com Port #2/4...\n");
   }
old_int_mask = inp(PIC_IMR);
outp(PIC_IMR, (port_base==COM_1) ? (old_int_mask & 0xEF) : (old_int_mask & 0xF7 ));
enable();
}
/*-------------关闭串口--------------*/
Close_Serial(int port_base)
{
outp(port_base + SER_MCR, 0);
outp(port_base + SER_IER, 0);
outp(PIC_IMR, old_int_mask );
if (port_base == COM_1)
   {
   _dos_setvect(INT_SER_PORT_0, Old_Isr);
   printf("\nClosing Communications Channel Com Port #1.\n");
   }
else
   {
   _dos_setvect(INT_SER_PORT_1, Old_Isr);
   printf("\nClosing Communications Channel Com Port #2.\n");
   }

}

/*-------------发送应用----------------*/

void main(int argc,char *argv[])
{

char ch,press;
int done=0;
FILE *fp;
argc=2;
//argv[1]="c:\\comfile.c";
 if(argc<2)
 {
  printf("\nUsage:display filename.wav!!!");
 // exit(1);
 }
 if((fp=fopen(argv[1],"r+b"))==NULL)
 {
  printf("cannot open the file\n");
 // exit(0);
 }
fseek(fp, 0, SEEK_SET);
Open_Serial(COM_1,SER_BAUD_9600,SER_PARITY_EVEN| SER_BITS_8 | SER_STOP_1);
printf("com:1;bps:9600;parity:even;bits:8;stop bit:1");
printf("press any key to begin sending");
getch();
//Serial_Write();   //该语句可用于发送单个字符

while(!done&&ch != EOF)          //发送文件开始
     {
 ch = fgetc(fp);
 //if(ch==EOF) Serial_Write(27);
 Serial_Write(ch);
 delay(30);
 if (kbhit())
 {
  press=getch();
  if (press==27)
  {
   Serial_Write(27);
   done=1;
  }
 }
     } 


Close_Serial(COM_1);
fclose(fp);
}


阅读(1731) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~