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

📄 serialkd.c

📁 基于80196KB开发的C程序,在伟福和星研环境中编译通过,用于学习8096系列单片机的中断编程技术.并成功地用于某地机动车检测业务.
💻 C
字号:
/*
** FILE     : serialkd.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(kd) control
**            or use: #pragma model(kd)
**            or even better use:
**                      mk196 -f serialkd.mak
*/
//#pragma model(196)
#include        <stdio.h>
#include        <kd_sfrs.h>
#include        <kd_funcs.h>

/* declare interrupt routines */
#pragma interrupt(receive=25,transmit=24)


/*   Initialize the chip configuration bytes   */
const unsigned int            ccr = {0x20CD};
#pragma locate(ccr=0x2018)


#define         FREQUENCY               12000000L    /* 16 MHz  */
#define         BAUD_RATE_VALUE         1200
#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_stat  to preserve the RI
                                                                 and TI bits on a read.  */

/*   receive and transmit buffers and their indexes    */

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

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


/*  declares and locates the special function registers  */

void transmit(void)                                         /* serial interrupt routine  */
{
    wsr = 0;

    status_temp |= sp_stat;                                 /* image sp_stat into status_temp  */

    /*   transmitt a character if there is a character in the buffer  */
    if (begin_trans_buff != end_trans_buff)
    {
        sbuf = 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 - 1)
            begin_trans_buff=0;
        status_temp &= (~TI_BIT);                           /* clear TI bit in status_temp.   */
    }
}

void receive(void)                                          /* serial interrupt routine  */
{
    wsr = 0;

    status_temp |= sp_stat;                                 /* image sp_stat 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))
    {
        ;                                                   /* 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 - 1)
            end_rec_buff=0;
        receive_buff[end_rec_buff]=sbuf;                    /* 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));

    trans_buff[end_trans_buff]=c;                           /*  put character in buffer  */
    if (++end_trans_buff>TRANSMIT_BUF_SIZE - 1)             /*  make buffer appear  */
        end_trans_buff=0;                                   /*  circular.           */
    if (status_temp & TI_BIT)
        int_pend1 |= 0x01;                                  /*  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 avaliable. */
    if (++begin_rec_buff>RECEIVE_BUF_SIZE - 1)              /*  make buffer appear    */
        begin_rec_buff=0;                                   /*  circular.  */
    return(receive_buff[begin_rec_buff]);                   /*  return the character in buffer. */
}

void init_serial_port(void)
{
    unsigned char                 wsr_image = wsr;
    wsr = 0;
    baud_rate = ((unsigned char) BAUD_REG);
    baud_rate = ((unsigned char) (BAUD_REG >> 8));
    sp_con = 0x09;                                          /* mode 1,
                                                             * no parity,
                                                             * receive enabled,
                                                             * no 9th bit */
    status_temp = sp_stat | TI_BIT;

    end_rec_buff=0;                                         /* initialize buffer pointers        */
    begin_rec_buff=0;
    end_trans_buff=0;
    begin_trans_buff=0;
 
    int_mask1 = 0x03;                                       /* enable the serial port interrupts  */
    
    enable();                                               /* global enable of interrupts       */
    wsr = wsr_image;                                        /* restore wsr */
}

void main(void)
{
    char                          c;
    init_serial_port();
    while((c=getch()) != 0x1b)                              /*  stay in loop till escape key pressed  */
     // printf("key pressed = %02X\n\r",c);
     putchar(c);
}

⌨️ 快捷键说明

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