|
|
  |
Проблема с ATtiny13, срыв генерации |
|
|
|
Jan 29 2008, 08:34
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 22-01-08
Пользователь №: 34 312

|
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); } наблюдается нестабильность генерации (звук какими-то рывками), по истечении некоторого времени может (но не всегда) произойти "прорыв" на некоторое время, и звук становится нормальным, т.е. плавно понижается и повышается. Что не так?
|
|
|
|
|
Jan 29 2008, 09:20
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(simer @ Jan 29 2008, 11:34)  наблюдается нестабильность генерации (звук какими-то рывками), Что не так? ну Вы бы хоть настройки таймера указали и частоту проца, телепатить то лень... Изменять регистр OCRxx в произвольные моменты времени можно не во всех режимах таймера
|
|
|
|
|
Jan 29 2008, 09:20
|

Частый гость
 
Группа: Свой
Сообщений: 128
Регистрация: 21-06-07
Из: Омск
Пользователь №: 28 594

|
Пишете как я погляжу в 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, хотя здесь нужно смотреть как оно все это звучать будет.
|
|
|
|
|
Jan 29 2008, 09:55
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 22-01-08
Пользователь №: 34 312

|
Цитата ну Вы бы хоть настройки таймера указали и частоту проца, телепатить то лень... Sorry  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, хотя здесь нужно смотреть как оно все это звучать будет. Ну я думаю принципиально не отличается, меня больше волнует нестабильность, чем характер.
Сообщение отредактировал simer - Jan 29 2008, 09:54
|
|
|
|
|
Jan 29 2008, 10:31
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(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); } Ну или выбрать другой режим работы таймера...
|
|
|
|
|
Jan 29 2008, 12:50
|
Группа: Новичок
Сообщений: 12
Регистрация: 22-08-07
Пользователь №: 29 981

|
На моей практике: 1. из 2000 контроллеров tiny 13 штук 20 забраковал из=за нестабильности тактового генератора - были какие-то слышимые биения в звуке. По осциллу ничего не видно. 2. Внешняя память (использую сд-карты) бывает медленная - между секторами большая пауза, которая слышна как биение.
|
|
|
|
|
Jan 29 2008, 12:55
|

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

|
Цитата(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% свободен.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jan 29 2008, 14:41
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 22-01-08
Пользователь №: 34 312

|
singlskv, спасибо огромное! все получилось GM, Цитата Отличное решение, с достаточно жёстким временным условием, впрочем.
Смягчить условия можно, если следить не за содержимым таймера, а за флагом OCF0A в регистре TIFR0 и менять содержимое OCR0A, когда флаг установлен, ну и не забыть его сбросить после установки. А ещё лучше делать изменения OCR0A в прерывании, тогда процессор будет на 99% свободен. Как только осмыслю все это, обязательно попробую, спасибо!
Сообщение отредактировал simer - Jan 29 2008, 14:42
|
|
|
|
|
Jan 29 2008, 15:24
|

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

|
Цитата(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%. Вот именно это я и имел виду под словами "жёсткое временное условие". Возможно вам этот простой по барабану, я же не знаю вашей конечной задачи, просто обратил ваше внимание.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|