📄 16c550.c
字号:
#include <16C550Cfg.h>
#include <reg52.h>
//----------------------------------------------------------------------------------------
typedef unsigned char uchr;
typedef unsigned int uint;
typedef unsigned long ulng;
//----------------------------------------------------------------------------------------
#define bit_test(BBYTE,BBIT) ( ( BBYTE ) & ( 1 << ( BBIT ) ) )
#define bit_set(BBYTE,BBIT) ( BBYTE ) |= ( 1 << ( BBIT ) )
#define bit_clr(BBYTE,BBIT) ( BBYTE ) &= ~( 1 << ( BBIT ) )
//----------------------------------------------------------------------------------------
#if C550_USING_EXTERN_INT_NUMBER==1
#define C550_IE IE1
#define C550_IT IT1
#define C550_EX EX1
#define C550_INT 2
#elif C550_USING_EXTERN_INT_NUMBER==0
#define C550_IE IE0
#define C550_IT IT0
#define C550_EX EX0
#define C550_INT 0
#else
#error "C550_USING_EXTERN_INT_NUMBER" 定义错误,取值范围(0,1)
#endif
//----------------------------------------------------------------------------------------
C550_REG struct {
char flag;
uchr rin;
uchr rout;
uchr tin;
uchr tout;
uchr rbuff[ C550_RBUFF_LEN ];
uchr tbuff[ C550_TBUFF_LEN ];
} c550;
#define K_START 0
#define K_TIMEOUT 1
/*----------------------------------------------------------------------------------------
名 称: c550_init
功 能: 初始化16C550寄存器和缓冲区
说 明:
原 型: void c550_init( void )
参 数:
返回值:
作 者: 李德强
编译器: Keil C51 V7
创 建: 2003年12月29日 09:44
----------------------------------------------------------------------------------------*/
void c550_init( void ) {
uint len;
uchr C550_REG * ptr;
len = sizeof( c550 );
ptr = ( uchr C550_REG * )&c550;
do {
*ptr = 0;
++ ptr;
} while( -- len );
//SET FCR
C550_FCR = C550_VAL_FCR;
//SET MCR
C550_MCR = C550_VAL_MCR;
//SET LCR Select Divisor Latch Enable
bit_set( C550_LCR, 7 );
//SET BAUD
C550_DLL = C550_VAL_DL;
C550_DLM = C550_VAL_DL >> 8;
//SET LCR
C550_LCR = C550_VAL_LCR;
//SET IER
C550_IER = C550_VAL_IER;
C550_IT = 1;
C550_EX = 1;
EA = 1;
}
/*----------------------------------------------------------------------------------------
名 称: c550_trsblank
功 能: 获取发送缓冲区内剩余空间
说 明:
原 型: unsigned char c550_trsblank( void )
参 数:
返回值: 发送缓冲区内剩余空间
作 者: 李德强
编译器: Keil C51 V7
创 建: 2003年12月29日 09:44
----------------------------------------------------------------------------------------*/
uchr c550_trsblank( void ) {
uchr tmp;
tmp = c550.tin - c550.tout;
if( tmp >= C550_TBUFF_LEN ) return 0;
return C550_TBUFF_LEN - tmp;
}
/*----------------------------------------------------------------------------------------
名 称: c550_rcvhold
功 能: 获取接收缓冲区内字符数
说 明:
原 型: unsigned char c550_rcvhold( void )
参 数:
返回值: 接收缓冲区内字符数
作 者: 李德强
编译器: Keil C51 V7
创 建: 2003年12月29日 09:45
----------------------------------------------------------------------------------------*/
uchr c550_rcvhold( void ) {
return c550.rin - c550.rout;
}
/*----------------------------------------------------------------------------------------
名 称: c550_putstr
功 能: 发送一个字符串
说 明:
原 型: unsigned char c550_putstr( unsigned char len, char * str )
参 数: len 待发送字符串长度
str 待发送字符串的首地址
返回值: 实际发送的字符数量
作 者: 李德强
编译器: Keil C51 V7
创 建: 2003年12月29日 09:48
----------------------------------------------------------------------------------------*/
uchr c550_putstr( uchr len, char * str ) {
uchr count;
count = c550.tin - c550.tout;
if( count >= C550_TBUFF_LEN ) return 0;
count = C550_TBUFF_LEN - count;
if( len > count ) len = count;
else count = len;
while( len -- ) {
c550.tbuff[ ( c550.tin ++ ) & ( C550_TBUFF_LEN - 1 ) ] = (*str);
++ str;
} //while
if( ( count != 0 ) && ( ! bit_test( c550.flag, K_START ) ) ) {
bit_set( c550.flag, K_START );
C550_THR = c550.tbuff[ (c550.tout ++ ) & ( C550_TBUFF_LEN - 1 ) ];
} //if
return count;
}
/*----------------------------------------------------------------------------------------
名 称: c550_rclear
功 能:
说 明:
原 型: void c550_rclear( unsigned char len )
参 数: len 要获取的字符串长度
返回值:
作 者: 李德强
编译器: Keil C51 V7
创 建: 2003年12月29日 09:49
----------------------------------------------------------------------------------------*/
void c550_rclear( uchr len ) {
uchr count;
count = c550.rin - c550.rout;
if( len > count ) {
c550.rin = 0;
c550.rout = 0;
}
else {
c550.rout += len;
}
}
/*----------------------------------------------------------------------------------------
名 称: c550_getstr
功 能: 获取一个字符串
说 明:
原 型: unsigned char c550_getstr( unsigned char len, char * str )
参 数: len 要获取的字符串长度
str 保存字符串的首地址
返回值: 实际获取的字符数量
作 者: 李德强
编译器: Keil C51 V7
创 建: 2003年12月29日 09:49
----------------------------------------------------------------------------------------*/
uchr c550_getstr( uchr len, char * str ) {
uchr count;
count = c550.rin - c550.rout;
if( len > count ) len = count;
else count = len;
while( len -- ) {
*str = c550.rbuff[ ( c550.rout ++ ) & ( C550_RBUFF_LEN - 1) ];
++ str;
} //while
return count;
}
/*----------------------------------------------------------------------------------------
名 称: c550_isr
功 能: 16C550的中断服务函数
说 明:
原 型: void c550_isr( void )
参 数:
返回值:
作 者: 李德强
编译器: Keil C51 V7
创 建: 2003年12月29日 09:46
----------------------------------------------------------------------------------------*/
void c550_isr( void ) interrupt C550_INT using 1
{
uchr tmp;
uchr count;
//RXRDY
while( bit_test( C550_LSR, 0 ) ) {
tmp = C550_RHR;
count = c550.rin - c550.rout;
if( count <= C550_RBUFF_LEN ) {
c550.rbuff[ ( c550.rin ++ ) & ( C550_RBUFF_LEN - 1 ) ] = tmp;
} //if
}
//TXRDY
if( bit_test( C550_LSR, 5 ) ) {
count = c550.tin - c550.tout;
if( count > 16 ) count = 16;
tmp = count;
if( tmp == 0 ) {
bit_clr( c550.flag, K_START );
} //if
else {
while( tmp -- ) {
C550_THR = c550.tbuff[ ( c550.tout ++ ) & ( C550_TBUFF_LEN - 1 ) ];
} //while
} //else
} //if
//处理C550_ISR
while( ! ( bit_test( C550_ISR, 0 ) ) );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -