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

📄 io.c

📁 In-system Programming with C51 MCU and External Flash
💻 C
字号:
/*C**************************************************************************
* NAME: io.c  
*----------------------------------------------------------------------------
* PURPOSE: 
* Functions dedicated to the HEX file reception from the host via the Uart.
* These functions provide uart initialization, interrupt handling and 
* Rx circular buffer management.
*****************************************************************************/

/*_____ I N C L U D E S ____________________________________________________*/
#include "compiler.h"
#include "config.h"
#include "isp.h"

/*_____ M A C R O S ________________________________________________________*/
/* XON / XOFF Contro characters */
#define XON        17  
#define XOFF       19

/* Must be 2^y for modulo computation */
#define RX_BUF_SIZE 16

/* XOFF when only 50% buffer size left */
/* XON when 25% rx buffer full */
#define XOFF_THRESH (RX_BUF_SIZE - (RX_BUF_SIZE / 2) ) 
#define XON_THRESH  (RX_BUF_SIZE / 4) 

/* Wait for end of Tx over the Uart */
#define WAIT_EO_TX  {while (TI==0); TI=0;}

/*_____ D E F I N I T I O N ________________________________________________*/
static Uchar rx_buffer[RX_BUF_SIZE]; /* Rx circular buffer */ 
static Uchar rx_index_wr;            /* Rx circular buffer indexes */ 
static Uchar rx_index_rd;
static Bool  tx_off;                 /* XOFF state indicator */
Uchar nb_rx_data;                    /* Number of data in the Rx buffer */

/*_____ D E C L A R A T I O N ______________________________________________*/
void  rx_buffer_wr(Uchar rx_data);

/*F**************************************************************************
* NAME: uart 
*----------------------------------------------------------------------------
* PURPOSE: 
* Uart interrupt handler: processes Rx uart events only.
*****************************************************************************/
Interrupt(void uart(void),4)
{
  if (RI == 1)              /* Processes Rx event only, not Tx */
  {   
    rx_buffer_wr(SBUF);     /* Writes the received data into the Rx buffer */
    RI = 0;
  }
  
} 
               
/*F**************************************************************************
* NAME: uart_tx 
*----------------------------------------------------------------------------
* PURPOSE: 
* Send a character over the serial link. Exit when the character 
* transmission is over.
*****************************************************************************/
void uart_tx(Uchar tx_data)
{
	SBUF = tx_data;
  WAIT_EO_TX;
}
    
/*F**************************************************************************
* NAME: uart_init 
*----------------------------------------------------------------------------
* PURPOSE: 
* Set the C51 Uart in 8-bit data, 9600 bauds, no parity operating mode.
*****************************************************************************/
void uart_init(void)
{
  SCON = 0x50;
  TMOD = TMOD | 0x20 ;      /*  Timer1 in mode 2 & not gated */
  TH1 = 0xFD;               /*  9600 bauds at 11.059200 MHZ */
  TL1 = 0xFD; 
  PCON = PCON & 0X80;
  TCON |= 0x40;         
  TI=1;
}

/*F**************************************************************************
* NAME: uart_rx_enable
*----------------------------------------------------------------------------
* PURPOSE: 
* Initializes Uart for data reception: circular buffer reset, XON/XOFF 
* protocol initialization and interrupt enabled.
*****************************************************************************/
void uart_rx_enable(void)
{
  rx_index_wr = rx_index_rd = nb_rx_data = 0;
  WAIT_EO_TX;                   /* Wait any previous transmission (printf) */
	uart_tx(XON);
  ES = 1; 
}



/*F**************************************************************************
* NAME: uart_rx_disable
*----------------------------------------------------------------------------
* PURPOSE: 
* Disable Rx reception upon interrupts.
*****************************************************************************/
void uart_rx_disable(void)
{
  ES = 0;
  TI = 1;                       /* Enable Tx for printf (polling) */
}

/*F**************************************************************************
* NAME: rx_buffer_empty
*----------------------------------------------------------------------------
* PARAMS:  
* return: TRUE when Rx buffer is empty.
*----------------------------------------------------------------------------
* PURPOSE: 
* Check if new Rx data have been stored in the Rx buffer.
*****************************************************************************/
Bool rx_buffer_empty(void)
{
  if (nb_rx_data == 0) 
    return TRUE;
  else
    return FALSE;
}

/*F**************************************************************************
* NAME: rx_buffer_wr 
*----------------------------------------------------------------------------
* PARAMS:  
* rx_data: Rx data to store in the buffer.
*----------------------------------------------------------------------------
* PURPOSE: 
* Stores the newly received data in the buffer and keep indexes updated. 
*****************************************************************************/
void rx_buffer_wr(Uchar rx_data)
{
  nb_rx_data++;
  rx_buffer[rx_index_wr] = rx_data;
  
  /* Circular buffer index computation */
  rx_index_wr = (rx_index_wr + 1) % RX_BUF_SIZE; 

  /* Stops host transmission when more than XOFF_THRES characters are stored 
   * in the Rx buffer */
  if ((tx_off==FALSE) && (nb_rx_data > XOFF_THRESH))
  { 
		uart_tx(XOFF);
    tx_off = TRUE;
  }   
}

/*F**************************************************************************
* NAME: rx_buffer_rd
*----------------------------------------------------------------------------
* PARAMS:  
* return: the next data available from the Rx buffer.
*----------------------------------------------------------------------------
* PURPOSE: 
* Retrieve the next data from the RX buffer.
*****************************************************************************
* NOTE: 
* All interrupts are disabled when updating rx_data because a Rx interrupt
* may occur and disturb the computation (rx_data also updated in the Uart 
* interrupt handler.
*****************************************************************************/
Uchar rx_buffer_rd(void)
{
	static Uchar data_cnt=0;			/* For progression dots */ 

  Uchar rx_data;

  EA=0;                        	/* Avoid conflicts with rx_buffer_wr() */
  nb_rx_data--;       
  EA=1;

  rx_data = rx_buffer[rx_index_rd];

  /* Circular buffer index computation */
  rx_index_rd = (rx_index_rd + 1) % RX_BUF_SIZE;

  /* Progression dots every 256 data */
	data_cnt++;
	if (data_cnt == 0) 
		uart_tx('.');

  /* Resumes host transmission when less than XON_THRES characters are stored 
   * in the Rx buffer */
	EA = 0;
  if ((tx_off == TRUE) && (nb_rx_data < XON_THRESH))
  { 
		uart_tx(XON);
    tx_off = FALSE;
  } 
	EA = 1;

  return(rx_data);
}

⌨️ 快捷键说明

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