Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вопрос о таймере
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
-Alexey-
Нужно сделать так, чтобы во время отсчета таймером 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");
}
SasaVitebsk
Возьмите в руки калькулятор и посчитайте значение, которое вы пытаетесь присвоить восьмибитному ocr0.
А ещё лучше посмотрите результирующий листинг. Сама программа тоже вызывает некоторые вопросы. Даже задавать боюсь. smile.gif
=GM=
Цитата(-Alexey- @ Jan 30 2008, 13:21) *
Нужно сделать так, чтобы во время отсчета таймером 0 интервала времени и до его окончания выполнялись некоторые действия, после таймер заново перезагружался. В данном варианте я жду появления флага совпадения OCF0.
Т.е. while выполняется только первый. Да и выполняется сам код слишком быстро, а должен 8сек работать

1) OCR0 у вас 8-битный, а вы пытаетесь записать туда число 488.

2) После того как OCF0 установится, надо бы его сбросить, а то он всё время будет в 1, невзирая ни на что.

3) Что делает ваша программа после выполнения putsf("\nEND")?
-Alexey-
SasaVitebsk
=GM=
1) у меня OCR0=243, еще раз пересчитал [1000000/2/1024/2]
2) пробовал писать так TIFR&=(~0b10) после выхода из while, тот же результат
3) конец программы smile.gif While(1) мне не нужен (если речь об этом), это только тестовый кусок из моей основной программы, в котором и возникли неполадки. Смысл - только протестировать нужную мне часть кода.
SergeiCh
Все правильно. Первый send1 будет слать единицы, пока не дождется совпадения. Поскольку OCF0 не сбрасывается, дальше при вызове send0/1 в while мы попадать не будем.

Цитата(-Alexey- @ Jan 30 2008, 21:34) *
2) пробовал писать так TIFR&=(~0b10) после выхода из while, тот же результат

OCF0 сбрасывается единичкой: TIFR = (1<<OCF0);
-Alexey-
SergeiCh
да TIFR|=0b10 помогло
Благодарю всех за участие, рад что все так просто решилось wink.gif
Еще с флагами не работал, видимо поэтому и забыл, что у AVR сбрасываются единицей smile.gif
SasaVitebsk
Код
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;
  };
defunct
Цитата(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 и так это знает, и он просто скопировал код автора "как есть".
Qwertty
Цитата(-Alexey- @ Jan 30 2008, 19:19) *
SergeiCh
да TIFR|=0b10 помогло

Будьте внимательней!!! То что предложил SergeiCh совсем не похоже на то, что у Вас получилось. В Вашем случае сбросятся ВСЕ флаги в TIFR.
-Alexey-
defunct
Да, спасибо, мне тоже нравиться на нескольких строках, но не хотел тут растягивать код

Цитата(Qwertty @ Jan 30 2008, 23:58) *
Будьте внимательней!!! То что предложил SergeiCh совсем не похоже на то, что у Вас получилось. В Вашем случае сбросятся ВСЕ флаги в TIFR.

почему все? поясните, пжлста
SergeiCh
Цитата(-Alexey- @ Jan 31 2008, 17:18) *
почему все? поясните, пжлста

TIFR |= 0b10; эквивалентро TIFR = TIFR | 0b10;
Поскольку флаги сбрасываются единицами, все установленные флаги и сбросятся smile.gif
defunct
Цитата(-Alexey- @ Jan 31 2008, 13:18) *
мне тоже нравиться на нескольких строках, но не хотел тут растягивать код

Чтобы не растягивать код тут можете применять таги [ codebox ] / [ /codebox], вот как это будет выглядеть:

CODE

#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");
}
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.