Display_Avr_3/UART/uart.c
Kirill Kurshakow 0a9eb215db uart modified
2023-11-07 12:01:09 +03:00

119 lines
4.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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; // Записываем в регистр значение переменной для передачи
}
// очищение буфера
void USART_FlushTxBuf(void)
{
txBufTail = 0;
txCount = 0;
txBufHead = 0;
void USART_PutChar(unsigned char sym)
{
if(((UCSRA0 & (1<<UDRE0)) != 0) && (txCount == 0)) // Если модуль не занят и передающий буфер пустой, символ записывается в регистр UDR
UDR0 = sym;
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++; // увеличиваем счетчик принятых символов
}
}