#include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #define F_CPU 16000000 #define SIZE_BUF 8 //кольцевой (циклический) буфер volatile unsigned char usartTxBuf[SIZE_BUF]; unsigned char txBufTail = 0; //"указатель" хвоста буфера unsigned char txBufHead = 0; //"указатель" головы буфера volatile unsigned char txCount = 0; //счетчик символов uint8_t receive = 0; uint8_t rx_data = 0; volatile uint8_t rx_flag = 0; void UARTInit(void) { UCSR1B=0; UCSR1C=0; // Обнулим, на всякий случай регистры статуса и контроля. UBRR0H = 0; // Старшие биты регистра скорости. UBRR0L = 103; //скорость передачи данных 9600 UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0)|(1<<TXCIE0)|(0<<UDRIE0);//Включаем (подключаем ножки контроллера) приём и передачу по UART. UCSR0C = (1<<UCSZ01)|(1<<UCSZ00); //8 bit } void UARTSend(uint8_t data) { while (!(UCSR0A & (1<<UDRE0))); // Ждём опустошения буфера передачи (читаем флаг). UDR0 = data; // Записываем в регистр значение переменной "data" для передачи. } //"очищает" буфер void USART_FlushTxBuf(void) { txBufTail = 0; txCount = 0; txBufHead = 0; //положить символ в буфер void USART_PutChar(unsigned char sym) { if(((UCSRA0 & (1<<UDRE0)) != 0) && (txCount == 0)) //Если модуль USART не занят и передающий буфер пустой, UDR0 = sym; //символ записывается в регистр UDR else { if (txCount < SIZE_BUF){ //если в буфере еще есть место usartTxBuf[txBufTail] = sym; //помещаем в него символ txCount++; //инкрементируем счетчик символов txBufTail++; //и индекс хвоста буфера if (txBufTail == SIZE_BUF) txBufTail = 0; } } } //взять символ из буфера unsigned char GetChar(void) { unsigned char sym = 0; if (count > 0){ //если буфер не пустой sym = cycleBuf[head]; //считываем символ из буфера count--; //уменьшаем счетчик символов head++; //инкрементируем индекс головы буфера if (head == SIZE_BUF) head = 0; } return sym; } //функция загрузки строк void USART_SendStr(unsigned char * data) { unsigned char sym; while(*data){ // пока не будет считан символ конца строки sym = *data++; USART_PutChar(sym); } } // unsigned char UARTGet() { // while(!rx_flag); //пока значение флага не станет равно "1" // rx_flag = 0; // return rx_data; //возвращет состояние переменной rx_data // } int main(void) { sei(); UARTInit(); DDRL = 0b11111111; // Определим порт "L" на выход while(1) { receive = UARTGet(); receive++; UARTSend(receive); } } //обработчик прерывания по завершению передачи ISR(USART_TXC_vect) { if (txCount > 0){ //если буфер не пустой UDR0 = usartTxBuf[txBufHead]; //записываем в UDR символ из буфера txCount--; //уменьшаем счетчик символов txBufHead++; //инкрементируем индекс головы буфера if (txBufHead == SIZE_BUF) txBufHead = 0; } else { UCSR0B &= ~(0<<TXCIE0); } // rx_data = UDR0; //В нем данные из приемного буфера UDR переносятся в глобальную переменную rx_data // rx_flag = 1; //выставляется флаг rx_flag, говорящий о том, что прием завершен } //прерывание по завершению приема ISR (USART_RXC_vect) { if (rxCount < SIZE_BUF){ //если в буфере еще есть место usartRxBuf[rxBufTail] = UDR0; //считать символ из UDR в буфер rxBufTail++; //увеличить индекс хвоста приемного буфера if (rxBufTail == SIZE_BUF) rxBufTail = 0; rxCount++; //увеличить счетчик принятых символов } }