Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема с ATtiny13
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
simer
ATtiny13.
Генерация звука.
Таймер дергает ногой OC0A. При постоянном значении OCR0A полет нормальный.
Задача стоит в имитации звука сирены, т.е. частота должна плавно повышаться и понижаться.
Но при изменении в цикле

Код
for (i=10; i>0; i--)
{
   OCR0A=3+i;
   delay_ms(20);
}

for (i=0; i<10; i++)
{
   OCR0A=3+i;
   delay_ms(20);
}


наблюдается нестабильность генерации (звук какими-то рывками), по истечении некоторого времени может (но не всегда) произойти "прорыв" на некоторое время, и звук становится нормальным, т.е. плавно понижается и повышается.

Что не так?
singlskv
Цитата(simer @ Jan 29 2008, 11:34) *
наблюдается нестабильность генерации (звук какими-то рывками),
Что не так?

ну Вы бы хоть настройки таймера указали и частоту проца,
телепатить то лень...

Изменять регистр OCRxx в произвольные моменты времени можно не во всех режимах таймера
Ден
Пишете как я погляжу в CodeVision
А если попробовать написать так:
Цитата
for (i=3; i<250; i++)
{
OCR0A=i;
delay_ms(20);
}

for (i=250; i>3; i--)
{
OCR0A=i;
delay_ms(20);
}

так изменение значения регистра OCR0A будет происходить более плавно, почти 250 шагов, а не 10, хотя здесь нужно смотреть как оно все это звучать будет.
simer
Цитата
ну Вы бы хоть настройки таймера указали и частоту проца,
телепатить то лень...


Sorry smile.gif


Chip type : ATtiny13
Clock frequency : 9,600000 MHz

Код
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 9,375 kHz
// Mode: CTC top=OCR0A
// OC0A output: Toggle on compare match
// OC0B output: Disconnected
TCCR0A=0x42;
TCCR0B=0x05;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;



Цитата
Изменять регистр OCRxx в произвольные моменты времени можно не во всех режимах таймера

А где об этом подробнее почитать?

Цитата(Ден @ Jan 29 2008, 11:20) *
Пишете как я погляжу в CodeVision
А если попробовать написать так:

так изменение значения регистра OCR0A будет происходить более плавно, почти 250 шагов, а не 10, хотя здесь нужно смотреть как оно все это звучать будет.


Ну я думаю принципиально не отличается, меня больше волнует нестабильность, чем характер.
singlskv
Цитата(simer @ Jan 29 2008, 12:55) *
А где об этом подробнее почитать?
Об этом всегда читают в даташитах... ну на крайняк в книжках
However, changing TOP to a value close to BOTTOM
when the counter is running with none or a low prescaler value must be done with care
since the CTC mode does not have the double buffering feature. If the new value written
to OCR0A is lower than the current value of TCNT0, the counter will miss the Compare
Match. The counter will then have to count to its maximum value (0xFF) and wrap
around starting at 0x00 before the Compare Match can occur.


Никогда не пишите так: TCCR0A=0x42
Это малоинформативно.
Код
  TCNT0=0x00;
  OCR0A=13;    // !!!!!!!!!!!!!!!!! не нужно оставлять 0, здесь начальное значение TOP
  TCCR0A=((1<<COM0A0)|(1<<WGM01));
  TCCR0B=((1<<CS02)|(1<<CS00));


ваш код для режима CTC можно подправить например так:
Код
for (i=10; i>0; i--)
{
   while (TCNT0>2);
   OCR0A=3+i;
   delay_ms(20);
}

for (i=0; i<10; i++)
{
   while (TCNT>2);
   OCR0A=3+i;
   delay_ms(20);
}


Ну или выбрать другой режим работы таймера...
Nickolya_K
На моей практике:
1. из 2000 контроллеров tiny 13 штук 20 забраковал из=за нестабильности тактового генератора - были какие-то слышимые биения в звуке. По осциллу ничего не видно.
2. Внешняя память (использую сд-карты) бывает медленная - между секторами большая пауза, которая слышна как биение.
=GM=
Цитата(singlskv @ Jan 29 2008, 10:31) *
ваш код для режима CTC можно подправить например так:
Код
for (i=10; i>0; i--)
{
   while (TCNT0>2);
   OCR0A=3+i;
   delay_ms(20);
}

for (i=0; i<10; i++)
{
   while (TCNT>2);
   OCR0A=3+i;
   delay_ms(20);
}

Отличное решение, с достаточно жёстким временным условием, впрочем.

Смягчить условия можно, если следить не за содержимым таймера, а за флагом OCF0A в регистре TIFR0 и менять содержимое OCR0A, когда флаг установлен, ну и не забыть его сбросить после установки. А ещё лучше делать изменения OCR0A в прерывании, тогда процессор будет на 99% свободен.
simer
singlskv, спасибо огромное! все получилось smile.gif

GM,
Цитата
Отличное решение, с достаточно жёстким временным условием, впрочем.

Смягчить условия можно, если следить не за содержимым таймера, а за флагом OCF0A в регистре TIFR0 и менять содержимое OCR0A, когда флаг установлен, ну и не забыть его сбросить после установки. А ещё лучше делать изменения OCR0A в прерывании, тогда процессор будет на 99% свободен.

Как только осмыслю все это, обязательно попробую, спасибо!
=GM=
Цитата(simer @ Jan 29 2008, 14:41) *
GM,
Как только осмыслю все это, обязательно попробую, спасибо!

Да пожалуйста.

Возможно, я употребил не совсем подходящее слово, постараюсь объяснить.
Цитата(=GM= @ Jan 29 2008, 12:55) *
Отличное решение, с достаточно жёстким временным условием, впрочем

Я имел в виду, что у вас OCR0A меняется в цикле 3, 4, 5 и т.д. до 13, а смена OCR0A может происходить только тогда, когда содержимое таймера равно 0 или 1. Всё оставшееся время процессор стоит в цикле while (TCNT0>2); Для OCR0A=4, это будет 2 и 3, т.е. простой в течение 50% времени, для OCR0A>4 будет ещё хуже и в конце цикла дойдёт до 85%. Вот именно это я и имел виду под словами "жёсткое временное условие". Возможно вам этот простой по барабану, я же не знаю вашей конечной задачи, просто обратил ваше внимание.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.