uart modified
This commit is contained in:
parent
d3b39dbc9f
commit
0a9eb215db
36
UART/circular_buf.c
Normal file
36
UART/circular_buf.c
Normal 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
18
UART/circular_buf.h
Normal 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
123
UART/main.c
Normal 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
23
UART/timer.c
Normal 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
7
UART/timer.h
Normal 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
119
UART/uart.c
Normal 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
11
UART/uart.h
Normal 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
25
main.c
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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_ */
|
Loading…
Reference in New Issue
Block a user