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

📄 serialkr.c

📁 MCS-196单片机的串口通讯.采用C语言编译.有灵活的移植功能.
💻 C
字号:
/*
** FILE     : serialkr.c
**            This program was published in "Embedded Applications Journal" 3Q 1993.
**            The article: 'C' Interrupt Routine for the serial MCS-96 Asynchronous Port.
**            by Larry C. Ferra, Intel Corporation.
**
** NOTE     : compile with model(kr) control
**            or use: #pragma model(kr)
**            or even better use:
**                      mk196 
*/

#ifdef  _C196_
#if _ARCHITECTURE_ != 'KR'
/* This will generate a warning, please check model() control. */
#pragma model(KR)
#endif
#endif
#include        <stdio.h>
#include        <kr_sfrs.h>
#include        <kr_funcs.h>

/* declare interrupt routines */
#pragma interrupt(receive=28,transmit=27)


#ifdef EVAL_BOARD

/*   Reserve the 9 bytes required by eval board   */

char                          reserve[9];
#pragma locate(reserve=0x30)

#else

/*   Initialize the chip configuration bytes   */
const unsigned int            ccr[2] = {0x20FF,0x20DE};
#pragma locate (ccr = 0x2018)

#endif

#define		WINDOW_SELECT		0x1F

#define		FREQUENCY		(long)16000000 /* 16 MHz  */
#define		BAUD_RATE_VALUE		9600
#define		BAUD_REG		((unsigned int)(FREQUENCY/((long)BAUD_RATE_VALUE*16)-1)+0x8000)

#define		RI_BIT			0x40
#define		TI_BIT			0x20

unsigned char                 status_temp;                  /*   image of sp_status  to preserve the RI
                                                                 and TI bits on a read.  */

/*   receive and transmit buffers and their indexes    */

#define		TRANSMIT_BUF_SIZE	20
unsigned char                 trans_buff[TRANSMIT_BUF_SIZE];
char                          begin_trans_buff;
char                          end_trans_buff;

#define		RECEIVE_BUF_SIZE	20
unsigned char                 receive_buff[RECEIVE_BUF_SIZE];
char                          end_rec_buff;
char                          begin_rec_buff;


/*  serial interrupt routine  */
/*  see pragma interrupt above */
void transmit(void)
{
    wsr = WINDOW_SELECT;                                    /*  Use SFR_1f if available */
    status_temp |= sp_status;                               /*  image sp_status into status_temp  */

    /*   transmitt a character if there is a character in the buffer  */
    if (begin_trans_buff != end_trans_buff)
    {
	sbuf_tx_1f = trans_buff[begin_trans_buff];          /*  transmit character  */

	/*   The next statement makes the buffer circular by starting over when the
	     index reaches the end of the buffer.   */

	if (++begin_trans_buff >= TRANSMIT_BUF_SIZE)
            begin_trans_buff = 0;
	status_temp &= ~TI_BIT;                             /*  clear TI bit in status_temp.   */
    }
}

/*  serial interrupt routine  */
/*  see pragma interrupt above */
void receive(void)
{
    wsr = WINDOW_SELECT;                                    /*  Use SFR_1f if available */
    status_temp |= sp_status;                               /*  image sp_status into status_temp  */

    /*   If the input buffer is full, the last character will be ignored,
	 and the BEL character is output to the terminal.  */

    if (end_rec_buff+1==begin_rec_buff
	||
	(end_rec_buff==RECEIVE_BUF_SIZE-1 && begin_rec_buff==0)
	)
    {
	;                                                   /*  input overrun code  */
    }
    else
    {
	/*   The next statement makes the buffer circular by starting over when the
	     index reaches the end of the buffer.   */

	if (++end_rec_buff >= RECEIVE_BUF_SIZE)
            end_rec_buff = 0;
	receive_buff[end_rec_buff] = sbuf_rx_1f;            /*  place character in buffer  */
    }
    status_temp &= ~RI_BIT;                                 /*  clear RI bit in status_temp.  */
}

/* See stdio.h for declaration of putch. */
int putch(int c)
{
    /*   remain in loop while the buffer is full.  This is done by checking
	 the end of buffer index to make sure it does not overrun the
	 beginning of buffer index.   The while instruction checks the case
	 when the end index is one less then the beginning index and at the
	 end of the buffer when the beginning index may be equal to 0 and
	 the end buffer index may be at the buffer end.   */

    while (end_trans_buff+1==begin_trans_buff
	   ||
	   (end_trans_buff==TRANSMIT_BUF_SIZE-1 && begin_trans_buff==0)
	   )
      /* loop here */;

    trans_buff[end_trans_buff] = c;                         /*  put character in buffer  */
    if (++end_trans_buff >= TRANSMIT_BUF_SIZE)              /*  make buffer appear circular */
        end_trans_buff = 0;
    if (status_temp & TI_BIT)
        int_pend1 |= 0x08;                                  /*  If transmitt buffer
                                                                was empty, then cause
                                                                an interrupt to start
                                                                transmitting.  */
}

/* See stdio.h for declaration of getch. */
int getch(void)
{
    while (begin_rec_buff == end_rec_buff);                 /* remain in loop while there is
                                                               not a character available. */
    if (++begin_rec_buff >= RECEIVE_BUF_SIZE)               /*  make buffer appear circular */
        begin_rec_buff = 0;
    return receive_buff[begin_rec_buff];                    /*  return the character in buffer. */
}

void main(void)
{
    char                          c;

    wsr = WINDOW_SELECT;                                    /*  Use SFR_1f if available */
    sp_baud = BAUD_REG;                                     /* set baud rate as described by the Embedded
                                                             ** Controller Handbook
                                                             */
    sp_con  = 0x09;                                         /* mode 1, no parity, receive enabled, no 9th bit */
    status_temp = sp_status;
    p2_reg   = 0xFF;                                         /*  Init port2 reg */
    p2_dir   = 0xFE;                                         /*  TXD output     */
    p2_mode  = 0x03;                                         /*  p2.0-1 lsio  */
 
    wsr = 0;                                                /*  Use SFR without suffix */
    end_rec_buff     = 0;                                   /* initialize buffer pointers        */
    begin_rec_buff   = 0;
    end_trans_buff   = 0;
    begin_trans_buff = 0;
    status_temp = TI_BIT;                                   /* allow for initial transmission    */
    int_mask1   = 0x18;                                     /* enable the serial port interrupt  */

    enable();                                               /* global enable of interrupts       */
 
    while ((c=getch()) != 0x1b)                             /*  stay in loop till escape key pressed  */
        printf("key pressed = %02X\r\n",c);
}

⌨️ 快捷键说明

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