Вот уже изобретенный велосипед:
//**********************************************************************************************
//****************** USART SUBROUTINES *********************************************************
//**********************************************************************************************
#define UART_TXD_PIN (1<<5)
#define UART_RXD_PIN (1<<6)
#define UART_RX_OVERFLOW 1
#define UART_TX_OVERFLOW 4
#define UART_OVRE 2
#define RX_BUF_LEN 400 // Длина буфера приема
#define TX_BUF_LEN 20 // Длина буфера передачи
__no_init unsigned char RX_Buf[RX_BUF_LEN]; // Буфер приема из RS232
unsigned short int RX_Buf_Head,RX_Buf_Tail; // Указатели в буфере приема из RS232
__no_init unsigned char TX_Buf[TX_BUF_LEN]; // Буфер передачи RS232
unsigned short int TX_Buf_Head,TX_Buf_Tail; // Указатели в буфере передачи RS232
unsigned char UART_Error;
unsigned int UART_CountError;
int UART_TX_Len(void);
//------------------------- Инициализация USART -----------------------------------------------------
void UART_Init(unsigned int UART_SPEED){
unsigned int SavI;
SavI=__get_CPSR();
__set_CPSR(SavI|I_BIT);
RX_Buf_Head=RX_Buf_Tail=TX_Buf_Head=TX_Buf_Tail=0;
// прерывания: TXRDY, RXRDY
*AT91C_PMC_PCDR=(1<<AT91C_ID_US0); // Выключить тактовую для периферии
*AT91C_US0_IDR=0xFF; // Выключение всех прерываний от USART
*AT91C_US0_CR=0x10C; // Сбросить UART 1
*AT91C_US0_CR=0x10C; // Сбросить UART 2
*AT91C_US0_CR=0x50; // Включить приемник и передатчик
*AT91C_US0_MR=0x001028C0|AT91C_US_FILTER; // 0x101020C0
*AT91C_US0_BRGR=QFREQ/16/UART_SPEED; // Делитель для UARTa
*AT91C_US0_IER=0x1; // Включение прерываний от TXRDY, RXRDY
*AT91C_PIOA_PDR=UART_TXD_PIN|UART_RXD_PIN;
*AT91C_PIOA_ASR=UART_TXD_PIN|UART_RXD_PIN;
*AT91C_PMC_PCER=(1<<AT91C_ID_US0); // Включить тактовую для периферии
UART_Error=0;
UART_CountError=0;
__set_CPSR(SavI); }
//******** Low byte first **********************************************************************
//**********************************************************************************************
void UART_Send_Byte(unsigned char Byte){
TX_Buf[TX_Buf_Head++]=Byte;
if(TX_Buf_Head>=TX_BUF_LEN) TX_Buf_Head=0;
if(TX_Buf_Head==TX_Buf_Tail){ UART_Error|=UART_TX_OVERFLOW; UART_CountError++; }
}
//**********************************************************************************************
unsigned int UART_Get_Byte(void){
unsigned int RetVal=RX_Buf[RX_Buf_Tail++];
if(RX_Buf_Tail>=RX_BUF_LEN) RX_Buf_Tail=0;
return RetVal; }
//**********************************************************************************************
int UART_RX_Len(void){
unsigned int SavI=__get_CPSR(),Res;
__set_CPSR(SavI|I_BIT);
Res= (RX_Buf_Head>=RX_Buf_Tail?RX_Buf_Head-RX_Buf_Tail:(RX_Buf_Head+RX_BUF_LEN)-RX_Buf_Tail);
__set_CPSR(SavI);
return Res;
}
//**********************************************************************************************
int UART_TX_Len(void){
unsigned int SavI=__get_CPSR(),Res;
__set_CPSR(SavI|I_BIT);
Res= (TX_Buf_Head>=TX_Buf_Tail?TX_Buf_Head-TX_Buf_Tail:(TX_Buf_Head+TX_BUF_LEN)-TX_Buf_Tail);
__set_CPSR(SavI);
return Res;
}
//**********************************************************************************************
inline void UART_Start_Transmit(void){ *AT91C_US0_IER=AT91C_US_TXRDY; } // Включение прерываний от TXRDY
//**********************************************************************************************
void UART_TX_Clear(void){
unsigned int SavI=__get_CPSR();
__set_CPSR(SavI|I_BIT);
TX_Buf_Head=TX_Buf_Tail=0;
__set_CPSR(SavI);
}
//**********************************************************************************************
void UART_RX_Clear(void){
unsigned int SavI=__get_CPSR();
__set_CPSR(SavI|I_BIT);
RX_Buf_Head=RX_Buf_Tail=0;
__set_CPSR(SavI);
}
//************* Обработчик прерывания от UART **************************************************
__nested __irq __arm void UART_Irq_Handler(void){
unsigned int Status;
Status=*AT91C_US0_CSR; // Считываем источник прерывания
if(Status&AT91C_US_OVRE){ UART_Error|=UART_OVRE; UART_CountError++; }
if ( (Status & AT91C_US_TXRDY ) ) // Если порт готов к передаче байта
if(TX_Buf_Head!=TX_Buf_Tail ){ // и есть данные для передачи
*AT91C_US0_THR=TX_Buf[TX_Buf_Tail++]; // отправляем байт из буфера передачи
if(TX_Buf_Tail>=TX_BUF_LEN) TX_Buf_Tail=0; } // Проверка выхода указателя головы за конец буфера
else
*AT91C_US0_IDR=AT91C_US_TXRDY; // Если буфер передачи пуст, отключаем источник прерываний
if ( Status & AT91C_US_RXRDY){ // Если был принят байт
RX_Buf[RX_Buf_Head++]=*AT91C_US0_RHR; // Переписываем его в приемный буфер
if(RX_Buf_Head>=RX_BUF_LEN) RX_Buf_Head=0; // Проверка выхода указателя головы за конец буфера
if(RX_Buf_Head==RX_Buf_Tail) UART_Error|=UART_RX_OVERFLOW;
}
*AT91C_US0_CR = AT91C_US_RSTSTA; // Очищаем флаги ошибок
*AT91C_AIC_EOICR=1; // Отправляем сигнал окончания обработки прерывания EOI
}