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