Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.92/48: Рейтинг темы: голосов - 48, средняя оценка - 4.92
flatgad
geJI<|>eP
188 / 187 / 19
Регистрация: 22.07.2010
Сообщений: 734
1

Работа с UART (ATMega328)

06.05.2015, 15:08. Просмотров 9604. Ответов 13

Всем привет. Сижу мучаю атмегу и понять не могу что не так. Мне надо сделать uart c ехом. Но это для меня сложно решил разбить на части задачу. И первая задача состоит в правильной отправке данных на uart. Из даташита взял такую вот такой код

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#define F_CPU 16000000L
#include <avr/io.h>
#include <util/delay.h>
 
#define FOSC 1843200 // Clock Speed
#define BAUD 19200
#define MYUBRR FOSC/16/BAUD-1
 
 
void USORT_Init(unsigned int ubrr){
    UBRR0H = (unsigned char)(ubrr>>8);
    UBRR0L = (unsigned char)ubrr;
    /*Enable receiver and transmitter */
    UCSR0B = (1<<RXEN0)|(1<<TXEN0);
    /* Set frame format: 8data, 2stop*/
    UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}
 
void USORT_Transmit( unsigned char data )
{
    /* Wait for empty transmit buffer */
    while ( !( UCSR0A & (1<<UDRE0)) );
    /* Put data into buffer, sends the data */
    UDR0 = data;
}
 
void main( void ){
    USORT_Init(MYUBRR);
    while(1){
        USORT_Transmit(0x09);
        _delay_ms(50);  
    }
}
по идеи в программе которая слушает должно быть число 9 но у меня в итоге получается C6. я думал что может со скоростями напутал но вроде по дпташиту все ок. Подскажите где может быть проблема?? Заранее спасибо.
0
Лучшие ответы (1)
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.05.2015, 15:08
Ответы с готовыми решениями:

UART (ATMega328)
Добрый день всем. Я не могу добиться нормальной работы UART Atmega 328p. (Для Atmega8 разобрался и...

Работа с FT232 UART
Такое вот дело, уж долгое время неполучается общение (FT232)UART с (MCU)UART. Думал проблема в...

Работа с UART в МК ATMega8
Не хочет работать передача данных. Подключаю к ножкам PD0 и PD1 через USB/UART TTL конвертор...

Работа UART по прерыванию
Доброго времени суток, уважаемые форумчане! Я делаю систему контроля на Atmega16A-AU, котрая...

Работа с UART ATMega8
к примеру надо отправить число 21367 в ком порт с атмеги8 чтобы потом на компе программой считать....

13
pyzhman
1161 / 516 / 76
Регистрация: 15.05.2012
Сообщений: 2,956
06.05.2015, 15:13 2
Лучший ответ Сообщение было отмечено flatgad как решение

Решение

Цитата Сообщение от flatgad Посмотреть сообщение
#define F_CPU 16000000L
...
#define FOSC 1843200 // Clock Speed
Точно ок?
1
flatgad
geJI<|>eP
188 / 187 / 19
Регистрация: 22.07.2010
Сообщений: 734
06.05.2015, 15:46  [ТС] 3
как я понял то F_CPU надо для delay функции а FOSC для установки скорости у Atmeg-и

Добавлено через 18 минут
Все разобрался с помощью поста . Вроде передает нормально.
0
flatgad
geJI<|>eP
188 / 187 / 19
Регистрация: 22.07.2010
Сообщений: 734
15.05.2015, 17:35  [ТС] 4
Вопрос появился ещё один принимаю байты и если есть байт конца последовательности присутствует "FF" я отправляю эхо с теме же данными но проблема стала в неожиданном месте. При передачи набора байт где есть 0 я получаю не полный ответ эха пример :

Отправляю 04 01 FF - Принимаю 04 01 FF

Отправляю 04 01 00 FF - Принимаю эхо 04 01

Как с нулем быть подскажите ?

Вот полный код :
Кликните здесь для просмотра всего текста

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
 
#define FOSC 8000000UL // Clock Speed
#define BAUD 4800L
#define MYUBRR FOSC/16/BAUD-1
 
#define BUFFER_UART_SIZE 32
uint8_t Nbyte=0;
static uint8_t buff_uart[BUFFER_UART_SIZE]; 
 
 
void USORT_Init(unsigned int ubrr){
    UBRR0H = (unsigned char)(ubrr>>8);
    UBRR0L = (unsigned char)ubrr;
    /*Enable receiver and transmitter */
    UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0)|(1<<TXCIE0);
    /* Set frame format: 8data, 2stop*/
    UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}
 
void USORT_Transmit( char data )
{
    /* Wait for empty transmit buffer */
    while ( !( UCSR0A & (1<<UDRE0)) );
    /* Put data into buffer, sends the data */
    UDR0 = data;
}
 
void USORT_Transim_String(char * data){
    unsigned char d;
    while(*data){
        d = *data++;
        USORT_Transmit(d);
    }
}
 
char USORT_Receive( void )
{
    /* Wait for data to be received */
    while ( !(UCSR0A & (1<<RXC0)) );
    /* Get and return received data from buffer */
    return UDR0;
}
 
void ClearBuffUart(void){
    for(int i=0;i<BUFFER_UART_SIZE;i++){
        buff_uart[i]=0;
    }   
}
 
ISR(USORT_RX_vect)
{
    unsigned char b;
    b = UDR0;
    buff_uart[Nbyte] = b;
    Nbyte++;
    if (b == (int16_t)0xFF){
        USORT_Transim_String(buff_uart);
        Nbyte = 0;
        ClearBuffUart();
    }   
    if (Nbyte>=BUFFER_UART_SIZE){
        USORT_Transim_String(BUFFER_UART_SIZE);
        Nbyte = 0;
        ClearBuffUart();
    } 
}
 
void main( void ){
    USORT_Init(MYUBRR);
    sei();
    while(1){
    }
}
0
15.05.2015, 17:35
Voland_
1734 / 1068 / 106
Регистрация: 04.01.2010
Сообщений: 3,652
16.05.2015, 19:05 5
опишите, как работает данная функция?:
C
1
2
3
4
5
6
7
void USORT_Transim_String(char * data){
    unsigned char d;
    while(*data){
        d = *data++;
        USORT_Transmit(d);
    }
}
в каждой строчке комментарий
1
Витальич
1277 / 1183 / 175
Регистрация: 02.12.2013
Сообщений: 4,886
16.05.2015, 20:28 6
Цитата Сообщение от flatgad Посмотреть сообщение
Как с нулем быть подскажите ?
а уважаем Voland_ таки прав, проблема в указанной функции
1
flatgad
geJI<|>eP
188 / 187 / 19
Регистрация: 22.07.2010
Сообщений: 734
16.05.2015, 21:07  [ТС] 7
C
1
2
3
4
5
6
7
void USORT_Transim_String(char * data){
    unsigned char d;
    while(*data){// пока есть указатель
        d = *data++;//указатель увеличиваем на 1
        USORT_Transmit(d);//отправляем байт 
    }
}
вроде правильно. Если я ошибаюсь то сильно не критикуйте я тока учусь в С.
0
Витальич
1277 / 1183 / 175
Регистрация: 02.12.2013
Сообщений: 4,886
16.05.2015, 21:11 8
Цитата Сообщение от flatgad Посмотреть сообщение
while(*data){// пока есть указатель
указатель раз именован значит когда ....... цикл while ......
1
flatgad
geJI<|>eP
188 / 187 / 19
Регистрация: 22.07.2010
Сообщений: 734
18.05.2015, 14:46  [ТС] 9
Вроде победил немного доработав отправку байт. Если кому интересно :

Кликните здесь для просмотра всего текста

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
 
#define FOSC 8000000UL // Clock Speed
#define BAUD 4800L
#define MYUBRR FOSC/16/BAUD-1
 
#define BUFFER_UART_SIZE 16
uint8_t Nbyte=0;
static uint8_t buff_uart[BUFFER_UART_SIZE]; 
uint8_t buffer_index = 0;
//Очистка буфера
void ClearBuffUart(void){
    for(int i=0;i<BUFFER_UART_SIZE;i++){
        buff_uart[i]=0;
    }   
    Nbyte = 0;
}
//Инициализация уарт
void USORT_Init(unsigned int ubrr){
    UBRR0H = (unsigned char)(ubrr>>8);
    UBRR0L = (unsigned char)ubrr;
    UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0)|(1<<TXCIE0);
    UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}
//Передача масива
void USORT_Transmit(void)
{
    buffer_index=0;     
    UDR0 = buff_uart[0];    
    UCSR0B|=(1<<UDRIE0);
}
//Прерывание отправки данных
ISR (USORT_UDRE_vect){
    buffer_index++;
    if (buffer_index==Nbyte){
        UCSR0B &=~(1<<UDRIE0);
        ClearBuffUart();
    }       
    else{
        UDR0 = buff_uart[buffer_index];
    }   
}
//Прием данных
char USORT_Receive( void )
{
    while ( !(UCSR0A & (1<<RXC0)) );
    return UDR0;
}
//Прерывание по приему данных
ISR(USORT_RX_vect)
{
    unsigned char b;
    b = UDR0;
    buff_uart[Nbyte] = b;
    Nbyte++;
    if (b == (uint8_t)0xFF){
       USORT_Transmit();
    }
    if (Nbyte == BUFFER_UART_SIZE){
        USORT_Transmit();   
    }   
}
 
void main( void ){
    USORT_Init(MYUBRR);
    sei();
    while(1){
    }
}
1
Voland_
1734 / 1068 / 106
Регистрация: 04.01.2010
Сообщений: 3,652
19.05.2015, 09:40 10
...при асинхронном приеме/передаче и еще в одном случае будет глючить.
1
Витальич
1277 / 1183 / 175
Регистрация: 02.12.2013
Сообщений: 4,886
19.05.2015, 09:41 11
Цитата Сообщение от Voland_ Посмотреть сообщение
при асинхронном приеме/передаче
согласен, а еще какой интересно?
1
flatgad
geJI<|>eP
188 / 187 / 19
Регистрация: 22.07.2010
Сообщений: 734
19.05.2015, 10:32  [ТС] 12
Voland_ "и еще в одном случае будет глючить." а в каком случае будет глючить ? А то мне не охота через пол года отлавливать баги

Меня пока смущает прием байт :
C
1
2
3
4
5
char USORT_Receive( void )
{
    while ( !(UCSR0A & (1<<RXC0)) );
    return UDR0;
}
может есть другая реализация буду очень благодарен за разъяснения . А то передача вроде отрабатывает нормально. А вот с приемом получается такая штука, если данные отправить то основная работа контроллера на время приема подвисает . Для меня это не критично, но если можно решить с прерываниями более красиво рад буду увидеть. Спасибо.
0
Voland_
1734 / 1068 / 106
Регистрация: 04.01.2010
Сообщений: 3,652
19.05.2015, 11:28 13
flatgad, с одним озвученным случаем Витальич согласен, хотя, он может никогда и не произойти, а вот со вторым:
- просимулируйте отправку такого пакета: "I have 2 bugs.."+0xFF То есть всего 16 байт. Последний байт 0xFF
1
flatgad
geJI<|>eP
188 / 187 / 19
Регистрация: 22.07.2010
Сообщений: 734
19.05.2015, 13:38  [ТС] 14
понял сенкс за подсказку. Но это я поборю тем что есть фиксированные команды в начале строки если после команды в 15 байт не попало FF тогда возврат команды эррор, но это уже потом. Я просто хотел разобраться с передачей и приемом байт по прерываниям.
0
19.05.2015, 13:38
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.05.2015, 13:38

Работа с UART (Си, ATtiny 2313)
Дорогие формчане и знатаки по микроконтролёрам я Новичок в этом деле. У меня есть вопрос, есть...

работа с UART (IDE WinAVR)
предыстория: есть мега88 с кварцем 20МГц (уж какой нашёл), также есть код, сгенерённый CvAVR для...

MSP430F5435A. Работа с UART
написал такую програмку для отправки по UART... эффекта нету, со стороны схемы всё норм, в чём...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.