Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.95/21: Рейтинг темы: голосов - 21, средняя оценка - 4.95
0 / 0 / 0
Регистрация: 11.03.2021
Сообщений: 5
1

Послать команду по UART c терминала на atmega16 (симуляция в Proteus)

12.03.2021, 15:55. Показов 4223. Ответов 8

Author24 — интернет-сервис помощи студентам
Здравствуйте! Уважаемые форумчане нужна ваша помощь!!! Хочу подключить датчик к ATmega16 по UART, симулирую все это на Proteus + терминал. ATmega16 посылает команду (например 77 77 77 77 77 ), терминал как-то отвечает (например 01 02 03 04 05 06 07 08 09 0А). Я хочу записать полученные с терминала данные и как-то обработать. Почитал в интернете про 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
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
78
79
80
81
82
83
84
#define F_CPU 1000000UL
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
 
 
char rx_buffer[20];
char RHAA[] = {0x77,0x77,0x77,0x77,0x77};
unsigned char cicl=0;
bool flag=0;
 
ISR(USART_RXC_vect) // прием данных
{   
    char data;
    data=UDR;
    rx_buffer[cicl]=data; // записываю принятые данные в массив
    cicl++;
    
    if (cicl>17) // если больше n байт обнуляю массив 
    {
        for(unsigned char k=0;k<20;k++)
        {
        rx_buffer[k]=0;
        cicl=0;
        }
    }
        if(data == 0x0A)   // для по этому байту МК отправляет массив обратно в терминал (для диагностики)
        flag=1;
 
} 
 
void UART_settings (unsigned char ubrr)
{   
    //  Устанавливаем скорость передачи 9600
    UBRRH = (unsigned char)(ubrr>>8);
    UBRRL = (unsigned char)(ubrr);
    
    //Удвоенная скорость передачи данных
    UCSRA |= (1<<U2X);
    
    //подключаем приемник и передатчик
    UCSRB |= (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
 
    //подключаем регистр USCRC вместо UBRRH, устанавливаем 2 стоп бита, устанавливаем формат данных 8 бит
    UCSRC |= (1<<URSEL)|(1<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);
 
    
}
 
void Transmit_arr(char *sendArr,char size_sendArr) // Отправляю массив по UART
{
    unsigned char z=0;
    while (z<size_sendArr)
    {   
        if (UCSRA & (1<<UDRE) && z < size_sendArr)
        {   
            UDR = sendArr[z];
            z++;
        }
    }
}
 
int main(void)
{   
    sei(); //включаю прерывания
 
    DDRB = 0xFF; //настраиваю порт B на выход
    PORTB = 0x00;
    
    UART_settings(12); // задаю скорость передачи данных 9600 при Fмк= 1МГц , U2X=1 
    
    Transmit_arr(RHAA,5); // Посылаем RHAA 
    
while(1)
{
    if(flag)
    {   
        PORTB=0xFF;
        Transmit_arr(rx_buffer,20);
        flag=0;
    }   
    _delay_ms(0.01);  // здесь что-то должно быть (типа задержка ) или данные в терминал не приходят вообще ????
}
}
Миниатюры
Послать команду по UART c терминала на atmega16 (симуляция в Proteus)   Послать команду по UART c терминала на atmega16 (симуляция в Proteus)   Послать команду по UART c терминала на atmega16 (симуляция в Proteus)  

0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.03.2021, 15:55
Ответы с готовыми решениями:

Atmega16 и симуляция USART в proteus
Отлаживаю программу в Proteus. Она должна вываливать в USORT строку с данными. Но вместо этого...

ATtiny2313 + UART + симуляция в Proteus
Приветствую. Прошу помочь с локализацией проблемы отладки проекта. Проект такой: управление...

ATmega16+UART+Proteus+LabView нужна помощь
Доброго времени суток. Приходит время дипломов. То что нельзя было сделать за целый семестр...

Симуляция в proteus
У меня есть программа, написанная на ассемблере, и я хочу проверить правильность ее работы, но с...

Симуляция логики в Proteus
Столкнулся со странной особеностью симуляторов схем (Proteus, EveryCircuit). Транзисторы, катушки,...

8
2105 / 1192 / 496
Регистрация: 11.10.2018
Сообщений: 6,000
12.03.2021, 18:27 2
Цитата Сообщение от Karamboza Посмотреть сообщение
C++
1
#define F_CPU 1000000UL
- так частота может и не задаться, для компилятора или для среды. Какая, кстати, среда?
Задачу непонятно объясняете, попробуйте еще раз. Максимально просто, что Вы хотите получить?
Начинающие не используют режим X2 - хоть бы так заработало.

Добавлено через 3 минуты
Также учитывайте, что для работы по UART нужен специфический кварц, например F = 11,0592 (МГц).

Добавлено через 9 минут
RXD микроконтроллера c TXD терминала надо соединить.

Добавлено через 4 минуты
Цитата Сообщение от Karamboza Посмотреть сообщение
2 стоп бита,
- 1 стоп-бит поставь, да и не парься.

Добавлено через 1 минуту
Цитата Сообщение от Karamboza Посмотреть сообщение
C
1
UCSRC |=
- нужно не добавлять к регистру, а сделать его заново.

Добавлено через 4 минуты
Цитата Сообщение от Karamboza Посмотреть сообщение
C
1
sei();  //включаю прерывания
- прерывания не там включаешь, они включаются между setup и первым действием. Здесь нужно
C
1
cli();
Добавлено через 3 минуты
Цитата Сообщение от Karamboza Посмотреть сообщение
C
1
{0x77,0x77,0x77,0x77,0x77};
- сделайте массив попроще, например
C
1
{0x01, 0x02, 0x03, 0x04, 0x05};
Добавлено через 1 час 38 минут
]
Цитата Сообщение от Karamboza Посмотреть сообщение
C
1
if(UCSRA & (1<<UDRE) && z < size_sendArr)
- тут бы скобки надо поставить
C
1
if((UCSRA & (1<<UDRE)) && (z < size_sendArr))
1
Тутошний я
2146 / 1201 / 225
Регистрация: 03.11.2009
Сообщений: 4,416
Записей в блоге: 2
12.03.2021, 22:03 3
Цитата Сообщение от FFPowerMan Посмотреть сообщение
Также учитывайте, что для работы по UART нужен специфический кварц, например F = 11,0592 (МГц).
желательно. с ним без ошибок передаёт.
но работает и с другими кварцами.
0
0 / 0 / 0
Регистрация: 11.03.2021
Сообщений: 5
12.03.2021, 22:12  [ТС] 4
Большое спасибо вам за помощь!!! Пока я пытался написать проще, все заработало. Неправильно задал настройки UART ! По вашему совету отключил X2. скорость 4800 8N1. У меня остался еще один вопрос, подскажите пожалуйста !!! (Вопрос во вложении) .Среда у меня atmel studio.


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
78
79
80
81
82
83
84
85
#define F_CPU 1000000UL
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
 
 
char rx_buffer[5];
char srav[] = {0x77, 0x04, 0x00, 0x04, 0x08};
char answer[] = {0x77, 0x0D, 0x00, 0x84, 0x00, 0x00, 0x02, 0x01, 0x10, 0x00, 0x51, 0x00, 0x00, 0x00, 0xF5}; 
unsigned char cicl=0;
char flag=0;
bool equal=0;
 
ISR(USART_RXC_vect) // прием данных
{   
    char data;
    data=UDR;
    rx_buffer[cicl]=data; // записываю принятые данные в массив
    cicl++;
    
        for(unsigned char k=0;k<5;k++)
        {
            if(rx_buffer[k]!=srav[k]) //  сравниваю полученные данные с {0x77, 0x04, 0x00, 0x04, 0x08}
            {   
            flag = 0;
            break;  
            }
            else
            flag = 1;       
        }
} 
 
 
void UART_settings (void)
{   
    //  Устанавливаем скорость передачи 4800
    UBRRH = 0b00000000;
    UBRRL = 0b00001100; //(UBRR = 12 U2X =0 f =1.MHz)
    //подключаем приемник и передатчик и прерывания по RXC 
    UCSRB = 0b10011000;
    //подключаем регистр USCRC вместо UBRRH, устанавливаем 1 стоп бит, устанавливаем формат данных 8 бит
    UCSRC = 0b10000110;
    
    
}
 
void Transmit_arr(char *sendArr,char size_sendArr) // Отправляю массив по UART
{
    unsigned char z=0;
    while (z<size_sendArr)
    {   
        if (UCSRA & (1<<UDRE) && z < size_sendArr)
        {   
            UDR = sendArr[z];
            z++;
        }
    }
}
 
int main(void)
{   
    sei(); //включаю прерывания
 
    DDRB = 0xFF; //настраиваю порт B на выход
    PORTB = 0x00;
    
    UART_settings(); // задаю скорость передачи данных 4800 8N1 при Fмк= 1МГц  
    
while(1)
{
    if(flag)        // если данные совпадают, отправляю answer[] и все обнуляю.
    {   
        PORTB=0xFF;
        Transmit_arr(answer,answer[1]+2);  
        
        flag=0;
        cicl=0;
        for(unsigned char t=0;t<5;t++)
        {
        rx_buffer[t]=0;
        }
    }
    _delay_ms(0.01);  // здесь что-то должно быть (типа задержка) ))) или данные в терминал не приходят вообще ??????
}
}
Миниатюры
Послать команду по UART c терминала на atmega16 (симуляция в Proteus)  
0
614 / 374 / 70
Регистрация: 21.09.2008
Сообщений: 1,280
13.03.2021, 06:55 5
Цитата Сообщение от FFPowerMan Посмотреть сообщение
Также учитывайте, что для работы по UART нужен специфический кварц, например F = 11,0592 (МГц).
Вовсе нет. Прекрасно работает и на 16 МГц. Просто при некоторых скоростях процент ошибок при передаче может гораздо выше и чаще будут сбои, что приведено в технической документации на МК. Даже кварцевый резонатор на 11,0592 МГц проиграет 8 МГц на скорости 250 кбит/с, допустив -7,8% ошибок против 0%.
1
Модератор
Эксперт по электронике
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,524
13.03.2021, 08:24 6
Цитата Сообщение от Karamboza Посмотреть сообщение
У меня остался еще один вопрос, подскажите пожалуйста !!! (Вопрос во вложении) .
Создайте новую тему
правила п 5.16
Запрещено создавать темы с множеством вопросов во всех разделах, кроме разделов платных услуг. Один вопрос - одна тема.
и не забывайте про п 5.18
Запрещено размещать задания и решения в виде картинок (кроме формул и блок-схем) и других файлов с их текстом.
1
2105 / 1192 / 496
Регистрация: 11.10.2018
Сообщений: 6,000
13.03.2021, 08:58 7
C
1
_delay_ms();
- число целое должно быть, а не дробное, если надо в микросекундах, то так
C
1
_delay_us(10);
0
0 / 0 / 0
Регистрация: 11.03.2021
Сообщений: 5
13.03.2021, 11:21  [ТС] 8
Всем большое спасибо!!!
0
30 / 25 / 8
Регистрация: 26.06.2020
Сообщений: 105
14.03.2021, 09:12 9
Переменные "cicl" и "flag" объявите с квалификатором "volatile".
_delay_ms() перед применения нужно учесть следующее:
"Макрос F_CPU должен быть определен как константа, определяющая тактовую частоту процессора (в герцах)."
"Максимально возможная задержка составляет 262,14 мс / F_CPU в МГц."
Не будет лишним посмотреть "AVR Libc Home Page"
https://www.nongnu.org/avr-lib... delay.html
0
14.03.2021, 09:12
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.03.2021, 09:12
Помогаю со студенческими работами здесь

Симуляция Attiny 25/45/85 в PROTEUS "РЕШЕНО"
Коллеги, вот код, который просто обязан выдавать меиндр c частотой 62.5 Гц на PB0 Attiny 25/45/85...

Proteus. Симуляция и управление двигателем на МК Atmega
Добрый день !!! Нужно собрать схему в PROTEUS для управления трехфазным двигателем (переменного...

PIC16F84A. Симуляция в Proteus, не горят светодиоды на модели
Здравствуйте! Пишу первую программу на С для PIC, но при моделировании на Proteus 7 не работает...

AtMega16. ШИМ на Т/С1. Proteus.
Необходимо сделать ШИМ на Т/С1 для изменения среднего напряжения на лампочке. Вот код программы: ...

Проблема с АЦП в PROTEUS на AtMega16
Здравствуйте. Такой вопрос: делал программу под AtMiko8, всё работало и в PROTEUS’e и в железе....


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru