Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

Atmega8, Таймер, Промяна на честотата - Проблем
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=9869
Страница 1 от 1

Автор:  klez [ Пет Фев 10, 2012 11:17 pm ]
Заглавие:  Atmega8, Таймер, Промяна на честотата - Проблем

Здравейте, боря тука един таймер от 2 дни.
използвам го за генериране на правоъгълни импулси с променяща се честота (за генериране на звук през пиезо зумер)

Ползвам таймера в чисто хардуерен режим. Кода ми е следният:

Код:
TCCR1B |= (1<<WGM12); //Set mode to CTC
TCCR1A |= (1<<COM1A0) | (1<<COM1B0); //Enable timer1 compare output channel A&B in TogglMode   

timer1_setfreq(int freq) { // Функция за променяне на честотата
   int newfreq=0;
   freq*=2; //increase frequency *2 because we use Timer1 in Toggle mode, 2 toggles = 1 impulse
   newfreq= F_CPU/timer1_clockFrequency/freq; // The value for the number of cycles before toggle is calculated
   OCR1A=newfreq;
} // Задавам стойност на OCR1A регистъра. Когато таймера достигне стойността на този регистър в CTC Toggle режим,
таймера се нулира, стойността на съответния изходен пин на микроконтролера се променя и почва да брои от начало.



Проблема е следният.

Със този код пробвам да променям честотата плавно от 500Hz до 1500Hz:
Код:
   int i;
   for (i=500;i<=1500;i++) {
   timer1_setfreq(i);
   _delay_ms(2);
   }

Всичко окей, само че докато плавно се увеличава честотата на звука, на моменти има едно прекъсване...
Ако махна _delay_ms(2) доста повече пъти се появява това прекъсване на звука, ако сложа 15 милисекунди изчезва.

Доколкото ми е ясно, най вероятно се дължи на това, че просто функцията за промяна на честотата се опитва да пише в OCR1A регистъра в неподходящият момент, когато примерно таймера чете от него или нещо от сорта.

Мислех да сложа едно while(всичко е наред);
Преди онзи ред който пише стойност на OCR1A регистъра.
Ама не се сещам самото условие какво да е... Дали да е когато TCNT1 (стойността на брояча на таймера) е примерно между някакви стойности... или и аз не знам какво точно.
Някой има ли идеи, надявам се да съм обяснил разбираемо за какво иде реч.

Автор:  Dimitar [ Пет Фев 10, 2012 11:34 pm ]
Заглавие:  Re: Atmega8, Таймер, Промяна на честотата - Проблем

Сега не се сещам как е точно в мегите, но генерално когато таймера стигне определената стойност в компаратора би трябвало да се вдига някакъв флаг, за да ти генерира прекъсване (ако то е разрешено де). Та сложи в while проверка за тоя флаг и като се вдигне тогава зареждай новата стойност и после да не забравиш да го нулираш. Предполагам, че най-вероятно е от това, защото като променяш стойността в движение и най-вероятно се получава нещо като модулация на изхода, което пък се изразява в пукане.

Автор:  klez [ Съб Фев 11, 2012 12:35 am ]
Заглавие:  Re: Atmega8, Таймер, Промяна на честотата - Проблем

Код:
   while (!(TIFR&0b00001000));
   OCR1A=newfreq;
   TIFR |= (1<<OCF1A);


Пробвах така да сложа... маската TIFR&0b00001000 ми проверя само дали съответният флаг е Вдигнат, ако е 1, с NOT става 0 и цикъла прекъсва,
а програмата продължава към следващата стъпка, след което изчиства флага (при атмегата флага се изчиства като запишеш 1-ца на негово място)

Ама пак си прекъсва, разместват се прекъсванията на други места но пак ги има

Автор:  klez [ Съб Фев 11, 2012 1:06 am ]
Заглавие:  Re: Atmega8, Таймер, Промяна на честотата - Проблем

Сложих го така:
Код:
while (!((TCNT1<100)&(TCNT1>10)));


Сега ако има поне 2 милисекунди между двете смени, работи без прекъсване. Те като цяло мисля че ще имам поне по 2 милисекунди между отделните смени така че е окей вече

Автор:  Dimitar [ Съб Фев 11, 2012 1:12 am ]
Заглавие:  Re: Atmega8, Таймер, Промяна на честотата - Проблем

Явно е някакъв ефект от скоростта, с която се променя честота. В какъв обхват я променяш тая честота?

Автор:  TheHungry [ Съб Фев 11, 2012 1:16 am ]
Заглавие:  Re: Atmega8, Таймер, Промяна на честотата - Проблем

Пробвай така


unsigned int TV;


TV = (unsigned long) 250000 / (unsigned long) freq;

if ( OCR1A != TV )
{
TCNT1 = 0;
OCR1A = TV;
}

при мен така работи

Автор:  klez [ Съб Фев 11, 2012 1:04 pm ]
Заглавие:  Re: Atmega8, Таймер, Промяна на честотата - Проблем

Митко най вероятно наистина прекалено бързо се опитвам да я променям.

TheHungry, мерси ще го пробвам. Това няма ли, при OCR1A=TV изобщо да пропусне да промени честотата?

Автор:  TheHungry [ Съб Фев 11, 2012 7:13 pm ]
Заглавие:  Re: Atmega8, Таймер, Промяна на честотата - Проблем

klez написа:
Митко най вероятно наистина прекалено бързо се опитвам да я променям.

TheHungry, мерси ще го пробвам. Това няма ли, при OCR1A=TV изобщо да пропусне да промени честотата?



То това е идеята ....

Автор:  Реконструктор [ Съб Фев 11, 2012 10:53 pm ]
Заглавие:  Re: Atmega8, Таймер, Промяна на честотата - Проблем

Трябва да сменяш стойността на сравняващия регистър и да зануляваш таймера след завършване на таймерния цикъл. В противен случай просто опресняваш преди да е достигнал стойност, при която се случва нещо.

Автор:  klez [ Съб Фев 11, 2012 11:05 pm ]
Заглавие:  Re: Atmega8, Таймер, Промяна на честотата - Проблем

Мисля че открих проблема..... просто един цикъл на таймера ако нямам _delay_ функция е по-дълъг отколкото няколко смени на променливата, сега като сменям честотата през повече от 2 милисекунди е окей, а мен реално ще ми трябва през 100-200 милисекунди да я сменям най-малко така че за момента ме устройва.

Автор:  marcuka68 [ Чет Фев 16, 2012 2:26 pm ]
Заглавие:  Re: Atmega8, Таймер, Промяна на честотата - Проблем

Тази ситуация, мисля, че е описана тук, в документацията (четох дейташийта на друга АТмега, но таимерите не им се различават, струва ми се).

Прикачени файлове:
Timer 1 CTC mode.JPG
Timer 1 CTC mode.JPG [ 156.1 KiB | Прегледано 2176 пъти ]

Автор:  klez [ Чет Фев 16, 2012 3:02 pm ]
Заглавие:  Re: Atmega8, Таймер, Промяна на честотата - Проблем

Определено... явно съм го пропуснал това, а уж четох няколко пъти всичко от дейташийта за таймерите

Страница 1 от 1 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/