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

📄 int232.c

📁 一位十年经验美国工程师的工程代码
💻 C
字号:
//****************************************************************************
//                           intserial.c
//                             V1.00
//
// These are interrupt and timer driven serial routines.
// Uses the Interrupt input pin and Timer0 overflow interrupt etc.
//
// The received data is double buffered to hopefully limit overflows
//
// Author: Michael Pearce
//         Chemistry Department, University of Canterbury
//
// Started: Monday 3 May 1999
//
//****************************************************************************
//                        Version Information
//****************************************************************************
// Version 1.00 - 03 May 1999
//  Start of the project.
//****************************************************************************
#include <conio.h>

#define DEBUG
//********** Define the PORTS and TRIS to use ***********
// Change to Suit your requirements


static bit	RXDPin @ (unsigned)&PORTB*8+0;		/* bit0  in port B */
static bit	RXDTris @ (unsigned)&TRISB*8+0;		/* bit0 in port B */

static bit	TXDPin @ (unsigned)&PORTB*8+1;		/* bit1 port B */
static bit	TXDTris @ (unsigned)&TRISB*8+1;		/* bit1 in port B */


#ifdef DEBUG
 static bit	TestPin @ (unsigned)&PORTB*8+7;		/* Test PIN port A 0 */
 static bit	TestTris @ (unsigned)&TRISB*8+7;
 static bit	TestPin1 @ (unsigned)&PORTB*8+6;		/* Test PIN port A 0 */
 static bit	TestTris1 @ (unsigned)&TRISB*8+6;
 static bit	TestPin2 @ (unsigned)&PORTB*8+5;		/* Test PIN port A 0 */
 static bit	TestTris2 @ (unsigned)&TRISB*8+5;

#endif


//********** Define the Baud Rate to use ***********
// Requires PIC_XTAL to be defined (The Crystal Frequecy being used in MHz)

// Maximum and minimum baud rates depend on the crystal frequency used
// Here is a list of what rates should work - tested bauds marked with *
// These are calculated using a OVERSAMPLE of 8 - it may be possible to
// increase of decrease the range by changing the oversample to help but do not
// recommend going less than a 6 times oversample.
// Maximum Speeds calculated by no less than 10 timer ticks (before overhead)
// This may not leave much processor time due to minimum times taken
// by interrupt routine to check things.
//
// XTAL     BAUD RATES                                      TESTED
//---------------------------------------------------------------------
//  2MHz   300,600,1200,2400,4800                            NONE
//  4MHz       600,1200,2400,4800,9600                       NONE
//  8MHz           1200,2400,4800,9600,19200                 NONE
// 10MHz                2400,4800,9600,19200                 NONE
// 12MHz                2400,4800,9600,19200                 NONE
// 16MHz                2400,4800,9600,19200,38400           NONE
// 20MHz                     4800,9600,19200,38400,56000     NONE
//--------------------------------------------------------------------


#define BAUD 9600                    //-- The Baud Rate Required
#define OVERSAMPLE 8                 //-- Samples per bit - Even Nus only
#define OVERHEAD (2+2)               //-- 2 Timer cycles + Interrupt cycles

#if	(OVERSAMPLE-1)&OVERSAMPLE
#error	OVERSAMPLE value must be a power of 2
#endif


// 1,000,000 / BAUD = us per bit Time
// Divide by us per instruction cycle to give the cycles per bit time
// Divide by number of ticks per sample time

#define TIMERTICKS ( ( (1000000/BAUD)  * (PIC_CLK/4 ) ) / (OVERSAMPLE-1) )

//#define TIMERTICKS (PIC_CLK*1000000) / (4 * BAUD * OVERSAMPLE)

// Subtract Timer ticks from the overflow value then add the overhead
// Hopefully this is the correct time for what you want

#if (TIMERTICKS > 0xFC)
 #error   ######### BAUDRATE NOT POSSIBLE - TO SLOW OR UNDERFLOWED ########
 #error   # Possible Solutions:
 #error   # Choose a faster Baud Rate
 #error   # Use a lower frequency Crystal/Clock
 #error   # Increase the OVERSAMPLE Rate to suit
#endif
#if (TIMERTICKS < 0x0A)
 #error   ######### BAUDRATE NOT POSSIBLE - TO FAST OR OVERFLOWED ########
 #error   # Possible Solutions:
 #error   # Choose Slower Baud Rate
 #error   # Use a Higher frequency Crystal/Clock
 #error   # Lower the OVERSAMPLE Rate to suit
#endif

//#define TIMERRELOAD (unsigned char) ((0xFF-TIMERTICKS)+2)
#define TIMERRELOAD 0xFF - TIMERTICKS + OVERHEAD

//********** Define the Flags, Data Etc ***********

bit RxdNewData=0;           //-- Indicated new data has been received
bit RxdOverflow=0;          //-- Indicates data recieved before buffer cleared
bit RxdReceiving=0;         //-- Indicated New data being read in
bit RxdStartOK=0;           //-- Indicates Valid Start Bit found

bit TxdInProgress=0;        //-- Indicates that data is being transmitted
bit SerialIntEnabled=0;     //-- Enables/Disables the Interrupt serial routine
bit DataOverflow=0;         //-- Indicates data overflow to user

char SerialTxdCount;        //-- Bit count for transmitted data
char SerialTxdDivider;      //-- Timer Divider for transmitted data
char SerialRxdCount;        //-- Bit count for received data
char SerialRxdDivider;      //-- Timer Divider for Recieved data

char RXDBuffer;             //-- Recieved data temp buffer
char RXDData;               //-- Recieved data buffer
char TXDData;               //-- Transmit data buffer


//****************************************************************************
//                     FUNCTION DEFINITIONS
//****************************************************************************
void InitUart(void);
void SerialEnable(void);
void SerialDisable(void);
//****************************************************************************
//                             InitUart
// Initialises the serial port bits and sets up and starts the timer
//****************************************************************************
void InitUart(void)
{
 #ifdef DEBUG
  TestTris=0;
  TestTris1=0;
  TestTris2=0;
 #endif
 RBPU=0;                   //-- Enable pull ups on Port B

 TXDPin=1;                 //-- Transmit pin initially High
 TXDTris=0;                //-- and set to output
 RXDTris=1;                //-- RXD pin set as input
 SerialEnable();           //-- Setup the interrupts etc
}
//********************* END OF InitUart


//****************************************************************************
//                          SerialEnable
// Enables the serial interrupt routine and configures the timer for serial
// timing.
//****************************************************************************
void SerialEnable(void)
{
 INTEDG=0;                           //-- Rxd pin Interrupt on FALLING Edge
 PSA=1;                              //-- Prescaler set for WDT
 T0CS=0;                             //-- Timer Increment on INTERNAL clock
 TMR0=TIMERRELOAD;                   //-- Load the timer
 SerialIntEnabled=1;                 //-- Enable the serial interrupt routines

 INTE=1;                             //-- Enable external interrupt
 T0IE=1;                             //-- Enable the timer interrupt
 GIE=1;                              //-- Enable the Global interrupt Enable
}
//********************* END OF SerialEnable

//****************************************************************************
//                             SerialDisable
//   Disables the serial interrupt routine - but leaves timer running
//****************************************************************************
void SerialDisable(void)
{
 SerialIntEnabled=0;
}
//********************* END OF SerialDisable

//****************************************************************************
//                        SerialDisableAll
//   Disables the serial interrupt routine and STOPS the timer
//****************************************************************************
void SerialDisableAll(void)
{
 SerialIntEnabled=0;                 //-- Disable the timer interrupt
 T0IE=0;
}
//********************* END OF SerialDisableAll

//****************************************************************************
//                         SerialInterrupt
//****************************************************************************
interrupt void SerialInterrupt(void)
{
 if(SerialIntEnabled)
 {
  //########## TIMER ZERO OVERFLOW INTERRUPT #############
  if(T0IF)
  {
   #ifdef DEBUG
    TestPin ^= 1;        //-- Toggle Test pin
   #endif
   TMR0=TIMERRELOAD;     //-- Reload the Timer
   T0IF=0;               //-- Clear the interrupt flag
   //########## RECIEVE DATA ############
   if(RxdReceiving)      //-- Receive the data in ????
   {
    if( (SerialRxdDivider--)==0)
    {
     #ifdef DEBUG
      TestPin2=RXDPin;
     #endif
     SerialRxdDivider=OVERSAMPLE;    //-- Reload the counter

     SerialRxdCount--;
     if(SerialRxdCount==9)
     {
      //-- Check for Start Bit
      if(RXDPin)
      {
       RxdReceiving=0;   //-- Bad Start Bit!!!  Cancel the Run!!!!
       INTE=1;
      }
     }
     else
     {
      if(SerialRxdCount)
      {
       #ifdef DEBUG
        TestPin1 = RXDPin;
       #endif

       //-- read in data bit
       RXDBuffer >> 1;
       if(RXDPin)
       {
       	RXDBuffer |= 0x80;     //-- Set the bit
       }
       else
       {
        RXDBuffer &=0x7F;     //-- Clear the bit
       }
      }
      else
      {
       //-- Check for Stop Bit
       if(RXDPin)
       {
        //-valid stop signal
        RxdReceiving=0;
        RXDData=RXDBuffer;
        if(!RxdNewData)
        {
         RxdNewData=1;       //-- New Data has arrived
        }
        else
        {
         RxdOverflow=1;      //-- Data has overflowed - latest data in buffer
        }
        INTE=1;
       }
       else
       {
        //-- NOT A VALID STOP SIGNAL - TRASH THE DATA
        RxdReceiving=0;      //-- BAD DATA - CANCEL THE RUN
        INTE=1;
       }
      }
     }
    }
   }

   if(TxdInProgress)    //-- Sending data out ????
   {
    if((--SerialTxdDivider)==0)
    {
     SerialTxdDivider=OVERSAMPLE;
     SerialTxdCount--;
     if(SerialTxdCount==9)
     {
      //-- Start Bit --
      TXDPin=0;
     }
     else
     {
      if(SerialTxdCount)
      {
       //-- Send Data Bit--
       if(TXDData & 0x01)
       {
        TXDPin=1;
       }
       else
       {
        TXDPin=0;
       }
       TXDData=TXDData >>1;   //-- Point to next data bit
      }
      else
      {
       //-- Stop Bit --
       TXDPin=1;
       TxdInProgress=0;
      }
     }
    }
   }
  }
  //########## END OF TIMER ZERO OVERFLOW INTERRUPT #############

  if(INTF)           //-- START OF NEW SERIAL BYTE ????
  {
   INTE=0;           //-- Disable interrupt until Receive complete
   INTF=0;           //-- Clear the interrupt Flag
   RxdReceiving=1;   //-- Indicate Receiving new Data
   SerialRxdCount=10;              //-- # of Bits to read in
   SerialRxdDivider=OVERSAMPLE/2; //-- First time to sample Start Bit (1/2)
  }
 }
 //else
 //{
 //********** Add Serial OFF Interrupt routines here **********
 //}

}
//********************* END OF SerialInterrupt
//****************************************************************************
//                            putch
//****************************************************************************
void putch(char c)
{
 while(TxdInProgress);        //-- Wait for data to be sent ---> Should have timeout in here!!!
 TXDData=c;                   //-- copy data to the output buffer
 SerialTxdCount=10;           //-- # of Bits to transmit
 SerialTxdDivider=OVERSAMPLE; //-- Initial divider - to allow for a stop bit!!!
 TxdInProgress=1;             //-- Transmit is now in progress
}
//********************* END OF putch

//****************************************************************************
//                             getch
//****************************************************************************
char getch(void)
{
 char c;
 while(!RxdNewData);       //-- Wait for new data to arrive
 c=RXDData;                //-- Copy data from buffer
 RxdNewData=0;             //-- Clear the New Data Flag
 if(RxdOverflow)           //-- Check if an Overflow occured
 {
  DataOverflow=1;          //-- Indicate the overflow - cleared by programmer
  RxdOverflow=0;           //-- Clear the overflow flag
 }
 return(c);                //-- Return the data
}
//********************* END OF getch
//****************************************************************************
//
//****************************************************************************

//********************* END OF





⌨️ 快捷键说明

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