Заголовок сообщения: Re: Автоматический выход из ждущего режима uart_receive();
Добавлено: Чт авг 11, 2022 16:15:46
Родился
Зарегистрирован: Чт мар 18, 2021 16:47:20 Сообщений: 11
Рейтинг сообщения:0
AlexandrRa писал(а):
так правильней.
Да хоть так, главная тут задача, отвязаться от c = uart_receive(); на время выполнения условия с циклом for, вот никак не смог отвязать разве что часто нажатием какой нибудь клавиши
Последний раз редактировалось Sulik Чт авг 11, 2022 21:14:51, всего редактировалось 3 раз(а).
void uart_handler_RX(void) { if (y < Size_data) // если весь пакет не принят { data[y] = UDR0; // запись следующего байта data[y] y++; // счётчик байт return; } y=0; }
И добавь прерывание по приёму
Добавлено after 2 minutes 18 seconds:
Код:
uint8_t flag = 0; uint8_t Size_data = 12; // например передаём 12 байт
ISR(PCINT0_vect){ if(PINB & (1 << PB0)) flag = 1; // Разрешение передачи данных }
int main(){ UART_init(); interrupt_init(); sei();
while(1){ if (flag){ for (y = 0; y < Size_data ; y++){ uart_transmit(data[y]); } flag = 0; // Данные переданы } }
и с на фиг ненужно стало
Добавлено after 3 minutes 10 seconds: Что за МК хоть?
Последний раз редактировалось AlexandrRa Чт авг 11, 2022 16:26:00, всего редактировалось 1 раз.
Заголовок сообщения: Re: Автоматический выход из ждущего режима uart_receive();
Добавлено: Чт авг 11, 2022 16:29:34
Родился
Зарегистрирован: Чт мар 18, 2021 16:47:20 Сообщений: 11
Рейтинг сообщения:0
AlexandrRa писал(а):
И не закрывай посылку значением данных в передаче. Отучайся от этого.
Иногда очень необходимо бывает закрыться именно "\0", есть такие моменты в коде где именно так необходимо учитывая, что количество символов в одном массиве данных могут быть разной длины, то увеличится эта длина то уменьшится.
Добавлено after 2 minutes 34 seconds:
AlexandrRa писал(а):
Что за МК хоть?
Atmega 328P
Добавлено after 2 minutes 59 seconds:
AlexandrRa писал(а):
И добавь прерывание по приёму
Это у меня добавлено, просто код я привел как пример
Последний раз редактировалось Sulik Чт авг 11, 2022 21:07:56, всего редактировалось 1 раз.
Передавай в первом байте размер пакета. Аналогично и при приёме делай. Избежишь проблем. Представь что у тебя в пакете байт по середине указывает на открытие или закрытия 8 дверей. В какой то момент можно передать не всю посылку, а лишь часть её.
Заголовок сообщения: Re: Автоматический выход из ждущего режима uart_receive();
Добавлено: Чт авг 11, 2022 16:42:22
Родился
Зарегистрирован: Чт мар 18, 2021 16:47:20 Сообщений: 11
Рейтинг сообщения:0
AlexandrRa писал(а):
и с на фиг ненужно стало
Он нужен в другом коде, просто приведенном мною примере он не нужен, но он нужен это для приема неких команд и отправка этих команд в нужное условие с данными
Добавлено after 6 minutes 32 seconds: Задача тут очень понятная, например консоль putty будет постоянно открыть по UART с МК, ждет ввода команд с клавы, но в то же время как только придет нужное прерывание отвязаться от uart_receive(); и начал обрабатывать другое условие с циклом с выводом данных на консоль и после обработки вернулась в тот же режим uart_receive();
Последний раз редактировалось Sulik Чт авг 11, 2022 21:07:09, всего редактировалось 1 раз.
Sulik, смотри, в каком сообщении ты жмешь кнопку "цитата". а то получается, что всё тобой процитированное, написано тобой, а не тем человеком, откуда ты взял цитату.
_________________ Мудрость приходит вместе с импотенцией... Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Задача тут очень понятная, например консоль putty будет постоянно открыть по UART с МК, ждет ввода команд с клавы, но в то же время как только придет нужное прерывание отвязаться от uart_receive(); и начал обрабатывать другое условие с циклом с выводом данных на консоль и после обработки вернулась в тот же режим uart_receive();
Нафига сидеть и ждать приёма? За этим прекрасно сможет следить флаг прерывания. А нужное прерывание смотри по флагу или данным в основном цикле. В этом случае ты всегда будешь отвязан от uart_receive(). И я бы лучше уходил в сон во время ожидания приёма, вместо того чтобы жрать энергию.
Не советую так делать, есть возможность прочитать не тот байт или потерять вообще всю посылку. Т. к. чтение данных будет только один раз за цикл. А если данные приходят несколько раз за цикл и неизвестно когда по времени? Очень легко пропустить посылку.
Расскажите это тем кто написал и тем кто применяет software serial.
Если бездумно сидеть в цикле, то всегда существует вероятность потерять данные, даже если применяются прерывания.
Приведенный код будет работать, но если есть аппаратная поддержка, то не применять аппаратные прерывания нет смысла.
Вот пример, смотритеСпойлерреализован кольцевой буфер приема поддержка по символьных или пакетных команд, заканчивающих символом ENTER поддержка примитивного редактирования при помощи backspace
код написан под компилятор CVAVR, то есть под компилятор winavr (interrupt [USART_RXC] void usart_rx_isr(void)) надо поменять на ISR(USART_RX_vect) и #asm("sei") на sei();
по умолчанию строка вида '0' - turn off LED располагается в RAM ее надо перенести во FLASH
Код:
#include <mega328p.h>
// Standard Input/Output functions #include <stdio.h>
void help(void) // HELP { SEND("\r\n"); SEND("\t'0' - turn off LED\r\n"); SEND("\t'1' - turn on LED\r\n"); SEND("\t'LED ON' - turn on LED\r\n"); SEND("\t'LRD OFF' - turn off LED\r\n"); SEND("\t'TOGGLE' - turn toggle LED\r\n"); SEND("\t'COUNT=N' - set all value by N (decimal):\r\n"); SEND("\tSTAT - shows which mode the automatic/off mode is in\r\n");
SEND("\tHELP - help\r\n"); SEND("\r\n"); }
// print 32bit unsigned int void printu(unsigned long val){ char bufa[11]; char bufb[10]; int i; int l = 0, bpos = 0; if(!val){ bufa[0] = '0'; l = 1; }else{ while(val){ bufb[l++] = val % 10 + '0'; val /= 10; } bpos += l; for(i = 0; i < l; ++i){ bufa[--bpos] = bufb[i]; } } bufa[l + bpos] = 0; SEND(bufa); }
// если BkSp - сдвигаем назад len_buff = strlen((void*)buff)-1; // определяем длину if((buff[len_buff] == 0x08)|| (buff[len_buff] == 0x7f)){ // стираем символ // но не левее начала буфера if(len_buff > 0) buff[len_buff-1]=0; else buff[len_buff]=0; }
// если Enter - ввод закончен if(((buff[len_buff] == '\n') || (buff[len_buff] == '\r'))) { flag=1; buff[len_buff]='\0'; // стираем символ Enter, заменяем концом строки \0 } }
// поиск обработчика if(flag) {
len_buff = strlen((void*)buff); // определяем длину команды // если не использовать по символьные команды, то len_buff не нужен
if(respcmp((void*)buff, "1") && len_buff == strlen("1")) { // это просто пример PORTB |= (1<<(0)); }
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 13
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения