Перейти к содержанию
    

DenisIV

Свой
  • Постов

    67
  • Зарегистрирован

  • Посещение

Весь контент DenisIV


  1. К сожалению из опыта.(Я раньше писал только на асм, там извращался как мог...) А насчёт цикла 1/32768 вы пожалуй правы. Иначе sleep не действует, а сразу выполняется обработчик TMR2 несколько раз... Самое интересное, что я жду пока в регистре ASSR младшие 3 бита будут равны 0, но почему-то это не помогает... Да, делитель у меня на TMR2 на 128. (счётчик на 256*делитель 128=32768). На осциле вижу импульсы(тест. ножку сделал) примерно 3-4 штуки по 12 микросекунд. это обработка TMR2+sleep. Как бы не получить время 1/32768*128=3.9ms Это будет катастрофа :(
  2. Именно TMR2, т.к. проц выключает свой тактовый генератор. Проблема в другом: именно в прерывании если просто выполнить sleep, проц от TMR2 не проснётся-прерывания-то выключены при входе в обработчик TMR1. А если их включить, то возможен бесконечный цикл/переполнение стека с TMR1. Вот я и думаю, что что-то здесь не так... Может остановить TMR1 и включить прерывания? А в sleep нужно уходить максимально быстро...
  3. Собственно, есть проект на Mega169. Тактовая внутренняя 8М, 2 прерывания: 1. Таймер 1 (~1000Hz) - опрос клавиатуры, индикатора и т.д. 2. Таймер 2 (RTC, кварц32768) - раз в секунду считается время. вот в 1-м таймере опрашивается датчик внешнего напряжения, его дребезг и т.д. и через некоторое время необходимо проц усыпить, дабы он не скушал слабенький аккум (~20mah,4.8v) Но просыпаться раз в 1 сек от таймера 2 и, добавив секунду снова уснуть(если питание не появилось)... Может кто сталкивался с такими задачами? Собственно интересует правильный процесс перехода в спячку, просыпание и снова спячка... т.е. необходимо ли разрешить прерывания и не сбрасывать флаг для TMR1 что бы проснулся от TMR2? но как я понимаю, флаг сбрасывается при входе в прерывание, значит его нужно ручками установить?
  4. Народ, это действительно засада или лыжи не едут... ?
  5. Подскажите ещё плиз: У меня на асме для оптимизации была такая конструкция подпрограммы с несколькими точками входа. Например: здоровенная подпрограмма, которой передаётся байт для обработки (~100 вызовов) и вызов этой же подпрограммы с вполне конкретным значением (3-4 варианта по ~40 вызовов) Как можно это применить в С? Как программист C я понимаю, что вызов функции, которая будет содержать константу для этой функции подойдёт, но для PIC (8 уровней стека :( ) не прокатит... Есть какая-нибудь альтернатива? Дополнительный параметр в функции передавать не хочу- в экономии смысла не будет, скорее наоборот. Глобальная переменная-как вариант, но не выход... Есть возможность вызвать функцию с какой-либо метки внутри, или это совсем глупо? Или есть варианты? Или это должен делать и считать оптимизатор?
  6. Ну я бы так не сказал: если в for(;;) нет условия, это может быть ошибкой, а for(;1;) тоже, что и while(1) и раз уж так, то while() { .... } должно работать так же как и for(;;) ? Т.е. в for не надо вставлять условие ??? а в while надо ??? Правильным будет всегда с условием. Это точно не противоречит стандарту С. А то, что как вы сказали "оптимизирующий компилятор знакомый с русским фольклором" - это скорее исключение, а не правило. Поэтому и обидно... :( Если я буду всем советовать for(;;) то это не будет правильно. Что for(;;) что while() - Варнинги обеспечены по любому. А хотелось бы писать правильно. И запись for(;1;) будет правильней.
  7. А есть разница? :) while(1) { .... } По-моему нет. В справке к Hi-Tech C они предлагают для бесконечного цикла for(;;) { .... } При каком-то кол-ве циклов внутри цикла for{ for { for { for {}}}} компилятор вешается поэтому приходится комбинировать for... while... if... и т.д. В IAR пока не смотрел. Вроде таких проблем не было.
  8. Зачем так грубо? Квалификации в области asm более чем достаточно. Была в 90-х годах версия АОН "Полесье" - знакомьтесь : я её автор. С я изучаю не так давно, а слова компилёр, программер, винт флэшка, скомпилять, отформатить являются слэнгом и не говорят о том, что человек чего-то не знает или не уважает. Например, если человек приходит в аптеку и просит резинку, ему дадут не жвачку. Они знают что это. Просто если иногда кому-то режет слух, скажите прямо об этом. Хотя у меня эта работа совмещена с хобби и поэтому я не раздражаюсь, если так говорят. Я раздражаюсь, если народ не представляет себе, о чём говорит. Например : - Я такой крутой программист, могу для ПК написать чё хошь! - Напиши, мне нужен генератор например 1 кГц на н-ной ножке LPT порта. - Легко! Потом берём осциллограф и смотрим : Вау, откуда взялся джиттер ? - Кричит, что щас исправит... Пытается... Не получается... Винда доступ не даёт... Драйвер свой писать надо... - А под ДОСом сможешь? - А как под дос написать? Итого мы видим, что человек учился с 1 по 10 класс, пропустил 2 и 3 классы. И этой базы у него нет. И он не представляет себе аппаратную часть ПК. А как можно написать программу, не зная схемы? Настоящий программист должен и в схемах рубить и с паяльником уметь!
  9. Могут... И будут правы: функция delay вызывается 7 раз из 8... (эт плохо...) А for заменяется while... Походу некоторые компилёры требуют конкретной операции внутри скобок for, а то (условие)?[тело true]:[тело false] - эт ж if(условие)[тело true]else[тело false] и их и тошнит... 2moderator:А может эти вышеперечисленные весчи собирать и в какую-ндь тему отдельно выделенную закидывать? ('Перед тем, как задать вопрос по С/C++, ознакомтесь...') А там и возможность замены ?/if, for/while, volatile, #pragma, и базовые вопросы/вырезки сообщений и т.д. Так сказать, перед тем, как наступить на грабли, прочитайте... Или в поиск... А если нет-то к нам... ?
  10. Ещё глотнул пива... Ведь оператор for работает так: for([первая инструкция];[условие выполнения];[инструкция после тела]) [тело] и его можно заменить на: [первая инструкция] while ([условие выполнения]) { [тело] [инструкция после тела] } итого мы можем: (Direction)? mask=1<<0:mask=1<<7; while(mask) { PORTx=(*byte&mask)? PORTx|(1<<BIT):PORTx&~(1<<BIT); delay_us(x); (Direction)? mask<<=1:mask>>1) } Или не можем? По-моему это абсолютно идентичные логически и т.д. конструкции... Гуру, если не прав, поправьте...
  11. Проходит,ошибок нет, вот по этому и спрашиваю, как обойти... Варнинги достали (>100) :( Мож #pragma optimize =none ? Ток я не знаю, как потом включить и будут ли варнинги дальше? А у меня варнинг-указание на засаду в проге. Игнорировать и отключать не хочется... Потом можно 3 дня глюк ловить... И не поймать... :(
  12. Попробуйте разделить все три прцедуры на строчки и поймёте где трабл. Да, не нравятся ему аргументы, но в какой позиции строки он не написал. Кстати, посмотрите, byte может у вас определено ранее #defin'ом как unsigned char? Может просто имя переменной поменять? Ксати, глотнул пива, идея пришла: А не прокатит ли такая конструкция: for ((Direction)? mask=1<<0:mask=1<<7;mask;(Direction)? mask<<=1:mask>>1) {PORTx=(*byte&mask)? PORTx|(1<<BIT):PORTx&~(1<<BIT);delay_us(x);} Сюда даже вместо 7 (в 'for') можно как-то подставить sizeof(); (хоть в байтах*8-1,хоть в битах-1) ? Тогда прога будет просто супер универсальной! (Я даже себе в библию программиста запишу ) И если Direction задано через union...struct... как бит, то налицо ещё и прямая экономия места... ?
  13. Ещё вопросик: Например, компилятор HiTech предупреждает при: while(1) { .... } while(1) { .... } типа warning: infinity loop, а вот ИАР не предупреждает, а молча делает... :) Но это лирика... У меня (в данном случае ИАР) ругается на переменные, когда я их обзываю volatile на то, что он не может просчитать их значение, т.к. не проинициализированы. А инитить я их не хочу, т.к. эти переменные лежат в озу и должны быть валидны и просле ресета (я их инициализю отдельно, считая их CRC или анализируя флаг сброса по питанию) Вот тут и грабли... (Опять повторю, прогу полностью переписать не cмогу(высшая математика), исправляю за самоучками :( )
  14. Не знаю, помню когда сдвиг вправо у меня компилёр ошибался и иногда задвигал в старший бит '1', а влево - всегда '0' (Или это был кольцевой сдвиг?) (Или это был глючный компилёр?) (Или тип переменной был signed?) Не сталкивались?
  15. Согласен. Но в данном случае вы неправы. Бывают разные ситуации. Я, например в данном случае пытаюсь добиться результатов после дилетанта-программиста. Возможности переписать ВСЮ прогу просто нет, отключаю оптимизацию=прога не влазит в кристалл. Программист в прерываниях использует почти все модули и я исправляю ошибки доступа, что бы основная прога не вешалась. Так что в данном случае мой вопрос правилен. Лично я пишу, правильно разбивая ресурсы/переменные и лично у меня проблем с оптимизацией не было. Просто исправлять за кем-то - неблагодарное и трудное занятие. Но необходимое (в моём случае)
  16. Спасибо. Это как раз и было нужно. А опять включить ? Или можно поменять степень оптимизации на ходу?
  17. Есть правда в словах... А если сделать вращение (что бы сохранить значение переменной), автор, я думаю, будет доволен... for(i=0;i<8;i++) { if (InByte & 0x01) {PortX.Y=1;InByte=((InByte>>1) | 0x80);} else {PortX.Y=0;InByte=((InByte>>1) & 0x7F);} delay_ms(x); } // сдвиг вправо for(i=0;i<8;i++) { if (InByte & 0x80) {PortX.Y=1;InByte=((InByte<<1) | 0x01);} else {PortX.Y=0;InByte=((InByte<<1) & 0xFE);} delay_ms(x); } // сдвиг влево Я возможно сделал чуть неоптимально, но на скорость и сохранность переменной это повлияет в лучшую сторону. Поправьте прогу чуть для своего удобства и вуаля! От модератора. Учитесь самостоятельно оформлять сообщения с помощью тэгов. Для оформления исходников служат тэги code (кнопка в редакторе сообщений) для небольших фрагментов и codebox (для бОльших текстов исходников).
  18. Согласен. А есть ли возможность указать компилятору в данном конкретном примере какой-нибудь командой #cmdxxx НЕ ОПТИМИЗИРОВАТЬ например именно строчку где a=2; ?
  19. Каждый модуль независим для компилятора и компилёр оптимизирует не проект, а данный модуль и если я в одном модуле только читаю а в другом только пишу переменную, то в обоих случаях если я не допишу volatile компилёр просто выкинет эти строки (просто примет за константу данные при компиляции) Вот в этом и грабли. Всё могло быть хорошо, если модуль один. (Вроде бы)
  20. Обычно (насколько я понимаю) у вас кусочек программы, похожей на RS232 передачу (разница в том, что обычно для 232 не хватает еще 2-х бит:Start и Stop) Дело не в том, убивать ли значение переменной или нет, дело в оптимальности далее полученного кода. А переменную можно и сохранить/восстановить. А можно и отдельную функцию сделать, которой сообщается эти 8 бит(байт) и может быть абсолютно всё равно, какие данные перед выходом из функции в этой переменной. Если не менять переменную, может быть и так: for (i=0;i<8;i++) { if (InByte&(1<<i)) {PortX.Y=1;} else {PortX.Y=0;} delay_ms(x); } Тут переменная не меняется. Но код по времени не будет точен(сдвигов 1<<i будет от 0 до 7) и между 1-м выводом в порт и 8-м будет разное время. Системы, чувствительные к длине периода могут дать ошибку. Хотя всё относительно... Если импульс идёт раз в секунду, то лишние 100 тактов наплевать. А если раз в 20-30 тактов-то можно сказать что это мёртвая затея. Там пройдёт только предыдущая затея (счётчик>вывод>сдвиг на 1>задержка) Но решать по какому пути идти-Вам. Это далеко не все.
  21. 2rezident: со static (и не тоько) разобрался, спасибо! Ещё вопросик... Насколько я понимаю, у меня эти проблемы с оптимизацией начались после того, как у меня образовалось более одного модуля, т.е. каждый модуль независим для компилятора и компилёр оптимизирует не проект, а данный модуль и если я в одном модуле только читаю а в другом только пишу переменную, то в обоих случаях если я не допишу volatile компилёр просто выкинет эти строки (просто примет за константу данные при компиляции), а с линкера не спросишь-он просто склеит готовые блоки. Опять же, если будет это всё в одном файле/модуле, то даже при макс. оптимизации компилёр может понять, что переменная юзается внутри в разных функциях (в т.ч и в прерываниях) и не будет оптимизировать до упора? Т.е. в данном случае не нужен тип global/static/volatile ? (модуль-то один, global итак будет автоматом, вопрос только про оптимизатор) Да, самое интересное: Я объявляю в модуле main глобальные переменные, в остальных модулях их же, но через extern, т.е. получается, что глобально в пределах проекта, но вот эта заноза-оптимизатор видит только в пределах модуля переменную (в смысле её использования), а не в пределах проекта? Или есть тонкости? Объясните плиз, где грабли... Крыша уже течёт... Просто я не умею их готовить... (с) какая-то реклама Чем-то чувствую, что и прав и нет. Хотелось бы понять, где. Я понимаю, RTFM, но всё же... F1 ! То, что люди задают глупые вопросы не означает, что они глупы, просто иногда не хватает опыта... Сорри, если чуть оффтоп... ;)
  22. Прошу простить... Это как допустим чья-то жена получила вчера права, начинает спрашивать мужа: "Как там решить вопрос с ГАИшниками, если..." Муж: "Я ж те говорил, книжки покупал..." На сколько я знаю, volatile говорит компилятору о том, что все связанные с переменной действия ни в коем случае не оптимизировать. Вопрос для многозадачных или "мощных" систем вроде выглядит по другому: требуется ещё лочить переменную на время обработки данных(например в прерывании меняется массив данных и указатели на него а основная прога может вылететь) И если можно про static. Просветите плиз тонкости... Может быть еще раз... Ну "я месяц назад получил права" :)
  23. Не согласен. Вы забыли про прерывания? Вот они и меняют этот бит. Может компилёру нужно дополнительно сообщить, что этот бит ещё где-то может модифицироваться? Вопрос, как... P.S. Я с асмом дружу очень, но большие модули переписываю на С, потому что надоело при смене типа мк в пределах одного изготовителя приходится сильно менять исходник, а при смене Z80<>PIC<>Holtek<>AVR<>msp430<>PC<>mcs48<>mcs51 и т.д. просто волосы дыбом встают... Поэтому и прошу помощи... Как было указано в начале темы, мож у мя глюки? 2Moderator: Может мне создать отдельную тему? Но я её хотел назвать именно так, как назвал автор:)
  24. Кстати, раз уж о глюках: У меня при включенной оптимизации компилятор думает, что раз тела у while нет, то можно и зациклить сам на себя БЕЗ проверки условия, т.е. MojBit=1; while(MojBit==1) { }; в асме выглядит так: Addr: rjmp Addr Если в тело хотя бы вставить _NOP(); т.е. while(MojBit==1) {_NOP();}; картина меняется - добавляется загрузка вита в 1 и проверка в теле while. Вопрос знатокам: Почему? Компилятор умнее пользователя? Модератор. Тема выделена как отдельная из другого топика.
  25. Я конечно закину, но может кто сможет выложить прямо здесь этот файл? У меня не получилось его приаттачить... Или залить как-то по другому на рапиду или ещё куда... Так мы по 10 раз замучаемся скачивать... хттп://rapidshare.com/files/175154922/HCPICP-pro-9.60PL4.3452.zip.html
×
×
  • Создать...