⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serial.cpp

📁 基于AMD X86构架的嵌入式处理器SC520的4串口驱动程序(带缓冲)
💻 CPP
字号:

#define SERIAL_GLOBALS
 
#include "includes.h"



/* Handle communications interrupts and put them in serialbuf */
void interrupt com1_int(...)
{
    
     unsigned char  temp;

    disable();
    temp =inportb(COM1BASE + IIR) ;
   //接收
    if ((temp& RX_ID)== RX_ID)
    {
       com1recvbufend->data =inportb(COM1BASE + RXR);
	com1recvbufend=com1recvbufend->next;
    }
   //发送
    else if ((temp&TX_ID)== TX_ID)
    {
       if(com1sendbufend !=com1sendbufstart)
        {
           
             outportb(COM1BASE +TXR ,com1sendbufstart->data);
	       com1sendbufstart =com1sendbufstart->next;
        }
    }
    // Signal end of hardware interrupt 
    
    outportb(ICR8259A, EOI);
    enable();
}
/* Handle communications interrupts and put them in serialbuf */
void interrupt com2_int(...)
{
      unsigned char  temp;

    disable();
    temp =inportb(COM2BASE + IIR) ;
   //接收
    if ((temp& RX_ID)== RX_ID)
    {
       com2recvbufend->data =inportb(COM2BASE + RXR);
	com2recvbufend=com2recvbufend->next;
    }
   //发送
   else if ((temp&TX_ID)== TX_ID)
    {
      if(com2sendbufend !=com2sendbufstart)
        {
              outportb(COM2BASE +TXR ,com2sendbufstart->data);
	       com2sendbufstart =com2sendbufstart->next;
	 }
     }
	 
    // Signal end of hardware interrupt 
    
    outportb(ICR8259A, EOI);
    enable();

}
//Handle communications interrupts and put them in serialbuf 
void interrupt com3_int(...)
{
      unsigned char  temp;

    disable();
    temp =inportb(COM3BASE + IIR) ;
   //接收
    if ((temp& RX_ID)== RX_ID)
    {
       com3recvbufend->data =inportb(COM3BASE + RXR);
	com3recvbufend=com3recvbufend->next;
    }
   //发送
   else if ((temp&TX_ID)== TX_ID)
    {
      if(com3sendbufend !=com3sendbufstart)
        {
              outportb(COM3BASE +TXR ,com3sendbufstart->data);
	       com3sendbufstart =com3sendbufstart->next;
	 }
     }
	 
    // Signal end of hardware interrupt 
    
    outportb(ICR8259A, EOI);
    enable();

}
// Handle communications interrupts and put them in serialbuf 
void interrupt com4_int(...)
{
      unsigned char  temp;

     disable();
    temp =inportb(COM4BASE + IIR) ;
   //接收
    if ((temp& RX_ID)== RX_ID)
    {
       com4recvbufend->data =inportb(COM4BASE + RXR);
	com4recvbufend=com4recvbufend->next;
    }
   //发送
   else if ((temp&TX_ID)== TX_ID)
    {
      if(com4sendbufend !=com4sendbufstart)
        {
              outportb(COM4BASE +TXR ,com4sendbufstart->data);
	       com4sendbufstart =com4sendbufstart->next;
	 }
     }
   
    // Signal end of hardware interrupt 
    outportb(ICR8259A, EOI);
    enable();

}
int GetBaseAddr(int Port )
{
    int  baseaddr;
    if (Port ==1)
    {
         baseaddr =COM1BASE;
	 
    }
    else  if (Port ==2)
    {
         baseaddr =COM2BASE;
    }
    else  if (Port ==3)
    {
         baseaddr =COM3BASE;
    }
    else  if (Port ==4)
    {
         baseaddr =COM4BASE;
    }
    return baseaddr;
}
/* This routine sets the speed; will accept funny baud rates. */
/* Setting the speed requires that the DLAB be set on.        */
void SetSpeed(int Port,long int Speed)
{
    char		temp;
    int		divisor;
    int baseaddr;

    baseaddr =GetBaseAddr(Port);
   
    divisor = (int) (115200/Speed);
  
    disable();
    temp= inportb(baseaddr + LCR);
    outportb(baseaddr + LCR, (temp| 0x80)); //Set DLAB 
    outportb(baseaddr + DLL, (divisor & 0x00FF));
    outportb(baseaddr + DLH, ((divisor >> 8) & 0x00FF));
    outportb(baseaddr + LCR, temp);          // Reset DLAB 
    enable();
}

/* Set other communications parameters */
void SetOthers(int Port,int Parity, int Bits, int StopBit)
{
    int                setting;

    setting  = Bits-5;
    setting |= ((StopBit == 1) ? 0x00 : 0x04);
    setting |= Parity;

    disable();
    outportb(GetBaseAddr(Port) + LCR, setting);
    enable();
}
/* Turn off communications interrupts */
void DisableI(int Port)
{
    int                temp;
    int  baseaddr;
    baseaddr =GetBaseAddr(Port);
    disable();
    temp= inportb(IMR8259A) | ~IRQ3 | ~IRQ4;
    outportb(IMR8259A, temp);
    outportb(baseaddr + IER, 0);
    temp = inportb(baseaddr + MCR) & ~MC_INT;
    outportb(baseaddr + MCR, temp);
    enable();
}
/* Turn on communications interrupts */
void EnableI(int Port)
{
    int   temp,temp1;
    int  baseaddr;
    baseaddr =GetBaseAddr(Port);
    disable();
    temp= inportb(baseaddr + MCR) | MC_INT;
    outportb(baseaddr + MCR, temp);
    outportb(baseaddr + IER, RX_INT|TX_INT);
    if(Port == COM1)
    {
         temp1 =IRQ4;
    }
    else  if(Port == COM2)
    {
         temp1 =IRQ3;
    }
    else  if(Port == COM3)
    {
         temp1 =IRQ5;
    }
    else  if(Port == COM4)
    {
         temp1 =IRQ6;
    }
     temp = inportb(IMR8259A) & temp1;
    outportb(IMR8259A, temp);
    enable();
}
/* Install our functions to handle communications */
void SetVects(int Port) //设置中断向量
{
   switch(Port)
   {
       case COM1:
               {
			 comoldvects[0] = getvect(0x0C);
			 setvect(0x0C, com1_int);
			 break;
       	  }
       case COM2:
               {
			 comoldvects[1] = getvect(0x0B);
                       setvect(0x0B, com2_int);
			break;
		        
       	  }
	case COM3:
               {
			 comoldvects[2] = getvect(0x0D);
                       setvect(0x0D, com3_int);
			 break;
       	  }
	case COM4:
               {
			 comoldvects[3] = getvect(0x0E);
                       setvect(0x0E, com4_int);
			break;
       	  }
	default:
			break;

   }
   
}    
/* Uninstall our vectors before exiting the program */
void ResVects(int Port)//恢复原有的中断向量
{

   switch(Port)
   {
       case COM1:
               {
			  setvect(0x0C, comoldvects[0]);
			  break;
       	  }
       case COM2:
               {
			  setvect(0x0B, comoldvects[1]);
			  break;
       	  }
	case COM3:
               {
			  setvect(0x0D, comoldvects[2]);
			  break;
       	  }
	case COM4:
               {
			  setvect(0x0E, comoldvects[3]);
			  break;
       	  }
	default:
			break;
   }
}
/* Go off-line */
void CommOff(int Port)
{
    DisableI(Port);

    outportb(GetBaseAddr(Port)+ MCR, 0);
}
/* Tell modem that we're ready to go */
void CommOn(int Port)
{
    int   temp, pnum;
   int baseaddr;
    if(Port <=4)
    {
        EnableI(Port);
    }
    baseaddr =GetBaseAddr(Port) ;
  
    temp = inportb(baseaddr+ MCR) | DTR | RTS;
    outportb(baseaddr + MCR, temp);
}
void CloseSerial(int Port)
{
    CommOff(Port);
    ResVects(Port);
}
void OpenSerial(int Port)
{
   
    SetVects(Port);
    CommOn(Port);
}
int InitSerial(int Port, long int Speed, int Parity, int Bits, int StopBit)
{
 
   
   if((Port ==0)||(Port >4))
   {
        return PORTERROR;
   }
   if ((Speed == 0)||(Speed >115200))            /* Avoid divide by zero */
    {
       return SPEEDERROR;
    }
    if (Bits < 5 || Bits > 8)
    {
       return BITSERROR;
    }
    if((StopBit != 1) && (StopBit != 2))
    {
       return STOPBITERROR;
    }
    if (Parity != NO_PARITY && Parity != ODD_PARITY && Parity != EVEN_PARITY)
    {
       return PARITYERROR;
    }
  //COM3COM4需要设置IRQ
    if((Port ==3)||(Port ==4))
    {
           outportb(COM34IRQADDR, COM34IRQ);//COM3=IRQ5,COM4=IRQ6
    }
    SetSpeed(Port,Speed);
	
    SetOthers(Port,Parity, Bits, StopBit);

    OpenSerial(Port);
    return OK;
	
}
void InitComBuf(void)
{
     int i;
//com1
    for (i=0;i<COMBUFSIZE;i++)
  {
         com1sendbuf[i].next =&com1sendbuf[i+1];
	  com1recvbuf[i].next =&com1recvbuf[i+1];
	  
  }
  com1sendbuf[COMBUFSIZE-1].next =com1sendbuf;
  com1recvbuf[COMBUFSIZE-1].next =com1recvbuf;
  com1sendbufstart =com1sendbuf;
  com1sendbufend  = com1sendbuf;
  com1recvbufstart =com1recvbuf;
  com1recvbufend   = com1recvbuf;
//com2
  for (i=0;i<COMBUFSIZE;i++)
  {
         com2sendbuf[i].next =&com2sendbuf[i+1];
	  com2recvbuf[i].next =&com2recvbuf[i+1];
  }
  com2sendbuf[COMBUFSIZE-1].next =com2sendbuf;
  com2recvbuf[COMBUFSIZE-1].next =com2recvbuf;
  com2sendbufstart =com2sendbuf;
  com2sendbufend  = com2sendbuf;
  com2recvbufstart =com2recvbuf;
  com2recvbufend   = com2recvbuf;
//com3
  for (i=0;i<COMBUFSIZE;i++)
  {
         com3sendbuf[i].next =&com3sendbuf[i+1];
	  com3recvbuf[i].next =&com3recvbuf[i+1];
  }
  com3sendbuf[COMBUFSIZE-1].next =com3sendbuf;
  com3recvbuf[COMBUFSIZE-1].next =com3recvbuf;
  com3sendbufstart =com3sendbuf;
  com3sendbufend  = com3sendbuf;
  com3recvbufstart =com3recvbuf;
  com3recvbufend   = com3recvbuf;
//com4
  for (i=0;i<COMBUFSIZE;i++)
  {
         com4sendbuf[i].next =&com4sendbuf[i+1];
	  com4recvbuf[i].next =&com4recvbuf[i+1];
  }
  com4sendbuf[COMBUFSIZE-1].next =com4sendbuf;
  com4recvbuf[COMBUFSIZE-1].next =com4recvbuf;
  com4sendbufstart =com4sendbuf;
  com4sendbufend  = com4sendbuf;
  com4recvbufstart =com4recvbuf;
  com4recvbufend   = com4recvbuf;
}

void DisableSendInt( int baseaddr)
{
   
    char temp;
    temp = inportb(baseaddr + IER);
    temp &=~TX_INT;
    outportb(baseaddr + IER, temp);
}
void EnableSendInt(int  baseaddr)
{
 
    char temp;
    temp = inportb(baseaddr + IER);
    temp |=TX_INT;
    outportb(baseaddr + IER, temp);

}


void ComSend(int Port,char *temp)
{
    unsigned char temp2=0;
    if(Port ==1)
    {
         if (com1sendbufend == com1sendbufstart) //发送缓冲为空时需要激活发送
        {
                temp2 =1;
         }
         else
        {
                temp2 =0;
        }
        DisableSendInt(COM1BASE);
        while(*temp)
        {
                  com1sendbufend->data =*temp;
	          com1sendbufend = com1sendbufend->next;
	          temp ++;
        }
        if(temp2)
        {
                   outportb(COM1BASE +TXR ,com1sendbufstart->data);
	           com1sendbufstart =com1sendbufstart->next;
     
         }
         EnableSendInt(COM1BASE);
    }
    else     if(Port ==2)
    {
         if (com2sendbufend == com2sendbufstart) //发送缓冲为空时需要激活发送
        {
                temp2 =1;
         }
         else
        {
                temp2 =0;
        }
        DisableSendInt(COM2BASE);
        while(*temp)
        {
                  com2sendbufend->data =*temp;
	          com2sendbufend = com2sendbufend->next;
	          temp ++;
        }
        if(temp2)
        {
                   outportb(COM2BASE +TXR ,com2sendbufstart->data);
	           com2sendbufstart =com2sendbufstart->next;
     
         }
         EnableSendInt(COM2BASE);
    }
    else     if(Port ==3)
    {
         if (com3sendbufend == com3sendbufstart) //发送缓冲为空时需要激活发送
        {
                temp2 =1;
         }
         else
        {
                temp2 =0;
        }
        DisableSendInt(COM3BASE);
        while(*temp)
        {
                  com3sendbufend->data =*temp;
	          com3sendbufend = com3sendbufend->next;
	          temp ++;
        }
        if(temp2)
        {
                   outportb(COM3BASE +TXR ,com3sendbufstart->data);
	           com3sendbufstart =com3sendbufstart->next;
     
         }
         EnableSendInt(COM3BASE);
    }
    else     if(Port ==4)
    {
        if (com4sendbufend == com4sendbufstart) //发送缓冲为空时需要激活发送
        {
                temp2 =1;
         }
         else
        {
                temp2 =0;
        }
        DisableSendInt(COM4BASE);
        while(*temp)
        {
                  com4sendbufend->data =*temp;
	          com4sendbufend = com4sendbufend->next;
	          temp ++;
        }
        if(temp2)
        {
                   outportb(COM4BASE +TXR ,com4sendbufstart->data);
	           com4sendbufstart =com4sendbufstart->next;
     
         }
         EnableSendInt(COM4BASE);
     }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -