maik-vs 0 22 августа, 2007 Опубликовано 22 августа, 2007 · Жалоба Дык у аффтара проблемы с передачей,значит руками флаги дергать ваще не надо.байт в UDR -и смотри чего-там с прерываниями.И скачайте версию 4.13,там атымельцы здорово над переферией поработали. Согласен. Я удивился, как он этих флагов не видел. Или мышой не ткнул? А что нового в периферии в 4.13? У меня только нумерацию битов приходится всё время включать, больше новостей не заметил. Проц М16. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 22 августа, 2007 Опубликовано 22 августа, 2007 · Жалоба Ну в принципе даже разрешение TXC можно не дергать, если вы можете дать гарантию, что время реакции на UDRE не превысит времени передачи символа.Ещё можно тупо в прерывании UDRE - если производится запись очередного байта в UDR, то не глядя заодно сбрасывать флаг TXC. В суме это даёт меньше кода, чем разрешение/запрещение TXCIE и защищает от задержки отработки UDRE. Так как если были запрещены прерывания и UDRE не отработало своевременно, успел установиться флаг TXC, то при разрешении прерываний (выходе из другого прерывания) первым будет передано управление на UDRE_vect. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=GM= 0 22 августа, 2007 Опубликовано 22 августа, 2007 · Жалоба To defunct. Посмотрел на ваш код. Пример написан под AT90S2313, чтобы переделать под Tiny2313 надо будет поменять таблицу векторов и возможно пару штрихов с настройкой UART'a Одно место меня озадачило, в теле подпрограммы PutChar вы снова вызываете PutChar. Это что, такая рекурсия заложена, или как? Вроде не должно работать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 22 августа, 2007 Опубликовано 22 августа, 2007 · Жалоба Одно место меня озадачило, в теле подпрограммы PutChar вы снова вызываете PutChar. Это что, такая рекурсия заложена, или как? Спасибо что проявили интерес ;> Да - там рекурсия. посылаем строку "hello\n" putchar автоматически добавит возврат каретки и терминал примет "hello\r\n". Вроде не должно работать. Попробуйте код. ;> Какой резон мне выкладывать что-то нерабочее? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=GM= 0 23 августа, 2007 Опубликовано 23 августа, 2007 · Жалоба Да - там рекурсия Посмотрел попристальнее - нет там никакой рекурсии. И вообще, проще было бы вызывать не rcall PutChar, a rcall __skip_add_cr (ну и названьице(:-)). И выполнение было бы быстрее, ведь рутина у вас и в прерывании вызывается... Попробуйте код А чего его пробовать, и так видно, что тяжеловесно и неоптимально. Например, фрагмент с кольцевым буфером можно написать в два раза короче. А что там за пляски с бубнами в PutChar: in AH,SREG cli + out SREG,AH? Не проще ли обойтись связкой cli/sei. Или вот: зачем стоит tst AL перед rcall PutChar в рутине Print? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 23 августа, 2007 Опубликовано 23 августа, 2007 · Жалоба Посмотрел попристальнее - нет там никакой рекурсии. Смотрите пристальнее сразу. Ок? Есть там рекурсия, коль скоро функция вызывает сама себя. проще было бы вызывать не rcall PutChar, a rcall __skip_add_cr (ну и названьице(:-)). Не сомневаюсь что вы именно так и поступаете, у меня же все метки начинающиеся с "__" внутренние и я стараюсь их не вызывать, чтобы было меньше путаницы. А что там за пляски с бубнами в PutChar: in AH,SREG cli + out SREG,AH? Не проще ли обойтись связкой cli/sei. Или вот: зачем стоит tst AL перед rcall PutChar в рутине Print? Не проще. Потому что вызывается эта функция еще и в прерывании. И вообще прежде чем хаить хамоватым тоном - разберитесь с кодом. Или вот: зачем стоит tst AL перед rcall PutChar в рутине Print? опечатка. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=GM= 0 23 августа, 2007 Опубликовано 23 августа, 2007 · Жалоба Есть там рекурсия, коль скоро функция вызывает сама себя. Ну-ну, tell it your sailors(:-). Рекурсии там нет. Рекурсия – это сведение вычисления задачи некоторой размерности N к вычислению аналогичных задач меньшей размерности. Вот пример классической рекурсии. Задача заключается в том, чтобы найти по заданному n число последовательности Фибоначчи Fn. #include <stdio.h> #include <time.h> long F(unsigned int n) { return n <= 1 ? n : F(n-1) + F(n-2); } int main() { time_t begin, end; long res; for(int n = 0; n < 40; n++) { time(&begin); res = F(n); time(&end); printf("%-3i\t%-9li\t%-20.3f\n",n,res,difftime(end,begin)); } return 0; } Кстати, цикл является частным видом рекурсии. У вас ни того, ни другого. Не сомневаюсь что вы именно так и поступаете, у меня же все метки начинающиеся с "__" внутренние и я стараюсь их не вызывать, чтобы было меньше путаницы. Дорогой мой, зачем метки тогда вообще писать. Я пишу программы так, чтобы они были эффективные и красивые, а не какие-то там крокозябры (это не вам). Не проще. Потому что вызывается эта функция еще и в прерывании. Ну хорошо, не проще, так не проще. Сейчас я вам покажу как ваш код работает. Выполняется программа Print, перед brne возникает прерывание по приему с rx. Программа прерывания запишет принятый байт внутрь строки, которую программа Print собирается поместить в кольцевой буфер. В результате вы получите не ту строку, которую копировали из флеши, а несколько другую. Я бы назвал сиё скрытым (неявным) багом. И вообще прежде чем хаить хамоватым тоном - разберитесь с кодом Прошу прощения, если кого-то обидел, но я никому не хамил и никого не хаял. Была выложена программа, идёт её обсуждение, ничего личного. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 23 августа, 2007 Опубликовано 23 августа, 2007 · Жалоба Ну-ну, tell it your sailors(:-). Рекурсии там нет. Рекурсия – это сведение вычисления задачи некоторой размерности N к вычислению аналогичных задач меньшей размерности. Вот пример классической рекурсии. Ваше определение рекурсии и пример - неверны. либо взяты не из той предметной области. рекурсия — частичное определение объекта через себя, определение объекта с использованием ранее определённых. Рекурсия используется, когда можно выделить самоподобие задачи. В программировании рекурсия — вызов функции или процедуры из неё же самой источник: http://ru.wikipedia.org/wiki/Рекурсия Ну хорошо, не проще, так не проще. Сейчас я вам покажу как ваш код работает. Выполняется программа Print, перед brne возникает прерывание по приему с rx. Программа прерывания запишет принятый байт внутрь строки, которую программа Print собирается поместить в кольцевой буфер. В результате вы получите не ту строку, которую копировали из флеши, а несколько другую. Я бы назвал сиё скрытым (неявным) багом. Теоретически возможно. Атомарность Print я не организовывал. Но конструкция реализованная в PutChar не препятствует организации атомарности Print. тем же самым in Rr, SREG - cli - out SREG, Rr Дорогой мой, зачем метки тогда вообще писать. Во-первых выбирайте выражения. Своему бойфренду можете говорить "дорогой мой". Во-вторых, я не виноват что русский язык порождает неоднозначность ("не вызывать" - имелось в виду "call" не делать. ) в третьих - это такой стиль - для обозначения внутренних меток (локальных для функций) на которые осуществяется условный переход я применю "тэг" - "__". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 23 августа, 2007 Опубликовано 23 августа, 2007 · Жалоба =GM=, при всём уважении к Вашим знаниям давайте будем добрее друг к другу. Так вы отобъёте всякое желание выложить свою прогу, чтобы кому-то помочь. :) Любая маломальски приличная прога содержит ошибки. Иногда их вылавливаешь годами. Плюс различные предпочтения у каждого программиста. Это как аккорды на гитаре. Один пользуется чаще такими а другой другими. Но если оба музыканта, то музыка всё равно звучит. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
WHILE 0 23 августа, 2007 Опубликовано 23 августа, 2007 · Жалоба Рекурсия – это сведение вычисления задачи некоторой размерности N к вычислению аналогичных задач меньшей размерности А откуда такое определение рекурмии,ссылку можно? В программировании рекурсия — вызов функции или процедуры из неё же самой Вот с этим не поспоришь. И чего-вы к обозначению внутренних меток прицепились?По моему,нормальная идея визуально разделять локальные и глобальные метки. З.Ы. вы кодер,не знающий ошибок? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=GM= 0 23 августа, 2007 Опубликовано 23 августа, 2007 · Жалоба Ваше определение рекурсии и пример - неверны. либо взяты не из той предметной области. рекурсия — частичное определение объекта через себя, определение объекта с использованием ранее определённых. Рекурсия используется, когда можно выделить самоподобие задачи. Мой пример классический, не я его выдумал, взгляните на него непредвзято (заменил там рекурсивную функцию F на более заметную RECURRENCE). long RECURRENCE(unsigned int n) { return n <= 1 ? n : RECURRENCE(n-1) + RECURRENCE(n-2); } Напишите ваш код PutChar на си в таком же виде, тогда и будем говорить, что верно, а что неверно. Интересно, что у вас будет параметром рекурсии? Теоретически возможно. Атомарность Print я не организовывал. Но конструкция, реализованная в PutChar не препятствует организации атомарности Print. тем же самым in Rr, SREG - cli - out SREG, Rr Так я и сказал. что все эти примочки внутри PutChar не нужны, не решают они задачу до конца, а снаружи атомарность передачи строки вы не обеспечили. И не теоретически, а сугубо практически, поверьте. Во-первых, выбирайте выражения. Своему бойфренду можете говорить "дорогой мой" Да что ж такое! Такое впечатление, что или у всех мозги такие извращенные, или все свихнулись на этой секссвободе, что ни скажешь, всё переводят в плоскость гениталий. Вы уж, уважаемый, тоже слова выбирайте. =GM=, при всём уважении к Вашим знаниям давайте будем добрее друг к другу. Так вы отобъёте всякое желание выложить свою прогу, чтобы кому-то помочь. :) Знаний как раз маловато, спасибо форуму, много даёт в плане самообразования. Да я...белый и пушистый, defunct'а почти люблю (как брата, а то опять поймет не в той плоскости(:-)). Что касается проги, не собирался я её критиковать, с первого взгляда она мне понравилась, посмотрел по диагонали - в подпрограмме вывода символа вроде используется рекурсия, вот думаю, люди рекурсию применяют, а я от неё как чёрт от ладана, ну я и спросил спроста, а потом уж стал смотреть, а он мне отвечает, да, там рекурсия, да какая рекурсия, курам на смех Любая мало-мальски приличная прога содержит ошибки. Иногда их вылавливаешь годами. Плюс различные предпочтения у каждого программиста. Это как аккорды на гитаре. Один пользуется чаще такими, а другой другими. Но если оба музыканта, то музыка всё равно звучит. :) Согласен. Ошибок в любой программе полно, у самого так. Смотришь на программу годичной давности, и думаешь, неужели это я написал такое гуано? Ну посмотрел я его программу, ну высказал замечания, будь благодарен, что кто-то потратил своё время, разобрался, принял участие, ответил, что плохого? Почему сразу надо воспринимать как наезд, которого и в помине не было. Дефункту не надо было говорить, чтоб код испытал(:-). Да если б все мои программы так критиковали, это было бы здорово, и программы были бы в стократ лучше... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 23 августа, 2007 Опубликовано 23 августа, 2007 · Жалоба Мой пример классический, не я его выдумал, взгляните на него непредвзято (заменил там рекурсивную функцию F на более заметную RECURRENCE). Взглянул непредвзято.. будем считать, что вы взяли определение рекурсии не из той предметной области. Напишите ваш код PutChar на си в таком же виде, тогда и будем говорить, что верно, а что неверно. Интересно, что у вас будет параметром рекурсии? отправляемый char, а что еще может быть параметром? функциональный аналог ассемблерной функции: void put(U8 ch) { if (ch == 0x0A) // add CR char ahead of LF put(0x0D); { U8 IStatus = ILock() pRing->storage[ pRing->tail ] = ch; pRing->tail = RingNextTail( pRing ); IUnlock( IStatus ); } } Так я и сказал. что все эти примочки внутри PutChar не нужны, не решают они задачу до конца, Это вам так кажется. Примочки внутри putchar решают свои задачи: - атомарность выгрузки символа в очередь - добавление символа CR а снаружи атомарность передачи строки вы не обеспечили. И не теоретически, а сугубо практически, поверьте. Господи, да что вы цепляетесь к фантикам от конфет. Чес слово. Уж не пойму или у меня там полный бред в коде или у вас проблемы с прочтением алгоритма из асм программы. поменять Print так: /* * Print() * Выводит строки размещенные во флеш памяти через PutChar * ---> Z - указатель на строку оканчиваемую \0 во флеш * <--- ничего не возвращает */ Print: in AH, SREG push AH cli __do_output: lpm; // читаем данные флеш adiw Z, 1 // увеличим указатель на 1 (z++) mov AL, R0 rcall PutChar tst AL brne __do_output pop AH out SREG, AH ret и будет обеспечиваться атомарность. push/pop конечно же можно сократить если использовать какой-либо другой регистр для хранения SREG вместо AH, но поставил специально для наглядности. да какая рекурсия, курам на смех Маленькая простенькая - но рекурсия, т.к. функция вызывает сама себя. Прочитайте определение рекурсии на wiki. Ну посмотрел я его программу, ну высказал замечания, будь благодарен, что кто-то потратил своё время, разобрался, принял участие, ответил, что плохого? Я выразил вам благодарность и попытался нормально ответить на ваши вопросы вначале. PS: я и сейчас пытаюсь отвечать на ваши вопросы по-сущесту, с приведением ссылок и примеров. Может вы просто не замечаете? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=GM= 0 23 августа, 2007 Опубликовано 23 августа, 2007 · Жалоба Уж не пойму или у меня там полный бред в коде или у вас проблемы с прочтением алгоритма из асм программы. поменять Print так: /* * Print() * Выводит строки размещенный во флеш памяти через UART * ---> Z - указатель на строку оканчиваемую \0 во флеш * <--- ничего не возвращает */ Print: in AH, SREG push AH cli __do_output: lpm; // читаем данные флеш adiw Z, 1 // увеличим указатель на 1 (z++) mov AL, R0 rcall PutChar tst AL brne __do_output pop AH out SREG, AH ret и будет обеспечиваться атомарность Ну, это другое дело. Но тогда сохранение/восстановление статус-регистра в PutChar не нужно, о чём я и толкую последние две страницы. Кстати, неплохо бы добавить проверку на переполнение буфера в подпрограмме обработки прерываний по приему. UART_RX_ISR так и будет писать по кругу, никаких ограничений у вас нет, возможен скрытый баг. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 23 августа, 2007 Опубликовано 23 августа, 2007 · Жалоба Ну, это другое дело. Но тогда сохранение/восстановление статус-регистра в PutChar не нужно, о чём я и толкую последние две страницы. Нужно! Т.к. PutChar автономная функция, и кроме Print может быть использована где угодно. "Лучше перебдеть чем "недобдеть" ;> Кстати, неплохо бы добавить проверку на переполнение буфера в подпрограмме обработки прерываний по приему. Это так и было задумано.. Практика показывает что для консольных приложений (а пример относился как раз консоли) много лучше допускать опустошение Tx (при переполнении) чем притормаживать CPU ожиданием освобождения места. UART_RX_ISR так и будет писать по кругу, никаких ограничений у вас нет, возможен скрытый баг. RX_ISR в идеале должен работать со входной очередью. Вывод "Эхо" по скорости заполнения не быстрее TX, переполнений по вине RX потока быть не должно. Ну а в случае когда полный overload, то деваться некуда или сбросить TX очередь или ждать окончания TX. Но мы не можем торчать в прерывании и ждать когда освободится место в очереди.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=GM= 0 24 августа, 2007 Опубликовано 24 августа, 2007 · Жалоба Открыл новую тему на предмет написания и использования циклических буферов, показал своё видение предмета. Приглашаю к обсуждению. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться