Форум РадиоКот https://radiokot.ru/forum/ |
|
Передача строки по UART https://radiokot.ru/forum/viewtopic.php?f=57&t=140381 |
Страница 1 из 6 |
Автор: | LEX38RUS [ Вс янв 08, 2017 12:16:21 ] |
Заголовок сообщения: | Передача строки по UART |
Добрый вечер. Программирование на МК начал только изучать. Задался вопрос передать с программы на ПК строку в МК, и в условии на МК уже сравнивать и выполнять те или иные действия. Как передать один байт с ПК на МК я разобрался, а вот как быть со строкой? Если там скажем в команде по пять символов? В принципе алгоритм понятен, но реализовать что то пока не могу. Пишу на Atmel Studio 7 Может кто чем поможет? Или на примере покажет? |
Автор: | Аlex [ Вс янв 08, 2017 12:42:09 ] |
Заголовок сообщения: | Re: Передача строки по UART |
LEX38RUS писал(а): Как передать один байт с ПК на МК я разобрался, а вот как быть со строкой? Дак строка - это n-ное кол-во байтов. Если один байт можете передать, почему не можете несколько ? ![]() Если честно, не понятно, что Вам непонятно. Поподробнее... И с кусками кода... |
Автор: | LEX38RUS [ Вс янв 08, 2017 12:43:59 ] |
Заголовок сообщения: | Re: Передача строки по UART |
Вопрос в том как их принять и сложить в строку |
Автор: | Аlex [ Вс янв 08, 2017 12:46:45 ] |
Заголовок сообщения: | Re: Передача строки по UART |
Заводим массив и переменную, которая будет индексом в массиве (порядковый номер байта) и по-одному байтику, инкрементируя индекс, принимаем. |
Автор: | LEX38RUS [ Вс янв 08, 2017 13:37:18 ] |
Заголовок сообщения: | Re: Передача строки по UART |
Еще нет столько опыта в написание такого рода код. Может кто поможет в реализации? |
Автор: | Аlex [ Вс янв 08, 2017 13:48:34 ] |
Заголовок сообщения: | Re: Передача строки по UART |
Чтобы Вам помочь, нужно знать чем конкретно. Для начала, покажите что у Вас есть на данный момент. |
Автор: | LEX38RUS [ Вс янв 08, 2017 14:09:40 ] |
Заголовок сообщения: | Re: Передача строки по UART |
Код: #include <avr/io.h> #define F_CPU 8000000UL //8MHz #include <util/delay.h> #include <avr/interrupt.h> uint8_t receive = 0; uint8_t rx_data = 0; volatile uint8_t rx_flag = 0; void UARTInit(void) { UBRRH = 0; UBRRL = 51; UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE); UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); } //void UARTSend(uint8_t data) { // while(!(UCSRA & (1<<UDRE))); // UDR = data; //} unsigned char UARTGet() { while(!rx_flag); rx_flag = 0; return rx_data; } int main(void) { DDRC = 0b00000001; sei(); UARTInit(); while(1) { receive = UARTGet(); if(receive == 0b00110001) { PORTC = 0b00000001; } if(receive == 0b00110010) { PORTC = 0b00000000; } } } ISR(USART_RXC_vect) { rx_data = UDR; rx_flag = 1; } Код слизан. Но принцип работы я понимаю кода. Ну и соответственно проверка, если пришел символ 1 то зажигаем диод если 2 то гасим. С этим все понятно и можно работать так в принципе, но охота до ума довести и сделать как отправку команд, допустим с ПК отправляю On и диод зажигаем, отправляю Off диод гасим. Вот и не могу докубатурить как организовать так чтоб принял байты, закончил прием, сложил их и можно было сравнить потом со строкой скажем так if(buffer == "On"{зажигаем диод} Вообщем с передачей и проверкой по одному байту проблем нет, а вот принять строку и проверить ее в условии проблема есть. За ранее благодарю. |
Автор: | Аlex [ Вс янв 08, 2017 16:00:20 ] |
Заголовок сообщения: | Re: Передача строки по UART |
Вот у Вас обработчик прерываний по приёму байта : Код: ISR(USART_RXC_vect) { В нём и заполняйте массив. А окончание приёма строки будет по нулевому байту.rx_data = UDR; rx_flag = 1; } Сначала добейтесь полноценного приёма строки, а парсинг - дело второстепенное, займётесь им потом. |
Автор: | LEX38RUS [ Пн янв 09, 2017 02:26:03 ] |
Заголовок сообщения: | Re: Передача строки по UART |
Допустим записал я в масив байты. Кпк мне далее этот масив сравнить с текстом? Через sprintf? К примеру имеем массив buffer_byt и его нужно сравнить с текстом скажем "ON" |
Автор: | tux [ Пн янв 09, 2017 04:32:33 ] |
Заголовок сообщения: | Re: Передача строки по UART |
Напрямую работать со строками в микроконтроллере нельзя. По крайней мере на С и асм. Строка это в любом случае массив, наполненный символами. Если так хочется писать on и off, то я бы сделал так. В цикле for читаем строку, допустим до нулевого символа и затем сравниваем с эталонными значениями других массивов (на самом деле я бы даже взял второй элемент массива и сравнил его с символом 'f' или 'n', это если не использовать защит от неправильно введенных символов). И в зависимости от полученного значения устанавливать флаг, от которого и будет зависеть дальнейший алгоритм действий. Могу в чем то ошибаться, так как сам далеко не большой специалист в программировании. |
Автор: | LEX38RUS [ Пн янв 09, 2017 06:14:25 ] |
Заголовок сообщения: | Re: Передача строки по UART |
В планах было сделать так, что если отправлена команда с ПК и содержит первый символ # то начинаем писать последующие принятые байты в массив и по принятию скажем последнего какого нибудь символа заканчиваем писать и принимать данные. Подобный пример находил в инете. Но не то. Для меня остаётся не понятным как мне сравнить данные которые записаны в массиве с другой строкой. |
Автор: | tux [ Пн янв 09, 2017 06:19:01 ] |
Заголовок сообщения: | Re: Передача строки по UART |
LEX38RUS писал(а): Но не то. Для меня остаётся не понятным как мне сравнить данные которые записаны в массиве с другой строкой. Другая строка - это тоже массив. То есть побайтово и сравниваем элементы каждого массива |
Автор: | afz [ Пн янв 09, 2017 07:45:59 ] |
Заголовок сообщения: | Re: Передача строки по UART |
Аlex писал(а): В нём и заполняйте массив. А окончание приёма строки будет по нулевому байту. Только не по нулю. Если набор идет с терминала, признаком окончания строки, обычно, служит символ <CR> (0x0D). А еще нужно решить вопрос с эхом - правильной реализацией будет пользовать терминал в режиме "без эха", а эхо делать самому, передавая каждый полученный символ назад. Получив <CR>, нужно занести в буфер строки нулевой байт, как признак конца этой строки, а "эхом" вернуть символы <CR>,<LF> (0x0D, 0x0A), после чего отметить основной программе, что строка получена. Ну, и не забыть, получая каждый байт, контролировать буфер строки на переполнение.
|
Автор: | tux [ Пн янв 09, 2017 07:58:29 ] |
Заголовок сообщения: | Re: Передача строки по UART |
afz писал(а): Аlex писал(а): В нём и заполняйте массив. А окончание приёма строки будет по нулевому байту. Только не по нулю. Если набор идет с терминала, признаком окончания строки, обычно, служит символ <CR> (0x0D). А еще нужно решить вопрос с эхом - правильной реализацией будет пользовать терминал в режиме "без эха", а эхо делать самому, передавая каждый полученный символ назад. Получив <CR>, нужно занести в буфер строки нулевой байт, как признак конца этой строки, а "эхом" вернуть символы <CR>,<LF> (0x0D, 0x0A), после чего отметить основной программе, что строка получена. Ну, и не забыть, получая каждый байт, контролировать буфер строки на переполнение.Это уже тонкости, на мой взгляд. Насколько я понял, человек не может понять как сравнить полученный массив со строкой с эталонной строкой. |
Автор: | Demiurg [ Пн янв 09, 2017 08:42:21 ] |
Заголовок сообщения: | Re: Передача строки по UART |
В качестве примеров. Код: //----------
void _Print_Buf (u08 x, char __flash *data); #define Print_Buf(x, data) _Print_Buf(((x)-1), (data)) //---------- //================== void _Print_Buf (u08 x, char __flash *data) { for (u08 i = 0; data [i] != 0;) { dsp_buf [x++] = data [i++]; } // init_dsp_buf (); } //================== //================== struct msg_cmd __flash table_msg_cmd [] = { {"CH1", KEY_ESC_COD}, {"CH2", KEY_ENTER_COD}, {"CH3", TEST_CMD}, {NULL_TEXT, NULL_CMD}, }; u08 select_cmd (void) { struct msg_cmd __flash *ptr = table_msg_cmd; while (ptr -> msg) { char __flash *ptr_2 = ptr -> msg; for (u08 i = 0; i < mirf_PAYLOAD; i++) { if (!ptr_2 [i]) return ptr -> cmd; if (ptr_2 [i] != mirf_buf [i]) break; } ptr++; } return false; } bool select_msg (u08 a) { struct msg_cmd __flash *ptr = table_msg_cmd; for (; ptr -> msg; ptr++) { if (a == ptr -> cmd) { print_buf (mirf_buf, 1, ptr -> msg); return true; } } return false; } //================== |
Автор: | ARV [ Пн янв 09, 2017 09:01:21 ] |
Заголовок сообщения: | Re: Передача строки по UART |
существуют же стадартные функции для работы со строками! scanf - прием строки strcmp - сравнение строк есть и другие с разными нюансами - почему бы не пользоваться ими? почему начинающему всегда стремятся дать советы, как сделать посложнее? |
Автор: | Demiurg [ Пн янв 09, 2017 09:10:22 ] |
Заголовок сообщения: | Re: Передача строки по UART |
ARV писал(а): ... Существуют. Лично я экономлю память МК. Как Flash так и SRAM. При подключении стандартных библиотек пару килобайт flash, а то и больше, сразу можно списывать. Не говоря уж о SRAM. Пы Сы Я же написал, "пример". Дальше дело ТС, что он будет делать. Использовать примеры или стандартные библиотеки. |
Автор: | tux [ Пн янв 09, 2017 09:21:09 ] |
Заголовок сообщения: | Re: Передача строки по UART |
ARV писал(а): очему начинающему всегда стремятся дать советы, как сделать посложнее? Мне, как начинающему, проще работать не со стандартными функциями (о которых я собственно и не знал ![]() |
Автор: | ARV [ Пн янв 09, 2017 10:11:22 ] |
Заголовок сообщения: | Re: Передача строки по UART |
tux писал(а): Мне, как начинающему, проще работать не со стандартными функциями (о которых я собственно и не знал т.е. изобретение велосипеда - это, по-вашему, проще? пока все едут, вы изобретаете, так? я понимаю случай, когда программист собаку съел на алгоритмах и способен конкурировать со стандартными функциями, решая задачи оптимизации и т.п. но когда начинающий, еще не сделавший сортировку пузырьком ни разу, вдруг решает, что самописные функции будут лучше - это, имхо, нонсенс.понимать, как работает сравнение строк - да, необходимо. писать это самому - нет, не всегда. Demiurg писал(а): Лично я экономлю память МК. Как Flash так и SRAM. При подключении стандартных библиотек пару килобайт flash, а то и больше, сразу можно списывать. не скажу, что это голословное утверждение, но сильно-сильно сомневаюсь в его истинности. расход памяти, конечно, имеет место быть, но ведь и самописная реализация какой-то функции потребует расходов... и не факт, что получится без ошибок.Demiurg писал(а): Дальше дело ТС, что он будет делать начинающего вести за ручку надо до тех пор, пока он не обретет опыт и станет способен самостоятельно принимать такие решения. даже для меня нет однозначного выбора между самописным вариантом приема строки из UART и scanf - я буду думать долго, а что взять с начинающего?но учиться (и учить) все-таки лучше от простого к сложному, от готового к нестандартному. avr-libc должна быть основой, настольной книгой, и только суровая действительность может быть основанием отказаться от нее. |
Автор: | Demiurg [ Пн янв 09, 2017 10:22:38 ] |
Заголовок сообщения: | Re: Передача строки по UART |
ARV писал(а): ... Смотрите: Код: //---------- void _Print_Buf (u08 x, char __flash *data); #define Print_Buf(x, data) _Print_Buf(((x)-1), (data)) //---------- //================== void _Print_Buf (u08 x, char __flash *data) { for (u08 i = 0; data [i] != 0;) { dsp_buf [x++] = data [i++]; } } //================== Print_Buf (2, 12, "Ваш текст"); Я работаю с символьными дисплеями так: создается буфер размером MAX_X*MAX_Y. Дисплей работает только на запись, чтения нет. Раз в 1 мс посимвольно отправляется содержимое буфера дисплея. Полное обновление дисплея происходит за MAX_X*MAX_Y + кол-во адресов строк. При дисплее 20х4 за 84 мс. Это сделано из-за того, что если на дисплей долго что-то не отправлять, на дисплее появляются кракозябры, которые появляются из-за помех. Сравните на досуге, сколько памяти займет мой способ и с применением стандартных библиотек. |
Страница 1 из 6 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |