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

📄 serial.c

📁 mcs51,2051,x86系列MCU
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
;; Copyright (C) Intel Corporation 1994
;;          All Rights Reserved.
;;
;; The Software is provided "AS IS."
;;
;; LIMITATION OF LIABILITY:    NEITHER INTEL NOR ITS VENDORS OR AGENTS
;;     SHALL BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF USE, LOSS OF DATA,
;;     INTERRUPTION OF BUSINESS, NOR FOR INDIRECT, SPECIAL, INCIDENTAL OR
;;     CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER THIS AGREEMENT OR
;;     OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/

#include <conio.h>
#include <string.h>
#include <DOS.h>

#include "80386ex.h"
#include "EV386EX.h"
#include "support.h"


/* APB_BLOCK_START = SIO */

/*
   InitSIO:

   Description:
      Initialization routine for Asynchronous Serial I/O Port.

   Parameters:
      Unit     Unit number of the serial port.  0 for SIO port 0, 1 for SIO port 1.
      Mode     Defines Parity, number of data bits, number of stop bits... Reference Serial Line
               Control register for various options
      ModemCntrl  Defines the operation of the modem control lines
      BaudRate Specifies baud rate.  The baud divisor value is calculated based on clocking source
               and clock frequency.  The clocking frequency is set by calling the InitializeLibrary
               function.
      ClockRate   Specifies the serial port clocking rate, for internal clocking = CLK2 for external = COMCLK

   Returns: Error Codes
      E_INVAILD_DEVICE  -- Unit number specifies a non-existing device
      E_OK           -- Initialized OK, No error.

   Assumptions:
        SIOCFG  Has already been configured for Clocking source and Modem control source

      REMAPCFG register has Expanded I/O space access enabled (ESE bit set).
      The processor Port pin are initialized separately.

    Syntax:

       #define SIO_0             0
       #define SIO_8N1           (SIO_8DATA | SIO_1STOPBIT | SIO_NOPARITY)
       #define SIO_MCR_RTS       0x2
       #define SIO_MCR_DTR       0x1
       #define SIO_8DATA         0x3
       #define SIO_1STOPBIT      0x0
       //Clock rate of COMCLK, ie. External clocking
       #define BAUD_CLKIN  1843200L

       int error;

       error = InitSIO(SIO_0,                     // Which Serial Port
                       SIO_8N1,                   // Mode, 8-data, no parity, 1-stop
                       SIO_MCR_RTS+SIO_MCR_DTR,   // Modem line controls
                       9600,                      // Baud Rate
                       BAUD_CLKIN);               // Baud Clocking Rate

   Real/Protected Mode:
      No changes required.

*/

int InitSIO(int Unit, BYTE Mode, BYTE ModemCntrl, DWORD BaudRate, DWORD BaudClkIn)
{
   WORD SIOPortBase;
   WORD BaudDivisor;

      /* Check for valid unit */
   if(Unit > 1)
      return E_INVALID_DEVICE;

      /* Set Port base based on serial port used */
   SIOPortBase = (Unit ? SIO1_BASE : SIO0_BASE);

   /* Initialized Serial Port registers */
      /* Calculate the baud divisor value, based on baud clocking */
   BaudDivisor = (WORD)(BaudClkIn / (16*BaudRate));

       /* Turn on access to baud divisor register */
   _SetEXRegByte(SIOPortBase + LCR, 0x80);
      /* Set the baud rate divisor register, High byte first */
   _SetEXRegByte(SIOPortBase + DLH, HIBYTE(BaudDivisor) );
   _SetEXRegByte(SIOPortBase + DLL, LOBYTE(BaudDivisor) );

      /*** Set Serial Line control register ***/
   _SetEXRegByte(SIOPortBase + LCR, Mode);         /* Sets Mode and reset the Divisor latch */

      /* Set modem control bits */
   _SetEXRegByte(SIOPortBase + MCR, ModemCntrl);

   return E_OK;
}

/*
   SetSIOInterrupt:

   Description:
      Initializes the Interrupt Enable Register (IER) and initializes the interrupt vector table with the
      address of the interrupt function, if provided.  If not provided this function only modifies the IER.

   Parameters:
      Unit          Unit number of the serial port.  0 for SIO port 0, 1 for SIO port 1.
      IntrSources   Which serial port features can cause the interrupt.
      InterruptFnc  Address of interrupt function, will be loaded into the interrupt table.  If
                    NULL no function is loaded.  Use SetInterruptVector to set interrupt routine.
      ISR_Type      Specifies if the interrupt function should be treated as a TRAP_ISR or an
                    INTERRUPT_ISR.  Real Mode only supports INTERRUPT_ISR (parameter is ignored).
                  Protected mode supports both.  If InterruptFnc is NULL parameter is ignored.

   Returns: Error Codes
      E_INVAILD_DEVICE  -- Unit number specifies a non-existing device
      E_OK              -- Initialized OK, No error.

   Assumptions:
      REMAPCFG register has Expanded I/O space access enabled (ESE bit set).
      The processor Port pin are initialized separately.
      ICU is initialized before this is called.
      Compiler supports far and interrupt keywords

   Syntax:

      #define SIO_INTR_NONE   0
      #define SIO_INTR_RBF    0x1
      #define SIO_INTR_TBE    0x2
      #define SIO_INTR_RLS    0x4
      #define SIO_INTR_MS     0x8
      #define INTERRUPT_ISR   1
      #define TRAP_ISR        2

      int error;

      error = SetSIOInterrupt (SIO_0,
                               SIO_INTR_RBF | SIO_INTR_TBE,
                               SIO_ISR,
                               INTERRUPT_ISR);

   Real/Protected Mode
      No changes required.  Uses SetInterruptVector which is mode dependent

*/

int SetSIOInterrupt(int Unit,BYTE IntrSources, void (far interrupt *InterruptFnc)(void), int ISR_Type)
{
   WORD SIOPortBase;
   int  ICUInterruptVector;

      /*** Check for valid unit ***/
   if(Unit > 1)
      return E_INVALID_DEVICE;

   if(InterruptFnc != NULL)
   {
         /*** Calculate which interrupt vector to initialized ***/
         /* Get the base vector number of the Master ICU, SIO 0 & 1 are on the Master */
      ICUInterruptVector = _GetEXRegByte(ICW2M) & 0xf8;  /* Clear bits 0 - 2 */
      ICUInterruptVector += (Unit == 0) ? 4 : 3;  /* Set to IRQ level.  SIO_0 = IRQ4, SIO_1 = IRQ3 */
         /*** Load interrupt function into the interrupt vector table ***/
      SetInterruptVector(InterruptFnc, ICUInterruptVector, ISR_Type);
   }

      /* Set Port base, based on serial port used */
   SIOPortBase = (Unit ? SIO1_BASE : SIO0_BASE);
   _SetEXRegByte(SIOPortBase + IER, IntrSources);

   return E_OK;
}


/*	SerialReadStr

   Description:
      Is a Polled serial port read function that will wait forever or until count characters are
      read from the serial port.

   Parameters:
      Unit        Unit number of the serial port.  0 for SIO port 0, 1 for SIO port 1.
      str         Address of where to place the input data
      count       Number of characters to read before returning.

   Returns: Error Code
      E_OK or Error code status (value of Line Status Register (LSR)

   Assumptions:
      REMAPCFG register has Expanded I/O space access enabled (ESE bit set).
      The processor Port pin are initialized separately.

   Syntax:

      #define SIO_0  0
      #define LENGTH 32

      char String_Read[LENGTH];
      int error;

      error = SerialReadStr (SIO_0,
                             String_Read,
                             LENGTH);

   Real/Protected Mode
      No changes required.

*/


int SerialReadStr(int Unit, char far *str, int count)
{
   WORD ReceivePortAddr;
   WORD StatusPortAddr;
   BYTE Status;
   int i;
   
      /* Set Port base, based on serial port used */
   ReceivePortAddr = (Unit ? RBR1 : RBR0);
   StatusPortAddr =  (Unit ? LSR1 : LSR0);
   
   for(i=0; i < count-1; i++)
   {
         /* Status register is cleared after read, so we must save it's value when read */
      while(!((Status=_GetEXRegByte(StatusPortAddr)) & SIO_RX_BUF_FULL))
         if( Status & SIO_ERROR_BITS )  /* Error Bit set then return NULL */
         {
            str[i+1] = '\0';
            return Status & SIO_ERROR_BITS;
         }
        str[i] = _GetEXRegByte(ReceivePortAddr);
    }
    str[i] = '\0';
    return E_OK;
}
	
/*
   SerialReadChar:
   
   Description:
      Is a Polled serial port read function that will wait forever or until a character has been
      recieved from the serial port.   
   
   Parameters:
      Unit        Unit number of the serial port.  0 for SIO port 0, 1 for SIO port 1.
   
   Returns: 
      BYTE Read from serial port, if zero an error occured.

   Assumptions:
      REMAPCFG register has Expanded I/O space access enabled (ESE bit set).
      The processor Port pin are initialized separately.

   Syntax:
   
      #define SIO_0 0
      
      BYTE character;
      
      character = SerialReadChar (SIO_0);
   
   Real/Protected Mode
      No changes required.
                  
*/


BYTE SerialReadChar(int Unit)
{
   WORD ReceivePortAddr;
   WORD StatusPortAddr;
   WORD Status;
   
      /* Set Port base, based on serial port used */
   ReceivePortAddr = (Unit ? RBR1 : RBR0);
   StatusPortAddr =  (Unit ? LSR1 : LSR0);

      /* Status register is cleared after read, so we must save it's value when read */
   while(!((Status=_GetEXRegByte(StatusPortAddr)) & SIO_RX_BUF_FULL))
      if( Status & SIO_ERROR_BITS )  /* Error Bit set then return NULL */
      {
         return 0;
      }
   
   return _GetEXRegByte(ReceivePortAddr);
}


/*
   SerialWriteChar:
   
   Description:
      Is a Polled serial port write function that will wait forever or until a character has been
      written to the serial port.
               
   Parameters:
      Unit        Unit number of the serial port.  0 for SIO port 0, 1 for SIO port 1.
       ch            Character value to be written out
       
   Returns: 
      None

   Assumptions:
      REMAPCFG register has Expanded I/O space access enabled (ESE bit set).
      The processor Port pin are initialized separately.

   Syntax:
       
       #define SIO_0 0 
       
       char Char_Out = 'a';
       
      SerialWriteChar (SIO_0, Char_Out); 
   
   Real/Protected Mode
      No changes required.

*/


void SerialWriteChar(int Unit, BYTE ch)
{     
   WORD TransmitPortAddr;
   WORD StatusPortAddr;

      /* Set Port base, based on serial port used */
   TransmitPortAddr = (Unit ? TBR1 : TBR0);
   StatusPortAddr =  (Unit ?  LSR1 : LSR0);
   
      /* Wait until buffer is empty */
   while(!(_GetEXRegByte(StatusPortAddr) & SIO_TX_BUF_EMPTY)) ;
   
   _SetEXRegByte(TransmitPortAddr,ch);
}

/*
   SerialWriteStr:
   
   Description:
      Is a Polled serial port write function that will wait forever or until all characters have been
      written to the serial port.  The NUL character ('\0') is used to indicate end of string.     
   
   Parameters:
      Unit        Unit number of the serial port.  0 for SIO port 0, 1 for SIO port 1.

⌨️ 快捷键说明

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