ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Вторник
9 июля
295983 Топик полностью
Kit (31.12.2011 00:17, просмотров: 100) ответил OlegPowerC на Реализация концепции асинхронного вывода буффера в UART
Вот уже изобретенный велосипед:  //********************************************************************************************** //****************** 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 }