uart #11

Merged
stud126165 merged 4 commits from uart into dev 2024-02-06 07:32:16 +00:00
10 changed files with 337 additions and 127 deletions
Showing only changes of commit 0a9eb215db - Show all commits

36
UART/circular_buf.c Normal file
View File

@ -0,0 +1,36 @@
#include <stdio.h>
#include <stdlib.h>
#include "circular_buf.h"
void initialize_buffer(struct circular_buffer* cb) {
cb->buf_head = 0;
cb->buf_tail = 0;
}
// Проверка, пустой ли буфер
int buffer_empty(const struct circular_buffer* cb) {
return cb->buf_head == cb->buf_tail;
}
// Проверка, заполнен ли буфер
int buffer_full(const struct circular_buffer* cb) {
return (cb->buf_tail + 1) % BUFFER_SIZE == cb->buf_head; //проверяем следующее число, если оно будет совпадать с индексом головы то будет false, при совпадении вывод true
}
// Запись в буфер
void write_buffer(struct circular_buffer* cb, int value) {
if (buffer_full(cb)) { // проверяем, заполнен ли буфер
return;
}
cb->buffer[cb->buf_tail] = value;// записываем значение в элемент массива в хвост
cb->buf_tail = (cb->buf_tail + 1) % BUFFER_SIZE;// присваивается cb->buf_tail, обновляется его значение на следующий индекс в буфере
}
// Чтение элемента
int read_buffer(struct circular_buffer* cb) {
if (buffer_empty(cb)) { // проверка на пустоту
return -1;// -1 как индикатор в случае ошибки
}
int value = cb->buffer[cb->buf_head]; // чтение по индексу головы
cb->buf_head = (cb->buf_head + 1) % BUFFER_SIZE; // увеличиваем индекс на 1
return value;
}

18
UART/circular_buf.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef CIRCULAR_BUFFER_H
#define CIRCULAR_BUFFER_H
#define BUFFER_SIZE 32
struct circular_buffer{
unsigned char buffer[BUFFER_SIZE];
unsigned char buf_head;
unsigned char buf_tail;
};
void initialize_buffer(struct circular_buffer* cb);
int buffer_empty(const struct circular_buffer* cb);
int buffer_full(const struct circular_buffer* cb);
void write_buffer(struct circular_buffer* cb, int value);
int read_buffer(struct circular_buffer* cb);
#endif /* CIRCULAR_BUFFER_H */

123
UART/main.c Normal file
View File

@ -0,0 +1,123 @@
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
#include <string.h>
#include "timer.h"
#include "circular_buf.h"
#define F_CPU 16000000
struct circular_buffer usartTxBuffer;
struct circular_buffer usartRxBuffer;
void UART_init(void) {
UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0) | (1 << UDRIE0); // прерывание по приему и опустошению буфера передачи
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
UBRR0H = 0;
UBRR0L = 103;
}
void UART_send(uint8_t* data, size_t length) {
for (size_t i = 0; i < length; i++) {
if (!buffer_full(&usartTxBuffer)) {
write_buffer(&usartTxBuffer, data[i]);
} else {
break; // если буфер передачи заполнен, то отправка прерывается
}
}
UCSR0B |= (1 << UDRIE0); // Включаем прерывание по опустошению буфера
}
void USART_put_char(unsigned char sym) {
if (((UCSR0A & (1 << UDRE0)) != 0) && buffer_empty(&usartTxBuffer)) {
UDR0 = sym;
} else {
if (!buffer_full(&usartTxBuffer)) {
write_buffer(&usartTxBuffer, sym);
} else {
// Буфер передачи полон, обработка ошибки или другая логика
}
}
}
int get_char(unsigned char* sym) {
if (!buffer_empty(&usartTxBuffer)) {
*sym = read_buffer(&usartTxBuffer);
return 1; // Символ успешно прочитан
} else {
return 0; // Буфер пуст, ошибка чтения
}
}
void USART_send_str(const unsigned char* data) {
while (*data) {
USART_put_char(*data++);
}
}
uint32_t receivedByteCount = 0;
// Получение данных из буфера
int UART_receive(uint8_t* data, size_t length) {
char overflow=0;
uint32_t byteCount=0;
uint32_t timeout_ms_mb = 100;
uint32_t timeout_ms = 4;
uint32_t start_time = millis();
while (buffer_empty(&usartRxBuffer)) {
if ((millis() - start_time) > timeout_ms_mb) {
// Обработка ошибки или таймаута
return -1;
}
}
while(1)
{
while (!buffer_empty(&usartRxBuffer)) {
int reader = read_buffer(&usartRxBuffer);//прием и запись символа в переменную
if(byteCount<=length){
data[byteCount] = reader; // запись в массив с индексом byteCount
}
else{
overflow=1;
}
byteCount++;
start_time = millis();
}
if ((millis() - start_time) > timeout_ms) { // если превышение времени в 4 ms
break;
}
}
return overflow?-1:byteCount;
}
int main(void) {
sei();
UART_init();
timerInit();
DDRD = 0xFF;
uint8_t buff[] = {0x48, 0x45, 0x4C, 0x4C, 0x4F, 0x21, 0x09};
//UART_send(buff, sizeof(buff));
//
//uint8_t receivedData[BUFFER_SIZE];
//UART_receive(receivedData,sizeof(receivedData));
//UART_send(receivedData, sizeof(receivedData));
while (1) {
//unsigned long currentTime = millis();
}
return 0;
}
// прерывание по завершению приема
ISR(USART_RX_vect) {
uint8_t data = UDR0; // читаем из регистра UDR0
if (!buffer_full(&usartRxBuffer)) {
write_buffer(&usartRxBuffer, data);// записываем символ в буфер приема
}
}
//перезаписать чтоб освободитть байт, из udr0

23
UART/timer.c Normal file
View File

@ -0,0 +1,23 @@
#include <avr/io.h>
#include <avr/interrupt.h>
static volatile unsigned long timerMillis = 0;
void timerInit() {
TCCR1B |= (1 << WGM12) | (1 << CS11) | (1 << CS10);
OCR1A = 249;
TIMSK1 |= (1 << OCIE1A);
sei();
}
unsigned long millis() {
unsigned long ms;
cli();
ms = timerMillis;
sei();
return ms;
}
ISR(TIMER1_COMPA_vect) {
timerMillis++;
}

7
UART/timer.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef TIMER_H
#define TIMER_H
void timerInit();
unsigned long millis();
#endif // TIMER_H

119
UART/uart.c Normal file
View File

@ -0,0 +1,119 @@
#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++; // увеличиваем счетчик принятых символов
}
}

11
UART/uart.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef UART_H
#define UART_H
void UARTInit(void);
void UARTSend(uint8_t data);
void USART_FlushTxBuf(void);
void USART_PutChar(unsigned char sym);
unsigned char GetChar(void);
void USART_SendStr(unsigned char * data);
#endif /* UART_H */

25
main.c
View File

@ -1,25 +0,0 @@
#include <stdint.h>
#include "config.h"
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "uart_hal.h"
int main(void)
{
//example
uint8_t data = 'A';
uart_init(9600,0);
uart_send_byte(data);
sei();
while (1)
{
if(uart_read_count() > 0){
data = uart_read();
uart_send_byte(data);
}
}
}

View File

@ -1,82 +0,0 @@
#include "uart_hal.h"
volatile static uint8_t rx_buffer[RX_BUFFER_SIZE] = {0};
volatile static uint16_t rx_count = 0;
volatile static uint8_t uart_tx_busy = 1;
// кольцевой буффер
ISR(USART_RX_vect){
volatile static uint16_t rx_write_pos = 0;
rx_buffer[rx_write_pos] = UDR0;
rx_count++;
rx_write_pos++;
if(rx_write_pos >= RX_BUFFER_SIZE){
rx_write_pos = 0;
}
}
ISR(USART_TX_vect){
uart_tx_busy = 1;
}
void uart_init(uint32_t baud,uint8_t high_speed){
uint8_t speed = 16;
if(high_speed != 0){
speed = 8;
UCSR0A |= 1 << U2X0;
}
baud = (F_CPU/(speed*baud)) - 1;
UBRR0H = (baud & 0x0F00) >> 8;
UBRR0L = (baud & 0x00FF);
UCSR0B |= (1 << TXEN0) | (1 << RXEN0) | (1 << TXCIE0) | (1 << RXCIE0);
}
void uart_send_byte(uint8_t c){
while(uart_tx_busy == 0);
uart_tx_busy = 0;
UDR0 = c;
}
void uart_send_array(uint8_t *c,uint16_t len){
for(uint16_t i = 0; i < len;i++){
uart_send_byte(c[i]);
}
}
void uart_send_string(uint8_t *c){
uint16_t i = 0;
do{
uart_send_byte(c[i]);
i++;
}while(c[i] != '\0');
uart_send_byte(c[i]);
}
uint16_t uart_read_count(void){
return rx_count;
}
uint8_t uart_read(void){
static uint16_t rx_read_pos = 0;
uint8_t data = 0;
data = rx_buffer[rx_read_pos];
rx_read_pos++;
rx_count--;
if(rx_read_pos >= RX_BUFFER_SIZE){
rx_read_pos = 0;
}
return data;
}

View File

@ -1,20 +0,0 @@
#ifndef UART_HAL_H_
#define UART_HAL_H_
#include <stdint.h>
#include "config.h"
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define RX_BUFFER_SIZE 128
void uart_init(uint32_t baud,uint8_t high_speed);
void uart_send_byte(uint8_t c);
void uart_send_array(uint8_t *c,uint16_t len);
void uart_send_string(uint8_t *c);
uint16_t uart_read_count(void);
uint8_t uart_read(void);
#endif /* UART_HAL_H_ */