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

Atmega2560, конфликт UART и задержки (delay)

27.11.2017, 16:31. Показов 1015. Ответов 1
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
В общем, есть STK600, нужно реализовать таймер обратного отсчета: по UART принимается строка вида HH:MM:SS, дальше идет обработка, валидация, отсчет (отправка в терминал по UART строки вида HH:MM:SS). Проблема в том, что, раз уж это таймер, то нужно отправлять эту строку раз в секунду, но использование _delay_ms() приводит к тому, что в терминал отправляется какой-то мусор, после чего цикл обрывается. Помогите разобраться, может, кто сталкивался с таким
Вот то, что написал:
Кликните здесь для просмотра всего текста
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
char buf_in[8];
char buf_out[8];
char hh[2];
char mm[2];
char ss[2];
int index_in = 0;
int index_out = 0;
int seconds, hours, minutes, s_max, max_size;
volatile bool read_finished = false;
volatile bool write_started = false;
bool read_started = false;
 
 
void SendByte(char* byte)
{
    while(*byte)
    {
        while (!(UCSR0A & (1 << UDRE0))) {}
        UDR0 = *(byte++);
    }
}
void SendData(char* data, int len)
{
    if (write_started == true)
    {
        int ind = 0;
        while(ind < len)
        {
            while (!(UCSR0A & (1 << UDRE0))) {}
            UDR0 = data[ind];
            ind++;
        }
        if (ind == len)
        {
            SendByte("!\r\n");
        }
    }
}
 
void Parse(char* _string)
{
    memcpy(hh, _string, sizeof(hh));
    memcpy(mm, &_string[3], sizeof(mm));
    memcpy(ss, &_string[6], sizeof(ss));
    
    hours = (int) (hh[0] - '0') * 10 + (int) (hh[1] - '0');
    minutes = (int) (mm[0] - '0') * 10 + (int) (mm[1] - '0');
    seconds = (int) (ss[0] - '0') * 10 + (int) (ss[1] - '0');
}
 
void BuildString(int h, int m, int s)
{
    hh[0] = (char) (h / 10) + '0';
    hh[1] = (char) (h % 10) + '0';
    mm[0] = (char) (m / 10) + '0';
    mm[1] = (char) (m % 10) + '0';
    ss[0] = (char) (s / 10) + '0';
    ss[1] = (char) (s % 10) + '0';
    
    memcpy(buf_out, hh, sizeof(hh));
    memcpy(&buf_out[3], mm, sizeof(mm));
    memcpy(&buf_out[6], ss, sizeof(ss));
}
ISR(USORT0_RX_vect)
{
    if (read_finished == false)
    {
        buf_in[index_in] = UDR0;
        index_in++;
        if (index_in == 8)
        {
            index_in = 0;
            SendByte(buf_in);
            SendByte("\r\n");
            read_finished = true;
        }
    }
}
bool Validate()
{
    bool res = false;
    if ((seconds >=0) && (seconds < 60))
    {
        if ((minutes >= 0) && (minutes < 60))
        {
            if ((hours >=0) && (hours < 100))
            {
                res = true;
            }
        }
    }
    return res;
}
int main(void)
{
    UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0) | (1 << TXCIE0) | (1 << UDRIE0);
    UCSR0C = (0 << UMSEL00) | (0 << UCSZ02) | (1 << UCSZ01) | (1 << UCSZ00);
    UBRR0 = 209;
    sei();
    buf_out[2] = ':';
    buf_out[5] = ':';
    while (1)
    {
        while (read_finished == true)
        {
            memcpy(buf_out, buf_in, sizeof(buf_in));
            Parse(buf_in);
            write_started = true;
            SendData(buf_in, 8);
            SendData(hh, 2);
            SendData(mm, 2);
            SendData(ss, 2);
            if (Validate())
            {
                for (int h = hours; h >= 0; h--)
                {
                    for (int m = minutes; m >= 0; m--)
                    {
                        if (m == minutes)
                            s_max = seconds;
                        else
                            s_max = 59;
                        for (int s = s_max; s >= 0; s--)
                        {
                            int tmp = 0;
                            BuildString(h, m, s);
                            write_started = false;
                            _delay_ms(250);
                            write_started = true;
                            SendData(buf_out, 8);
                            //_delay_ms(1000); - если раскомментировать, то отправляется мусор, и цикл прерывается
                        }
                    }
                }
            }
            read_finished = false;
        }
    }
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.11.2017, 16:31
Ответы с готовыми решениями:

Atmega2560. Обработчик прерывания UART
Добрый день. Помогите исправить код. Проблема в том, что при поступлении байта на UART программа...

Время задержки delay
Доброго времени суток. столкнулся с AnyLogic University 6.9.0. задача: Есть 3 блока Sourсе. из них...

Разное время задержки Delay для разных заявок
Здравствуйте.Подскажите пожалуйста,как выполнить такое: с одного источника выходят 2 наименования...

Алгоритм изменение Бегунком Время задержки блока Delay ?
Каким образом, и можно ли, получить доступ по ходу экперимента, (что бы изменять) к Время...

Создание задержки Task.Delay(...) более чем на Int32.MaxValue миллисекунд
Задался вопросом, можно ли Task.Delay() дать число, большее, чем длина int32? То есть, можно ли...

1
1624 / 806 / 146
Регистрация: 13.06.2015
Сообщений: 3,266
27.11.2017, 22:17 2
iks5, не делают задержку через delay в проектах сложнее, чем моргание одним светодиодом. Используйте прерывание по таймеру.
0
27.11.2017, 22:17
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.11.2017, 22:17
Помогаю со студенческими работами здесь

Нежданные задержки между посылками UART в Debian.
Плата Olinuxino с процессором OttWinner A20, дистрибутив Debian. посылаю пакеты длиной от 4 до 30...

Конфигурация UART и просмотр файла, в который приходят данные с UART
Уважаемые коллеги! Подскажите, пожалуйста, как будет оптимальнее прочитать (скорее залогировать...

Сообщения для 2 UART выводятся в 1 UART, STM32F103C8T6
Почему может неправильно работать uart? Подключил 1 uart к пк через usb/uart переходник, а второй к...

Два TX UART на один RX. Мультиплексирование UART.
Привет, сообщество. Возник небольшой затык. Есть необходимость при одном UART на Atmego32 подавать...

atmega2560 USART
Пытаюсь отправить данные в терминал, Настройки терминала BOUDRATE=19200; DATABITS=8;...


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

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