CodeVision AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение ARV »

алгоритм в общем-то прост. данные должны содержать некую регулярность, которую и надо искать. например, пакет всегда начинется с IF и имеет общий размер 11 байт, т.е. кроме первых двух еще 9.

каждый принятый байт надо сравнивать сначала с 'I' - как только встретится, следующий должен быть 'F' - если следующий не совпал, снова начинаем ждать 'I'. когда первые 2 совпали - тупо принимаем 9 байт, обрабатываем их и снова начинаем ждать 'I'...

как-то так.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
dibor
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Чт авг 27, 2020 13:15:49

Re: CodeVision AVR в вопросах и ответах

Сообщение dibor »

ARV писал(а):каждый принятый байт надо сравнивать сначала с 'I' - как только встретится, следующий должен быть 'F' - если следующий не совпал, снова начинаем ждать 'I'. когда первые 2 совпали - тупо принимаем 9 байт, обрабатываем их и снова начинаем ждать 'I'...
Спасибо.
Вся длинна 13 байт IF и 11 цифр.
Где то так и сделал в третий раз, но оказалось не все так просто.
Так как после IF должны быть только цифры то выше приведенный алгоритм не подошел, т.к. в некоторых случаях после IF следовали другие символы, видать другие команды.
Так что после того как совпали IF начал проверять что каждый новый 2....13 принятый байт это цифра, если какой либо нет то очищаю принятый буфер и устанавливаю индекс приемного счетчика на ноль, и начинаю анализировать вновь принятые байты.
Теперь вроде работает как надо. :)
Ivanoff-iv писал(а):а кодевижен хороший и в твоих проблемах не виноват
Злой вы какой то.
Написали много а толку ноль.
Если нечего сказать - то лучше всего молчать.
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: CodeVision AVR в вопросах и ответах

Сообщение Ivanoff-iv »

почему?
в вашем вопросе я не уловил, что буквы (префикс) обязательно "if" и нужно просто принять ряд цифр идущих следом...
тогда всё становится гораздо проще:
заводим в этом прерывании локальную статик унсигнед-чар переменную "х"=-2;
при приёме байта: (обозначим его а)

Код: Выделить всё

иф (x<=10)) 
    {
    иф ((а>="0")&&(a<="9")) //проверяем что принята цифра
        {
        у[х]=а-"0";         //записываем в массив числовые значения принятых цифр
        иф(х<10) {х++;}    //если посылка не полная переходим к следующей ячейке
        else {х=-2; установим флаг успешного приёма;}; //если полная
        } 
    else x=-2; //если принята не цифра - возвр. в исходное состояние с поиском "I"
    };
иф (х==-1) {иф (а=="f") {х++;} else x=-2;};  //поиск "F"
иф (х==-2) {иф (а=="i") х++;};  //поиск "I"
и когда в коде увидим взведённый флаг приёма - забираем цифры из массива у.
(порядок ифов такой, чтобы выполнение одного условия не вызвало цепного выполнения остальных, можно кейс или елзе-иф применить...)
я не злой :) видишь :)) улыбаюсь... я люблю помогать людям, но твоё ТЗ показалось мне совсем непонятным... (нужно чтото принять есть 2 буквы... а буквы IF в начале я посчитал вообще - так, для примера...)
Последний раз редактировалось Ivanoff-iv Пт авг 28, 2020 06:11:36, всего редактировалось 3 раза.
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Аватара пользователя
dibor
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Чт авг 27, 2020 13:15:49

Re: CodeVision AVR в вопросах и ответах

Сообщение dibor »

Ivanoff-iv писал(а):иф (x<=10)) {иф ((а>="0")&&(a<="9")) {иф(х<10) {у[х]=а-"0"; х++;} else {х=-2; установим флаг успешного приёма;};} else x=-2;};
Спасибо конечно.
Но так как я и сказал что я -1(хуже нуля) в С , то написанное, мне представляется какой то не ведомой мне магической строкой, извините.
Ivanoff-iv писал(а):локальную статик унсигнед-чар переменную "х"=-2;
Тут тоже не понял, вроде как без знаковая переменная а имеет значение -2, или я и вправду стар и туп :)

Всяко разно спасибо за желание помочь.
Написал свой кривой код и пусть он работает.
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: CodeVision AVR в вопросах и ответах

Сообщение Ivanoff-iv »

извняюсь, не хотел "давить"
-2 в переменной унсигнед чар это 0xFE (вобщем как и в знаковой) или 254 по русски :)
так мы убиваем сразу 3 зайцев -
1 сравнивать её будет проще (в условии когда считаем цифры, уже одно ограничение останется, а не 2)
2 при заполнении массива переменную х можно использовать в качестве номера элемента
3 считать проще (11 элементов от 0 до 10)
сама переменная обращается в 0 при переполнении (я поправил код, а то и переполнение не использовалось - но это не страшно, и ещё ошибку допустил, а это уже хуже...)

Добавлено after 1 hour 29 minutes 54 seconds:
строка действительно получилась слегка трудноватой для понимания, её следует разбить на несколько расставив перед иф'ами переносы и отступы, я это всё писал с телефона на выгуле собаки и обрамить правильным тегом и выравниваниями (чтоб оно читабельней выглядело) не смог...

Добавлено after 48 seconds:
сейчас попробую поправить...
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Аватара пользователя
dibor
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Чт авг 27, 2020 13:15:49

Re: CodeVision AVR в вопросах и ответах

Сообщение dibor »

dibor писал(а):сейчас попробую поправить...
Спасибо.
Попробую ваш вариант тоже, он выглядит намного короче чем я накалякал.

Добавлено after 48 minutes 28 seconds:
Нихт арбайтен :(
даже после исправления синтаксиса '0' вместо "0" и т.д.

Добавлено after 41 minute 49 seconds:
Так работает:

Код: Выделить всё

    char a;
    static char y[14];
    bit done;
    static unsigned char x=-2;
    status = UCSR0A;
     a = UDR0;

if (x<=11)
    {
    if ((a>='0')&&(a<='9'))
        {
        if(x<11) {y[x]=a; x++;}
        else {x=-2; done=1;};
        }
    else x=-2;
    };
if (x==-1) {if (a=='F') {x++;} else x=-2;};
if (x==-2) {if (a=='I') x++;};
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: CodeVision AVR в вопросах и ответах

Сообщение Ivanoff-iv »

ещё ошибку нашел...
у[х]=а; нужно вынести из иф и поставить его перед (внутри этой скобки останется только х++;)
и в сравнения верни 10 вместо 11.
ошибка проявляется тем, что нужна ещё одна (12я) цифра в посылке, чтобы взвести флаг. т.е. правильная посылка вида "ИФ###########" будет пропущена, если следом пойдёт буква.
Ошибку в коде исправил, заодно добавил комментарии...
_______
размер массива у достаточно 11, кстати, ты его используешь?
если нет, то убирай его совсем (и все операции с ним тоже),
если да, то почему тут объявлен? его ведь не видно будет из другой части кода?
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Аватара пользователя
dibor
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Чт авг 27, 2020 13:15:49

Re: CodeVision AVR в вопросах и ответах

Сообщение dibor »

Ivanoff-iv писал(а):у[х]=а-"0";
Что это????
так не работает!
Так работает:

Код: Выделить всё

if (x<=10)
    {
    if ((data>='0')&&(data<='9'))
        {
        y[x]=data;
        if(x<10) {x++;}
        else {x=-2; done=1;};
        }
    else x=-2;
    };
if (x==-1) {if (data=='F') {x++;} else x=-2;};
if (x==-2) {if (data=='I') x++;};
Массив y переписывается в другой когда приняты все данные

Код: Выделить всё

	if (done == 1)
	{
		strcpy(Command_string, y);
        done = 0;
	}
Спасибо!
Еще чему то научился :)
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: CodeVision AVR в вопросах и ответах

Сообщение Reflector »

[uquote="dibor",url="/forum/viewtopic.php?p=3884652#p3884652"]Так работает:

Код: Выделить всё

    bit done;
    static unsigned char x=-2;
[/uquote]
Done не инициализирована и может быть 1 с самого начала, x присваиваются отрицательные значения, но объявлена она как unsigned ...
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: CodeVision AVR в вопросах и ответах

Сообщение Ivanoff-iv »

Reflector, [uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3884535#p3884535"]-2 в переменной унсигнед чар это 0xFE (вобщем как и в знаковой) или 254 по русски :)[/uquote] беззнаковой я её обозначил только для того, чтобы не случилось казуса при сравнении:
мне нужно выделить интервал [0-10], я поставил одно условие (x<11) если переменная будет со знаком, то и -1 и -2 тоже подпадут под это условие, а в беззнаковом -1 и -2 будут поняты как 255 и 254 соответственно, и в интервал не попадают, что и требовалось.
dibor,
Ivanoff-iv писал(а):у[х]=а-"0";
ну, про кавычки ты уже сам понял, поэтому я и не стал их исправлять...
у[х]=а; загружает в массив ровно то, что прилетело в УАРТ
у[х]=а-'0'; перед загрузкой вычтет порядковый номер символа "0", а т.к. цифры идут по порядку - то останется только значение принятого числа... т.е. произойдет преобразование "0"->0, "1"->1, "2"->2... и.т.д.
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: CodeVision AVR в вопросах и ответах

Сообщение Reflector »

[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3884874#p3884874"]беззнаковой я её обозначил только для того, чтобы не случилось казуса при сравнении[/uquote]
Можно было спокойно нумеровать состояния начиная с 0, как обычно и делают, потом в одном месте отнять два(у[х - 2] = а). По идее компилятор даже дополнительно отнимать ничего не будет, а просто загрузит для начала массива адрес уменьшенный на 2. Как минимум это избавляет от казусов при чтении исходников :)
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: CodeVision AVR в вопросах и ответах

Сообщение Ivanoff-iv »

Да можно,но:
1)вместо if (x<=10) придется писать if ((x>=2)&&(x<=(10+2)))
2 условия вместо одного - код станет длиннее
2)вместо у[х] = а; придется писать у[х - 2] = а;
3)имхо код не станет понятней
так тут сразу видно, что 2 итерации подготовительные
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Аватара пользователя
dibor
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Чт авг 27, 2020 13:15:49

Re: CodeVision AVR в вопросах и ответах

Сообщение dibor »

Reflector писал(а):Done не инициализирована и может быть 1 с самого начала
Не может.
Если не инициализирована то всегда 0, так написано в документации.
Ivanoff-iv писал(а):у[х]=а-'0'; перед загрузкой вычтет порядковый номер символа "0"
Так не работает!
От каждого принятого символа а будет отниматься '0' ???

Все работает как я опубликовал.
Прекрасный трюк со значением х

Спасибо еще раз.
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: CodeVision AVR в вопросах и ответах

Сообщение Ivanoff-iv »

да, так и будет
специально в своем проекте (над которым сейчас работаю) написал outb-='0'; (outb - имеющаяся в проекте переменная)
и квавр в ассемблерной вкладке выдал:
; 0000 002D outb-='0';
LDI R30,LOW(48)
SUB R10,R30

это значит, что из переменной отнялось 48 (0x30 - как-раз то число, которым символ "0" закодирован) и ошибок это не вызвало.
а что не получается у тебя? ошибки компиляции кода или результат работы неправильный?

Добавлено after 3 minutes 35 seconds:
всё, я понял - тебе символы и нужны (а не значения), тогда да, отнимать ничего не надо.
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Аватара пользователя
dibor
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Чт авг 27, 2020 13:15:49

Re: CodeVision AVR в вопросах и ответах

Сообщение dibor »

Да, бэйсиковый я человек, привык к готовым функциям а тут ничего нет :(
Как вставить символ в уже существующий стринг?
Или надо по символьно переписывать в другой массив с добавлением дополнительного символа?
К примеру надо из стринга 144000000 сделать 144.000.000 для более удобного отображения.
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: CodeVision AVR в вопросах и ответах

Сообщение Reflector »

[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3884932#p3884932"]Да можно,но:
1)вместо if (x<=10) придется писать if ((x>=2)&&(x<=(10+2)))
2 условия вместо одного - код станет длиннее
2)вместо у[х] = а; придется писать у[х - 2] = а;
3)имхо код не станет понятней[/uquote]
У меня нет компилятора для AVR, тем более CodeVision, но запускаю в Compiler Explorer простенький пример для AVR GCC 9.2.0:

Код: Выделить всё

constexpr unsigned char x = -1;
static_assert(x == -1);
И получаю ошибку компиляции, потому то при сравнении все приводится к int и получаем (0xFF == 0xFFFF), а на STM32 int 32-х битный, там вместо -1 подставит 0xFFFFFFFF. Ну ладно, собираю тестовый пример с твоим кодом, уже для STM32:
Спойлер

Код: Выделить всё

	static char str[] = "IF12GIF01234567895I";
	static char y[10];
	bool done = false;
	uint8_t x = -2;

	for (char* p = str; *p; p++)
	{
		char a = *p;

		if (x <= 10)
		{
			if (a >= '0' && a <= '9')
			{
				y[x] = a;
				if (x < 10)
				{
					x++;
				}
				else
				{
					x = -2;
					done = true;
					break;
				}
			}
			else x = -2;
		}
		if (x == (uint8_t)-1)
		{
			if (a == 'F') x++;
			else x = -2;
		}
		if (x == (uint8_t)-2)
		{
			if (a == 'I') x++;
		}
	}

	rtt.printf<"{}, {}\n">(done, y);   // true, 01234567895
Добавил break и пару приведений к uint8_t, чтобы вообще работало, но в развернутом виде код уже не выглядит таким компактным, как изначально... Теперь пишу свою реализацию:
Спойлер

Код: Выделить всё

	static char str[] = "IF12GIF01234567895I";
	static char y[10];
	bool done = false;
	uint8_t x = 0;

	for(char* p = str; *p; p++)
	{
		char a = *p;
		
		if (x == 0)
		{
			if (a == 'I') x = 1;
		}
		else if (x == 1)
		{
			x = (a == 'F') ? 2 : 0;
		}
		else
		{
			if(a >= '0' && a <= '9')
			{
				y[x - 2] = a;
				if (x++ == 12)
				{
					done = true;
					x = 0;
					break;
				}
			}
			else x = 0;
		}
	}

	cout.printf<"{}, {}\n">(done, y);
Начальное состояние нулевое, никаких дополнительных условий не появилось, нет приведений и для -Os размеры двум бинарников абсолютно одинаковые.

ps. В настройках CodeVision есть "Promote char to int", который по умолчанию еще и вроде выключен, видимо потому код со сравнением (x == -1) и работает...
Аватара пользователя
dibor
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Чт авг 27, 2020 13:15:49

Re: CodeVision AVR в вопросах и ответах

Сообщение dibor »

Reflector писал(а):ps. В настройках CodeVision есть "Promote char to int", который по умолчанию еще и вроде выключен, видимо потому код со сравнением (x == -1) и работает...
У меня в настройках это выключено.
Не нравится x==-1 замените на x==255.

Думаю пример приведенный Ivanoff-iv самый короткий.
Так что пригодится еще кому нибудь.
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: CodeVision AVR в вопросах и ответах

Сообщение Ivanoff-iv »

Reflector, спасибо за предупреждение... на эти подводные грабли мне ещё предстояло наступить (я начинал в квавр и работаю в квавр, а на СТМ только собираюсь переходить)
впринципе -1 и -2 можно заменить любыми числами >11, только переходы в подготовительных этапах нужно сделать не инкрементом, а присвоением.
dibor, если у тебя получается выводить массив, то проще всего точки добавить прямо в него ещё на этапе заполнения:
при заполнении внутри проверки на окончание посылки там, где инкремент х, допиши
иф ((х%4)==3) {у[х]='.'; х++;};
или иф ((х&0х03)==3) {у[х]='.'; х++;};
// эти выражения дадут одинаковый результат, но второе выполнится быстрее.
и в сравнениях 10 замени на 12.
так он после каждой третьей из четырёх, позиции будет вставлять точку.

Добавлено after 2 minutes 57 seconds:
кстати квавр вроде не понимает конструкции вида иф(х++==12)... :(
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Аватара пользователя
dibor
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Чт авг 27, 2020 13:15:49

Re: CodeVision AVR в вопросах и ответах

Сообщение dibor »

Ivanoff-iv писал(а):то проще всего точки добавить прямо в него ещё на этапе заполнения
Этот массив использую для преобразования в число и т.д. поэтому это не вариант, хотя можно заполнять еще один массив параллельно.
Неужели нет наработанных функций как в Васике MID, Right, Insertchar ??
Аватара пользователя
mixon46
Говорящий с текстолитом
Сообщения: 1644
Зарегистрирован: Сб фев 18, 2012 15:42:29
Откуда: Курск

Re: CodeVision AVR в вопросах и ответах

Сообщение mixon46 »

Как преобразовать массив с данными
Mass [3]= {1,5,2} \\то есть три переменные в одну
I=152;

Если я правильно думаю то надо так
I= mass[1]×100+mass[2]×10+mass[3]×1

Да только проблема в том что отправляются 152 в виде знаков asc2
Ответить

Вернуться в «AVR»