📄 serialkd.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 + -