реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Вопрос о таймере, остановка процесса по окончанию счета
-Alexey-
сообщение Jan 30 2008, 13:21
Сообщение #1





Группа: Новичок
Сообщений: 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");
}
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jan 30 2008, 13:53
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Возьмите в руки калькулятор и посчитайте значение, которое вы пытаетесь присвоить восьмибитному ocr0.
А ещё лучше посмотрите результирующий листинг. Сама программа тоже вызывает некоторые вопросы. Даже задавать боюсь. smile.gif
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jan 30 2008, 13:54
Сообщение #3


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")?


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
-Alexey-
сообщение Jan 30 2008, 14:34
Сообщение #4





Группа: Новичок
Сообщений: 7
Регистрация: 11-11-07
Пользователь №: 32 231



SasaVitebsk
=GM=
1) у меня OCR0=243, еще раз пересчитал [1000000/2/1024/2]
2) пробовал писать так TIFR&=(~0b10) после выхода из while, тот же результат
3) конец программы smile.gif While(1) мне не нужен (если речь об этом), это только тестовый кусок из моей основной программы, в котором и возникли неполадки. Смысл - только протестировать нужную мне часть кода.
Go to the top of the page
 
+Quote Post
SergeiCh
сообщение Jan 30 2008, 15:23
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 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);
Go to the top of the page
 
+Quote Post
-Alexey-
сообщение Jan 30 2008, 16:19
Сообщение #6





Группа: Новичок
Сообщений: 7
Регистрация: 11-11-07
Пользователь №: 32 231



SergeiCh
да TIFR|=0b10 помогло
Благодарю всех за участие, рад что все так просто решилось wink.gif
Еще с флагами не работал, видимо поэтому и забыл, что у AVR сбрасываются единицей smile.gif
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jan 30 2008, 18:03
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 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;
  };
Go to the top of the page
 
+Quote Post
defunct
сообщение Jan 30 2008, 21:38
Сообщение #8


кекс
******

Группа: Свой
Сообщений: 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 и так это знает, и он просто скопировал код автора "как есть".
Go to the top of the page
 
+Quote Post
Qwertty
сообщение Jan 30 2008, 21:58
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527



Цитата(-Alexey- @ Jan 30 2008, 19:19) *
SergeiCh
да TIFR|=0b10 помогло

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

Сообщение отредактировал Qwertty - Jan 30 2008, 21:59
Go to the top of the page
 
+Quote Post
-Alexey-
сообщение Jan 31 2008, 10:18
Сообщение #10





Группа: Новичок
Сообщений: 7
Регистрация: 11-11-07
Пользователь №: 32 231



defunct
Да, спасибо, мне тоже нравиться на нескольких строках, но не хотел тут растягивать код

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

почему все? поясните, пжлста
Go to the top of the page
 
+Quote Post
SergeiCh
сообщение Jan 31 2008, 11:33
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 99
Регистрация: 22-03-07
Из: Novosibirsk
Пользователь №: 26 415



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

TIFR |= 0b10; эквивалентро TIFR = TIFR | 0b10;
Поскольку флаги сбрасываются единицами, все установленные флаги и сбросятся smile.gif
Go to the top of the page
 
+Quote Post
defunct
сообщение Jan 31 2008, 11:34
Сообщение #12


кекс
******

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



Цитата(-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");
}
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 16th July 2025 - 12:05
Рейтинг@Mail.ru


Страница сгенерированна за 0.01978 секунд с 7
ELECTRONIX ©2004-2016