|
|
  |
Вопрос о таймере, остановка процесса по окончанию счета |
|
|
|
Jan 30 2008, 13:21
|
Группа: Новичок
Сообщений: 7
Регистрация: 11-11-07
Пользователь №: 32 231

|
Нужно сделать так, чтобы во время отсчета таймером 0 интервала времени и до его окончания выполнялись некоторые действия, после таймер заново перезагружался. Например, для тестового варианта посылка в UART. UART отдельно работает, проверен. В данном варианте я жду появления флага совпадения OCF0. В результате выполнения получаю только единицы между START и END. А должны быть 16-ть раз поочередно N-единиц и N-нулей. Т.е. while выполняется только первый. Да и выполняется сам код слишком быстро, а должен 8сек работать. Заранее спасибо. Используются: CVavr, mega16. Код #include <mega16.h> #include <stdio.h>
#define F_XTAL 1000000L #define SPEED 2L
void Start_Timer0(void) { TCCR0 = 0b00111101; // CTC OCR0=F_XTAL/2L/1024L/SPEED-1; TIMSK = 0b11; }
void Stop_Timer0(void) { TCCR0=0; }
void send1(void) { while ((TIFR & 0b10)==0) { putsf("1"); }; }
void send0(void) { while ((TIFR & 0b10)==0) { putsf("0"); }; }
void main () { [...] //UART init putsf("\nSTART\n");
Start_Timer0(); for (i=0;i<16;i++) { if ((0x5555&(1<<i))) send1(); else send0(); }; Stop_Timer0();
putsf("\nEND"); }
|
|
|
|
|
Jan 30 2008, 13:54
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(-Alexey- @ Jan 30 2008, 13:21)  Нужно сделать так, чтобы во время отсчета таймером 0 интервала времени и до его окончания выполнялись некоторые действия, после таймер заново перезагружался. В данном варианте я жду появления флага совпадения OCF0. Т.е. while выполняется только первый. Да и выполняется сам код слишком быстро, а должен 8сек работать 1) OCR0 у вас 8-битный, а вы пытаетесь записать туда число 488. 2) После того как OCF0 установится, надо бы его сбросить, а то он всё время будет в 1, невзирая ни на что. 3) Что делает ваша программа после выполнения putsf("\nEND")?
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jan 30 2008, 14:34
|
Группа: Новичок
Сообщений: 7
Регистрация: 11-11-07
Пользователь №: 32 231

|
SasaVitebsk=GM=1) у меня OCR0=243, еще раз пересчитал [1000000/2/1024/2] 2) пробовал писать так TIFR&=(~0b10) после выхода из while, тот же результат 3) конец программы  While(1) мне не нужен (если речь об этом), это только тестовый кусок из моей основной программы, в котором и возникли неполадки. Смысл - только протестировать нужную мне часть кода.
|
|
|
|
|
Jan 30 2008, 15:23
|
Частый гость
 
Группа: Участник
Сообщений: 99
Регистрация: 22-03-07
Из: Novosibirsk
Пользователь №: 26 415

|
Все правильно. Первый send1 будет слать единицы, пока не дождется совпадения. Поскольку OCF0 не сбрасывается, дальше при вызове send0/1 в while мы попадать не будем. Цитата(-Alexey- @ Jan 30 2008, 21:34)  2) пробовал писать так TIFR&=(~0b10) после выхода из while, тот же результат OCF0 сбрасывается единичкой: TIFR = (1<<OCF0);
|
|
|
|
|
Jan 30 2008, 16:19
|
Группа: Новичок
Сообщений: 7
Регистрация: 11-11-07
Пользователь №: 32 231

|
SergeiChда TIFR|=0b10 помогло Благодарю всех за участие, рад что все так просто решилось  Еще с флагами не работал, видимо поэтому и забыл, что у AVR сбрасываются единицей
|
|
|
|
|
Jan 30 2008, 18:03
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Код for (i=0;i<16;i++) { if ((0x5555&(1<<i))) send1(); else send0(); }; Попробуйте так и сравните результирующий листинг Код uint16_t j=1; for (i=0;i<16;i++) { if ((0x5555 & j)) send1(); else send0(); j<<=1; };
|
|
|
|
|
Jan 30 2008, 21:38
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(SasaVitebsk @ Jan 30 2008, 21:03)  if ((0x5555&(1<<i))) send1(); else send0(); if () {} else {} Такие конструкции лучше разбивать на несколько строк: Код if ((0x5555&(1<<i))) send1(); else send0(); будет удобнее отлаживать программу: 1. точку останова можно поставить как на "условие", так и на "действие". 2. при пошаговой отладке будет сразу видно в какую ветку IF'a мы заглянули. да и код становится более наглядным, а значит становится сложнее сделать ошибку и проще найти уже сделанную. PS: мой коментарий направлен больше автору ветки, т.к. уверен SasaVitebsk и так это знает, и он просто скопировал код автора "как есть".
|
|
|
|
|
Jan 30 2008, 21:58
|
Местный
  
Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527

|
Цитата(-Alexey- @ Jan 30 2008, 19:19)  SergeiCh да TIFR|=0b10 помогло Будьте внимательней!!! То что предложил SergeiCh совсем не похоже на то, что у Вас получилось. В Вашем случае сбросятся ВСЕ флаги в TIFR.
Сообщение отредактировал Qwertty - Jan 30 2008, 21:59
|
|
|
|
|
Jan 31 2008, 10:18
|
Группа: Новичок
Сообщений: 7
Регистрация: 11-11-07
Пользователь №: 32 231

|
defunctДа, спасибо, мне тоже нравиться на нескольких строках, но не хотел тут растягивать код Цитата(Qwertty @ Jan 30 2008, 23:58)  Будьте внимательней!!! То что предложил SergeiCh совсем не похоже на то, что у Вас получилось. В Вашем случае сбросятся ВСЕ флаги в TIFR. почему все? поясните, пжлста
|
|
|
|
|
Jan 31 2008, 11:33
|
Частый гость
 
Группа: Участник
Сообщений: 99
Регистрация: 22-03-07
Из: Novosibirsk
Пользователь №: 26 415

|
Цитата(-Alexey- @ Jan 31 2008, 17:18)  почему все? поясните, пжлста TIFR |= 0b10; эквивалентро TIFR = TIFR | 0b10; Поскольку флаги сбрасываются единицами, все установленные флаги и сбросятся
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|