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

📄 16c550.c

📁 51单片机驱动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 + -