Modbus_master_2/uart/uart.c

120 lines
5.2 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; // Записываем в регистр значение переменной "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++; //увеличить счетчик принятых символов
}
}