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

Обсуждаем контроллеры компании Atmel.
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

Сообщение dm211 »

Вот так сделал-

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

char s[]="RING"; 
if(!strcmp(rx_buffer,s)) putsf("ATA\r");
Последний раз редактировалось dm211 Вт сен 01, 2009 17:20:42, всего редактировалось 1 раз.
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

Сообщение dm211 »

Но это работает только один раз, это понятно-нужно очистить массив,чтобы следующая приходящая строка вводилась на чистый массив. Как это можно сделать ?

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

memset(rx_buffer,0,100);
не помогает.
Аватара пользователя
alexsey163
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Чт авг 27, 2009 12:59:23
Откуда: тольятти
Контактная информация:

Сообщение alexsey163 »

здравствуйте а есть у кого нибудь старая версия code vision avr или дайте ссылку. :lol:
С надеждой в сердце ждущий счастья avrщик
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

Сообщение dm211 »

http://www.hardlock.org.ua/soft/cvavr/index.html
Мне бы кто ответил..
Аватара пользователя
alexsey163
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Чт авг 27, 2009 12:59:23
Откуда: тольятти
Контактная информация:

Сообщение alexsey163 »

спасибо вам но там она не работает. :( .Не знаете ли ещё откуда можно скачать старую версию.
С надеждой в сердце ждущий счастья avrщик
Аватара пользователя
Yellow Tiger
Сверлит текстолит когтями
Сообщения: 1148
Зарегистрирован: Вт июл 08, 2008 12:24:17

Сообщение Yellow Tiger »

dm211 писал(а):http://www.hardlock.org.ua/soft/cvavr/index.html
Мне бы кто ответил..
Работать напрямую с rx_buffer - не следует, ведь он хранит не строку, а данные циклического буфера - начало строки в нем не по адресу rx_buffer[0], а где угодно внутри. :)))
Я советовал использовать gets() - что-то не подошло в таком варианте? Слишком простой, так как не нужно пользоваться memset'ом? :)))
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

Сообщение dm211 »

gets() у меня ошибку выдает.
Аватара пользователя
Yellow Tiger
Сверлит текстолит когтями
Сообщения: 1148
Зарегистрирован: Вт июл 08, 2008 12:24:17

Сообщение Yellow Tiger »

И что теперь - отказаться от неё? :)))
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

Сообщение dm211 »

Допустим,без gets(), а с помощью getchar() собираю приходящие символы в массив m, внутри прерывания по приходящему символу:

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

char s[]="RING";
char m[5];
// Прерывание по приему символа в регистр  UDR
interrupt [USART_RXC] void usart_rx_isr(void)
{
......
 m[i]=getchar();
  i++; if(i==5)i=0;   
  if(!strcmp(m,s)){putsf("ATA\r");}
}

Тоже работает только один раз, пробовал так-

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

if(!strcmp(m,s)){putsf("ATA\r");m[0]='0';} // также m[0]='\0'; , m[0]=' ';
-толку нет. Перерыл весь инет-с такой проблемой вопросы есть,но ответа толкового нет.
Вот проект с Протеусом-
Вложения
UART.rar
(71.42 КБ) 230 скачиваний
Аватара пользователя
Yellow Tiger
Сверлит текстолит когтями
Сообщения: 1148
Зарегистрирован: Вт июл 08, 2008 12:24:17

Сообщение Yellow Tiger »

То, что ваша программа вообще работает - чистая случайность.

Общие замечания:

1. Я вам уже говорил - использовать приемный буфер, как строку нельзя - это только в первый раз символы укладываются в него с начала, а дальше - начало строки и её конец циклически ползают по буферу. Правда, ваше "работает только в первый раз" имеет другой объяснение - о нем чуть позже.

2. Участок кода от getchar() до putsf() должен быть вынесен за пределы обработчика прерываний - во-первых, потому, что работа со входным потоком и обработкой команд - это синхронная часть кода, а не асинхронная; а во-вторых потому, что тело обработчика прерываний должно исполняться за наикратчайшее время. Выносите всё в main() (пока нет других, вложенных функций).

3. глобальные переменные (i, m[]) объявляйте как volatile, иначе компилятор, видя, что к ним ни один оператор функции main и вызываемых ею, не обращается, может соптимизировать все "до нуля". :)))

Теперь о поведении программы.
Символьный массив m[] - статический, а значит - инициируется нулями. Что произойдет в первый раз, после приема символа 'G'??? ... подумали? Ответ нашли? ... Показываю - в буфере (еще до прихода символа '\r'!!!), будет строка 'RING\0' - и сравнение с помощью strcmp() пройдет правильно, но(!!!) - признак конца строки, после четырех символов RING - находится там случайно - он остался от нулей, внесенных во время инициализации статических данных, и больше его туда никто не поместит, а значит - strcmp() уже никогда не найдет там какую-либо строку, даже если вы приложите усилия к тому, чтобы прерывание всякий раз укладывало новую строку, начиная с первого символа.

В общем, в первый раз срабатывает правило четности ошибок, и программа срабатывает "верно", но потом количество ошибок становится нечетным,и программа перестает создавать видимость правильной работы. :)))

Удачи! :)
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

Сообщение dm211 »

Спасибо за подробные разьяснения.
Аватара пользователя
Yellow Tiger
Сверлит текстолит когтями
Сообщения: 1148
Зарегистрирован: Вт июл 08, 2008 12:24:17

Сообщение Yellow Tiger »

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

Сообщение ARV »

мне вообще непонятна страсть начинающих к кольцевым буферам и прерываниям... ну если опыта маловато, ну поступайте примитивно - работайте по ожиданию символа! 99% ваших потребностей реализуются так, что пока не пришло что-то - ничего не делается! тут никаких асинхронных приемов с буфферизацией не нужно...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Yellow Tiger
Сверлит текстолит когтями
Сообщения: 1148
Зарегистрирован: Вт июл 08, 2008 12:24:17

Сообщение Yellow Tiger »

Так ведь, такой пример попался... с кольцевым буфером. :(
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

Сообщение dm211 »

Да у меня давно все работает по приходу символа, иногда не хватает-например- узнать заряженность аккумулятора модема, чтоб снаружи включить зарядку
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

Сообщение dm211 »

Ну я же спрашиваю тех,у кого большой опыт...
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

Сообщение dm211 »

Тогда мне надо сделать по другому-не сравнивать строки полностью, а сделать реакцию, если в приходящих символах есть например одна за другой цифры 7,0, тогда и переполнение буфера не страшно. Буду думать над этим.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

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

если у вас набор принимаемых команд ограничен (это явно так), и каждая команда может быть однозначно определена не более чем по N первых символов, вы можете во-первых, хранить в памяти только эти N первых символов команды (т.е. сэкономить память), во-вторых, обойтись вообще без буфера, а анализировать приходящие символы по одному.

поясню алгоритм поиска.
вы определяете структуру типа

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

typedef struct{
   char flag; // признак "активности"
   char cmd[]; // строка-команда
}t_search
и потом создаете массив таких структур с заданием каждому элементу массива flag=1 и cmd = "вашей строке".

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

t_search array[3] = {
   {1,"RE"}, {1,"RU"}, {1,"ST"} // для команд RESET, RUN и STOP хватит анализа первых 2 символов
};


затем начинаете ждать символ. когда пришел символ - вы его сравниваете с первым символом команд во всем массиве, и устанавливаете flag=1 для тех элементов, в которых символы совпали.

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

array[i].flag = array[i].str[1] == ch;


затем ждете следующий символ и сравниваете его со вторым символом тех команд, у которых flag==1. если оказалось, что второй символ не совпал в некоторых элементах массива - вы делаете для них flag=0.

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

array[i].flag = array[i].flag && (array[i].str[2] == ch);
и так повторяете до тех пор, пока не будут приняты N символов, по которым 100% будет определена единственная команда в массиве - только у нее останется flag==1.

если синтаксис ваших команд таков, что принимается более длинаая команда, чем из N символов, или в команде имеются параметры, которые тоже надо обрабатывать, то это вы делаете уже после определения команды: "хвост" символов сверх N просто отбрасываете (ведь к этому моменту уже ясно, сколько там осталось символов), а параметры выделяете традиционным методом.

естественно, после всего этого надо сделать flag = 1;во всех элементах массива.

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

Мой уютный бложик... заходите!
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

Сообщение dm211 »

Спасибо, буду разбираться со структурами теперь.
klok
Родился
Сообщения: 4
Зарегистрирован: Ср сен 02, 2009 22:59:20
Откуда: NN
Контактная информация:

Сообщение klok »

Yellow Tiger писал(а):Прерывание помещает приходящие символы в буфер, getch() - достает их оттуда, а gets() - вызывает getch() (помещая результат в строку) пока не получит из неё символ конца строки. И всех делов.


Приветствую мастеров Си... У меня задача, сходная с задачей dm211 - есть набор запросов, на которые надо отвечать... УАРТ должен работать по прерыванию... Сразу скажу, на асме я это делал не напрягаясь, подозреваю что на Си это еще проще, только вот не вштырило меня еще Си :(
Подскажите как мне эту gets вызвать, и что она мне даст в ответ...

Лучше пример кода, дальше разберусь :)
Ответить

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