|
Запись в EEPROM, не работает пример из даташита |
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 21)
|
Jan 11 2008, 21:29
|

Гуру
     
Группа: Свой
Сообщений: 4 363
Регистрация: 13-05-05
Из: Москва
Пользователь №: 4 987

|
Цитата(smk @ Jan 11 2008, 23:48)  Теперь другая непонятная штука. Не выполняется оператор i++; Он просто пропускается симулятором. Почему?
unsigned char i; while (i<240) { while(TIFR1 & (1<<TOV1)) { TCNT1H = 0xF8; TCNT1L = 0x5F; i++; PORTA^=0b00000100; TIFR1 |= (1<<TOV1); } }
Буду благодарен за подсказку. Э-э, а чему равно начальное значение i ? PS. Пропускаться может по такой причине: переменная i у Вас во внутреннем цикле явно не используется, поэтому она была "оптимизирована" компилятором. Не разобрался, сперва для чего нужно i. Для того, чтобы не оптимизилось, операцию нужно сделать volatile.
--------------------
Самонадеянность слепа. Сомнения - спутник разума. (с)
|
|
|
|
|
Jan 11 2008, 21:34
|
Гуру
     
Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446

|
Цитата чему равно начальное значение i ? равно 0. применил volatile - проблема снялась. странно почему заоптимизировал....
--------------------
Живи днем так, чтобы ночью ты спал спокойно.
|
|
|
|
|
Jan 11 2008, 21:46
|

Гуру
     
Группа: Свой
Сообщений: 4 363
Регистрация: 13-05-05
Из: Москва
Пользователь №: 4 987

|
Цитата(smk @ Jan 12 2008, 00:34)  равно 0. Вообще-то, инициализировать нужно обязательно, если это не глобальная переменная. Цитата(smk @ Jan 12 2008, 00:34)  применил volatile - проблема снялась. странно почему заоптимизировал.... Точно. Видимо, оптимизатор за рамки вложенного цикла вылезти не может. Впрочем, здесь я не спец; возможно, старшие товарищи разъяснят. PS. Кстати, лажа у Вас, по-моему, написана...
--------------------
Самонадеянность слепа. Сомнения - спутник разума. (с)
|
|
|
|
|
Jan 11 2008, 22:07
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(smk @ Jan 11 2008, 23:34)  применил volatile - проблема снялась. Главная проблема не снялась - написан мягко говоря непонятный код. Не понятный ни человеку ни тем более компилятору. 1. Даже если переменная i глобальная, то обнулена она будет только при первом проходе. 2. i бесконтрольно и независимо увеличивается во внутреннем цикле. Чем ограничено количество внутренних циклов? 1 - 100 - миллион? Что будет с i при, например, 256 циклах - Вам ведомо? 3. Вы хоть сами сможете словами обьяснить для чего пляски с бубном вокруг i ? 4. Остальное выглядит еще хуже  5. Если после всего этого несчастному симулятору снесет крышу, я не решусь его упрекнуть.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 12 2008, 06:06
|

Частый гость
 
Группа: Участник
Сообщений: 83
Регистрация: 25-10-07
Из: Киев
Пользователь №: 31 728

|
Цитата(smk @ Jan 11 2008, 22:48)  while(TIFR1 & (1<<TOV1)) я бы это заменил на if, так как при первом же проходе устанавливается регистр так, чтобы след. раз условие не выполнялось... и наглядней. Хотя не понятно зачем считывать флаг прерываний вместо того, чтобы использовать само прерывание. Можно либо разрешить прерывание по переполнению и в нем выполнять TCNT1H = 0xF8; TCNT1L = 0x5F; i++; PORTA^=0b00000100; где i должна быть глобальной либо запустить режим сброса таймера по сравнению (CTC mode), чтобы он считал от 0 до сравнения (например до OCR1A=0xFFFF - 0xF85F=0x7A0), затем в прерывании по сравнению делать тоже кроме обновления счетчика.
Сообщение отредактировал Gogan - Jan 12 2008, 06:07
|
|
|
|
|
Jan 12 2008, 08:23
|
Гуру
     
Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446

|
Цитата 1. Даже если переменная i глобальная, то обнулена она будет только при первом проходе. да, она глобальная. пользую везде где нужен счетчик. Цитата 2. i бесконтрольно и независимо увеличивается во внутреннем цикле. Чем ограничено количество внутренних циклов? 1 - 100 - миллион? Что будет с i при, например, 256 циклах - Вам ведомо? Программа жздет появление флага переполнения таймера, while(TIFR1 & (1<<TOV1)) выполняет предустановку { выполняет предустановку TCNT1H = 0xF8; TCNT1L = 0x5F; наращивает счетчик i++; делает что-то полезное PORTA^=0b00000100; сбрасывает флаг TIFR1 |= (1<<TOV1); } и так до очередного выброса флага... когда i=240 - программа выходит из внешнего цикла. прерывания не использовал т.к. нет нужды делать чего-то во время ожидания. Цитата запустить режим сброса таймера по сравнению (CTC mode) так и есть, режим СТС. ну мне так видится, а как бы вы написали? я учусь и мне юудет интересно посмотреть на иные решения. Заранее спасибо. Цитата 4. Остальное выглядит еще хуже все может быть... а как правильнее? Цитата 3. Вы хоть сами сможете словами обьяснить для чего пляски с бубном вокруг i ? попробую... суть в том, что мне нужно отмерять промежутки времени, кратные 1 с, сигнализируя об их течении мигающим светодиодом или выполняя какие-либо действия в иные промежутки: промежуток 1 - действие 1; промежуток 2 - действие 2; . . . промежуток N - действие N. а так лучше? while((TIFR1 & (1<<TOV1))&(i<240)) { TCNT1H = 0xF8; TCNT1L = 0x5F; i++; PORTA^=0b00000100; TIFR1 |= (1<<TOV1); }
Сообщение отредактировал smk - Jan 12 2008, 07:52
--------------------
Живи днем так, чтобы ночью ты спал спокойно.
|
|
|
|
|
Jan 12 2008, 09:58
|

Частый гость
 
Группа: Участник
Сообщений: 83
Регистрация: 25-10-07
Из: Киев
Пользователь №: 31 728

|
Цитата(smk @ Jan 12 2008, 10:23)  а так лучше?
while((TIFR1 & (1<<TOV1))&(i<240)) Тут ошибка, нужно while((TIFR1 & (1<<TOV1))&&(i<240)) (второе И логическое а не побитное) Вобщем, если ничего более выполнять не нужно, либо оно выполняется в других прерываниях, тогда ваш вариант решения сойдет, да и проще чем через прерывания.
Сообщение отредактировал Gogan - Jan 12 2008, 09:58
|
|
|
|
|
Jan 12 2008, 10:13
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(smk @ Jan 12 2008, 10:23)  да, она глобальная. пользую везде где нужен счетчик. И очень напрасно. Если бы вы заводили ее каждый раз локально, компилятор мог бы, во-первых, разместить ее в регистре (что очень хорошо как для скорости, так и для размера) и, во-вторых, не сохранять ее значение после окончания цикла (оно ведь вам не нужно). По циклу - лучше переменную увеличивать прямо в месте проверки или сразу перед ним - тогда компилятор сможет для проверки воспользоваться флагами, остающимися от операции инкремента. Еще с точки зрения эффективности лучше инициализировать i числом и потом уменьшать, проверяя на ноль.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 12 2008, 10:42
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Это BLINKS раз моргнет светодиодиком используя опрос флага переполнения таймера. Код #define BLINKS 120 #define BIT_MY_LED (1<<2) #define T1_DIV 0xF85F
for( uint_least8_t i = (BLINKS)<<1;; ) { if( TIFR1 & (1<<TOV1) ) ) { TCNT1H = (unsigned char)((T1_DIV)>>8); TCNT1L = (unsigned char)T1_DIV; PORTA ^= BIT_MY_LED; TIFR1 |= (1<<TOV1); // Уверены, что сбрасывается '1' а не нулем? if( !--i ) break; } } Если честно, то я из тестового описания не уверен, что понял. Проблема Вашего описаня в том, что Вы задачу так ине сформулировали. Задача, например, - выкопать канаву. Вместо этого Вы попыталтсь рассказать как Вы держите лопату и как далеко кидаете землю и прочее.... Понято, что что-то хотите выкопать, но что уже не совсем понятно
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 12 2008, 15:58
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(smk @ Jan 12 2008, 17:44)  ../1.c:157: error: 'for' loop initial declaration used outside C99 mode Переключите компилятор в режим следования свежему 1999 года стандарту языка "C". Если вдруг найдутся неведомые мне причины не использовать современные компиляторы, то тогда так: Код { uint_least8_t i = (BLINKS)<<1; for(;; ) { ...... } } Цитата а вообще не уверен что аналог... Договаривайте.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 12 2008, 17:21
|
Гуру
     
Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446

|
Цитата Переключите компилятор в режим следования свежему 1999 года стандарту языка "C". не могу разобраться как... пробовал в makefile, но не дает. в makefile из директории WinAVR установлен режим gnu99. а есть ли возможность из AVR Studio изменить этот режим? gnu99 gnu9x The 1999 C standard plus GNU extensions. вот такое сейчас включено. если я не ошибаюсь, по умолчанию всегда так у WinAVR.
--------------------
Живи днем так, чтобы ночью ты спал спокойно.
|
|
|
|
|
Jan 12 2008, 17:23
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(smk @ Jan 12 2008, 18:57)  но не дает.... Что такое "не дает" мне не ведомо, но найдите, где можно добавить ключи для командной строки относящиеся ко всему проекту и допишите туда: -std=c99 или -std=gnu99 Цитата(smk @ Jan 12 2008, 19:21)  если я не ошибаюсь, по умолчанию всегда так у WinAVR. без понятия, разнообразными IDE не пользуюсь в принципе.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 12 2008, 18:25
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(smk @ Jan 12 2008, 20:21)  А чем i = (BLINKS<<1); лучше i=240? 240 это какое-то число, а BLINKS это осмысленное количество морганий. На код, естественно, совершенно не повлияет, но ошибиться задав нечтное число - нельзя, читать и потом сопровождать - удобнее.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 12 2008, 18:56
|
Гуру
     
Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446

|
Цитата BLINKS это осмысленное количество морганий Спасибо за идею! тогда уже i = (BLINKS<<2); - длительность включения нагрузки в секундах. это точно лучше. А количество морганий - главное чтоб не нудно мограло, а живенько более-менее.
--------------------
Живи днем так, чтобы ночью ты спал спокойно.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|