Аппаратный UART

c-file

/**
* @file	uart1.c
* @brief	UART1 module
*
* @author      Rustem Kalimullin
* @par E-mail:
*              hellos@mail.ru
*/
 
#include "common.h"
#include "circ_buf.h"
 
#ifndef UART1_BUFFER_SIZE
#define UART1_BUFFER_SIZE 0x10
#endif
 
#if (UART1_BUFFER_SIZE & (UART1_BUFFER_SIZE-1))
#error UART1_BUFFER_SIZE must be power of 2
#endif
 
DECLARE_CIRC_BUFFER( RxBuf1, UART1_BUFFER_SIZE );
DECLARE_CIRC_BUFFER( TxBuf1, UART1_BUFFER_SIZE );
 
 
//---------------------------------------------------------
void uart1_purge(int mask)
{
	istate_t int_state = __get_interrupt_state();
	__disable_interrupt();
 
	if( mask & PURGE_RXCLEAR ) circ_Init(&RxBuf1.b);
	if( mask & PURGE_TXCLEAR ) circ_Init(&TxBuf1.b);
 
	if( mask & PURGE_ABORT ) {
		U1CTL |= SWRST;
		__no_operation();
		U1CTL &= ~SWRST;
		U1IE |= (URXIE1 | UTXIE1);
	}
 
	__set_interrupt_state(int_state);
}
 
 
//---------------------------------------------------------
void uart1_enable_parity(void)
{
	istate_t int_state = __get_interrupt_state();
	U1CTL  = PENA | PEV | SWRST;  // 7e1, Software Reset
	U1CTL &= ~SWRST;
	U1IE |= (URXIE1 | UTXIE1);
	__set_interrupt_state(int_state);
}
 
//---------------------------------------------------------
void uart1_init(long baud)
{
	istate_t int_state = __get_interrupt_state();
	unsigned int uart_div = (long)xtal_freq / (long)baud;
 
	__disable_interrupt();
 
	U1CTL  = CHAR | SWRST;      // 8n1, Software Reset
	U1TCTL = SSEL1;             // UCLK = SMCLK
	U1MCTL = 0x00;              // no modulation
 
	U1BR0 = (unsigned char) (uart_div & 0xFF);
	U1BR1 = (unsigned char) (uart_div >> 8);
 
	uart1_purge( PURGE_ABORT | PURGE_RXCLEAR | PURGE_TXCLEAR );
 
	P3SEL |= (1<<6)|(1<<7);       // P3.6,7 = USART1 option select
	P3DIR |= (1<<6);              // P3.6 = output direction
 
	U1ME |= (URXE1 | UTXE1);
	U1CTL &= ~SWRST;
	U1IE |= (URXIE1 | UTXIE1);
 
	__set_interrupt_state(int_state);
}
 
 
//---------------------------------------------------------
unsigned char uart1_getchar(void)
{
	int t;
	do {
		t = circ_Get( &RxBuf1.b );
	} while( t == -1 );
	return t;
}
 
//---------------------------------------------------------
int uart1_getchar_timeout( unsigned int tot )
{
	int t;
	do {
		t = circ_Get( &RxBuf1.b );
		if( t != -1 ) break;
	} while( --tot );
	return t;
}
 
//---------------------------------------------------------
void uart1_putchar( unsigned char ch )
{
	while( circ_Put( &TxBuf1.b, ch ) == -1 ) continue;
	if ((U1TCTL & TXEPT)) SET_BITS(U1IFG,UTXIFG1);
}
 
//---------------------------------------------------------
void uart1_puts(const char *s)
{
	while(*s) uart1_putchar(*s++);
}
 
//---------------------------------------------------------
int uart1_is_rxdata(void)
{
	return ( circ_HasData( &RxBuf1.b ) );
}
 
//---------------------------------------------------------
int uart1_is_txdata(void)
{
	if ( circ_HasData( &TxBuf1.b ) ) {
		return 1;
	} else {
		return (U1IFG & UTXIFG1);
	}
}
 
//---------------------------------------------------------
#pragma vector=USART1RX_VECTOR
__interrupt void uart1_rx_handler(void)
{
	circ_Put( &RxBuf1.b, U1RXBUF );
}
 
//---------------------------------------------------------
#pragma vector=USART1TX_VECTOR
__interrupt void uart1_tx_handler(void)
{
	int t = circ_Get( &TxBuf1.b );
	if( t != -1 ) {
		U1TXBUF = t;
	} else {
		U1TCTL |= TXEPT;
	}
}

h-file

#ifndef KR_UART1_INCLUDED
#define KR_UART1_INCLUDED
 
enum { PURGE_ABORT=1, PURGE_TXCLEAR=2, PURGE_RXCLEAR=4 };
 
void uart1_init( long baud );
 
void uart1_purge( int mask );
 
unsigned char uart1_getchar( void );
int uart1_getchar_timeout( unsigned int tot );
 
void uart1_putchar( unsigned char ch );
void uart1_puts( const char *s );
 
int uart1_is_rxdata( void );
int uart1_is_txdata( void );
 
void uart1_enable_parity( void );
 
#endif
 
sources/uart1.txt · Последние изменения: 2021/10/09 14:22 kurt