Отговори на тема  [ 12 мнения ] 
Atmega8, Таймер, Промяна на честотата - Проблем 
Автор Съобщение
Ранг: Професионалист
Ранг: Професионалист
Аватар

Регистриран на: Нед Ное 08, 2009 12:17 am
Мнения: 512
Мнение 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 (стойността на брояча на таймера) е примерно между някакви стойности... или и аз не знам какво точно.
Някой има ли идеи, надявам се да съм обяснил разбираемо за какво иде реч.


Последна промяна klez на Съб Фев 11, 2012 12:58 am, променена общо 2 пъти



Пет Фев 10, 2012 11:17 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Ное 12, 2004 3:38 pm
Мнения: 9103
Местоположение: Chicago, IL
Мнение Re: Atmega8, Таймер, Промяна на честотата - Проблем
Сега не се сещам как е точно в мегите, но генерално когато таймера стигне определената стойност в компаратора би трябвало да се вдига някакъв флаг, за да ти генерира прекъсване (ако то е разрешено де). Та сложи в while проверка за тоя флаг и като се вдигне тогава зареждай новата стойност и после да не забравиш да го нулираш. Предполагам, че най-вероятно е от това, защото като променяш стойността в движение и най-вероятно се получава нещо като модулация на изхода, което пък се изразява в пукане.


Пет Фев 10, 2012 11:34 pm
Профил
Ранг: Професионалист
Ранг: Професионалист
Аватар

Регистриран на: Нед Ное 08, 2009 12:17 am
Мнения: 512
Мнение Re: Atmega8, Таймер, Промяна на честотата - Проблем
Код:
   while (!(TIFR&0b00001000));
   OCR1A=newfreq;
   TIFR |= (1<<OCF1A);


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

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


Съб Фев 11, 2012 12:35 am
Профил
Ранг: Професионалист
Ранг: Професионалист
Аватар

Регистриран на: Нед Ное 08, 2009 12:17 am
Мнения: 512
Мнение Re: Atmega8, Таймер, Промяна на честотата - Проблем
Сложих го така:
Код:
while (!((TCNT1<100)&(TCNT1>10)));


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


Съб Фев 11, 2012 1:06 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Ное 12, 2004 3:38 pm
Мнения: 9103
Местоположение: Chicago, IL
Мнение Re: Atmega8, Таймер, Промяна на честотата - Проблем
Явно е някакъв ефект от скоростта, с която се променя честота. В какъв обхват я променяш тая честота?


Съб Фев 11, 2012 1:12 am
Профил
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Съб Сеп 03, 2005 11:31 am
Мнения: 766
Местоположение: Пловдив
Мнение Re: Atmega8, Таймер, Промяна на честотата - Проблем
Пробвай така


unsigned int TV;


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

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

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

_________________
"I really do like SOLDERING as my programming language." Bob Pease


Съб Фев 11, 2012 1:16 am
Профил ICQ
Ранг: Професионалист
Ранг: Професионалист
Аватар

Регистриран на: Нед Ное 08, 2009 12:17 am
Мнения: 512
Мнение Re: Atmega8, Таймер, Промяна на честотата - Проблем
Митко най вероятно наистина прекалено бързо се опитвам да я променям.

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


Съб Фев 11, 2012 1:04 pm
Профил
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Съб Сеп 03, 2005 11:31 am
Мнения: 766
Местоположение: Пловдив
Мнение Re: Atmega8, Таймер, Промяна на честотата - Проблем
klez написа:
Митко най вероятно наистина прекалено бързо се опитвам да я променям.

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



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

_________________
"I really do like SOLDERING as my programming language." Bob Pease


Съб Фев 11, 2012 7:13 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Съб Сеп 25, 2004 12:32 pm
Мнения: 8382
Местоположение: София
Мнение Re: Atmega8, Таймер, Промяна на честотата - Проблем
Трябва да сменяш стойността на сравняващия регистър и да зануляваш таймера след завършване на таймерния цикъл. В противен случай просто опресняваш преди да е достигнал стойност, при която се случва нещо.


Съб Фев 11, 2012 10:53 pm
Профил
Ранг: Професионалист
Ранг: Професионалист
Аватар

Регистриран на: Нед Ное 08, 2009 12:17 am
Мнения: 512
Мнение Re: Atmega8, Таймер, Промяна на честотата - Проблем
Мисля че открих проблема..... просто един цикъл на таймера ако нямам _delay_ функция е по-дълъг отколкото няколко смени на променливата, сега като сменям честотата през повече от 2 милисекунди е окей, а мен реално ще ми трябва през 100-200 милисекунди да я сменям най-малко така че за момента ме устройва.


Съб Фев 11, 2012 11:05 pm
Профил
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Пет Авг 07, 2009 4:58 pm
Мнения: 273
Мнение Re: Atmega8, Таймер, Промяна на честотата - Проблем
Тази ситуация, мисля, че е описана тук, в документацията (четох дейташийта на друга АТмега, но таимерите не им се различават, струва ми се).


Прикачени файлове:
Timer 1 CTC mode.JPG
Timer 1 CTC mode.JPG [ 156.1 KiB | Прегледано 2171 пъти ]
Чет Фев 16, 2012 2:26 pm
Профил
Ранг: Професионалист
Ранг: Професионалист
Аватар

Регистриран на: Нед Ное 08, 2009 12:17 am
Мнения: 512
Мнение Re: Atmega8, Таймер, Промяна на честотата - Проблем
Определено... явно съм го пропуснал това, а уж четох няколко пъти всичко от дейташийта за таймерите


Чет Фев 16, 2012 3:02 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 12 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 2 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни