//*************************************************************************** // // Author(s)...: Pashgan http://ChipEnable.Ru // // Target(s)...: ATMega8535 // // Compiler....: IAR EWA 5.11A // // Description.: USART/UART. Используем кольцевой буфер // // Data........: 3.01.10 // //*************************************************************************** #include "usart.h" //передающий буфер unsigned char usartTxBuf[SIZE_BUF]; unsigned char txBufTail = 0; unsigned char txBufHead = 0; unsigned char txCount = 0; //приемный буфер unsigned char usartRxBuf[SIZE_BUF]; unsigned char rxBufTail = 0; unsigned char rxBufHead = 0; unsigned char rxCount = 0; //инициализация usart`a void USART_Init(void) { UBRRH = 0; UBRRL = 51; //скорость обмена 9600 бод UCSRB = (1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN); //разр. прерыв при приеме и передачи, разр приема, разр передачи. UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //размер слова 8 разрядов } //______________________________________________________________________________ //возвращает колличество символов передающего буфера unsigned char USART_GetTxCount(void) { return txCount; } //"очищает" передающий буфер void USART_FlushTxBuf(void) { txBufTail = 0; txCount = 0; txBufHead = 0; } //помещает символ в буфер, инициирует начало передачи void USART_PutChar(unsigned char sym) { //если модуль usart свободен и это первый символ //пишем его прямо в регистр UDR if(((UCSRA & (1<<UDRE)) != 0) && (txCount == 0)) UDR = sym; else { if (txCount < SIZE_BUF){ //если в буфере еще есть место usartTxBuf[txBufTail] = sym; //помещаем в него символ txCount++; //инкрементируем счетчик символов txBufTail++; //и индекс хвоста буфера if (txBufTail == SIZE_BUF) txBufTail = 0; } } } //функция посылающая строку по usart`у void USART_SendStr(unsigned char * data) { unsigned char sym; while(*data){ sym = *data++; USART_PutChar(sym); } } //обработчик прерывания по завершению передачи #pragma vector=USART_TXC_vect __interrupt void usart_txc_my(void) { if (txCount > 0){ //если буфер не пустой UDR = usartTxBuf[txBufHead]; //записываем в UDR символ из буфера txCount--; //уменьшаем счетчик символов txBufHead++; //инкрементируем индекс головы буфера if (txBufHead == SIZE_BUF) txBufHead = 0; } } //______________________________________________________________________________ //возвращает колличество символов находящихся в приемном буфере unsigned char USART_GetRxCount(void) { return rxCount; } //"очищает" приемный буфер __monitor void USART_FlushRxBuf(void) { rxBufTail = 0; rxBufHead = 0; rxCount = 0; } //чтение буфера unsigned char USART_GetChar(void) { unsigned char sym; if (rxCount > 0){ //если приемный буфер не пустой sym = usartRxBuf[rxBufHead]; //прочитать из него символ rxCount--; //уменьшить счетчик символов rxBufHead++; //инкрементировать индекс головы буфера if (rxBufHead == SIZE_BUF) rxBufHead = 0; return sym; //вернуть прочитанный символ } return 0; } //прерывание по завершению приема #pragma vector=USART_RXC_vect __interrupt void usart_rxc_my(void) { if (rxCount < SIZE_BUF){ //если в буфере еще есть место usartRxBuf[rxBufTail] = UDR; //считать символ из UDR в буфер rxBufTail++; //увеличить индекс хвоста приемного буфера if (rxBufTail == SIZE_BUF) rxBufTail = 0; rxCount++; //увеличить счетчик принятых символов } }