Отговори на тема  [ 21 мнения ]  Отиди на страница 1, 2  Следваща
Проблем на честотомер с Атмега32 
Автор Съобщение
Ранг: Новодошъл
Ранг: Новодошъл
Аватар

Регистриран на: Съб Авг 18, 2007 11:39 am
Мнения: 137
Местоположение: Русе
Мнение Проблем на честотомер с Атмега32
Здравейте, от известно време се мъча с направата на честотомер елемнтарен, който да мери честота в диапазона до 10 кHz. Използвам Атмега32 на 4 MHz. Измерването го правя като броя входните импулси с таймер/брояч 1 който пък нулирам през определен период с таймер 2. Теоритично би трябвало да измерва честота до 65 kHz като калибрирам системата и като знам, че брояа ми е 16 битов. Работя с микро С за АВР на микроелектроника. Но имам много гаден проблем и не мога да хвана къде греша. Това ми е сорса държа да подчертая че съм доста начинаещ и може би това не е най добрия метод за направа на честотомер. Ето това ми е сорса:
Код:
                /*// LCD module connections
sbit LCD_RS at PORTA5_bit;
sbit LCD_EN at PORTA4_bit;
sbit LCD_D4 at PORTA3_bit;
sbit LCD_D5 at PORTA2_bit;
sbit LCD_D6 at PORTA1_bit;
sbit LCD_D7 at PORTA0_bit;

sbit LCD_RS_Direction at DDA5_bit;
sbit LCD_EN_Direction at DDA4_bit;
sbit LCD_D4_Direction at DDA3_bit;
sbit LCD_D5_Direction at DDA2_bit;
sbit LCD_D6_Direction at DDA1_bit;
sbit LCD_D7_Direction at DDA0_bit;
// End LCD module connections*/

// LCD module connections
sbit LCD_RS at PORTD2_bit;
sbit LCD_EN at PORTD3_bit;
sbit LCD_D4 at PORTD4_bit;
sbit LCD_D5 at PORTD5_bit;
sbit LCD_D6 at PORTD6_bit;
sbit LCD_D7 at PORTD7_bit;

sbit LCD_RS_Direction at DDD2_bit;
sbit LCD_EN_Direction at DDD3_bit;
sbit LCD_D4_Direction at DDD4_bit;
sbit LCD_D5_Direction at DDD5_bit;
sbit LCD_D6_Direction at DDD6_bit;
sbit LCD_D7_Direction at DDD7_bit;
// End LCD module connections


unsigned  int count,oldCount,count1,Rh;
char txt[8],txt2[8];
const char _THRESHOLD = 16;
char counter,flag;

void Timer2Overflow_ISR() org IVT_ADDR_TIMER2_OVF {

  if (counter >= _THRESHOLD) {
     count1 = ((TCNT1H<<8)+TCNT1L);
     //count=count1;//-(count1*0.044);
     oldCount = count1;
     //Rh=565.3-(oldCount*0.07675);
     count1 = 0;
     counter = 0;
     TCNT1H=0;
     TCNT1L=0;

  }
  else
    counter++;                    // increment counter
}
void main() {
     SREG_I_bit = 1;                   // Interrupt enable
     TOIE2_bit  = 1;                  // Timer2 overflow interrupt enable
     TCCR2  = 0x07;                   // Start timer with 1024 prescaler
     TCCR1A = 0x00;                   //Setup TC1 to count PB1
     TCCR1B = 0x07;
  Lcd_Init();                                   // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);                          // Clear LCD
  Lcd_Cmd(_LCD_CURSOR_OFF);                     // Turn cursor off
  Lcd_Out(1, 1, "Frecuncy:");
  Lcd_Out(2,15,"Hz");
  while (1) {
  count = ((TCNT1H<<8)+TCNT1L);
  //Rh=565.3-(oldCount*0.07675);
  WordToStr(count, txt2);
  Lcd_Out(1, 10, txt2);
  WordToStr(oldCount, txt);
  Lcd_Out(2,1,txt);

  }
}

Проблема ми е следния. Това нещо работи и измерва, но примерно аз му подавам 6600 Hz то през голяма част от времето показва тази стойност, но на моменти показва примерно 6900 Hz. Прави го напълно произволно и най лошото е че не съм сигурен софтуерен ли е проблема или в хардуера ми. Склонен съм да мисля че е софтуерен защото на няколко пъти го бях укротил да си показва честотата колкото е. И само като добавя 1 сметка която трябва да имам започваха сривовете. Някой ако може да помогне със съвети или покаже къде греша в подхода. Да подчертая също че проблема не е в генератора от който подавам сигнал, прави го при 2 различни генератора. Също така генераторите ги контролирам с честотомер и няма подобен проблем. Всичко идва от моето устройство.

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


Чет Мар 24, 2011 6:39 pm
Профил
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Пет Авг 07, 2009 4:58 pm
Мнения: 273
Мнение 
Пробвай да видиш какъв резултат дава (а << 8), когато а е от тип char. Честота не съм мерил, но изразът, с който взимаш стойността на двата регистъра на таймера, ми изглежда грешен. А не можеш ли да я вземеш наведнъж: а = TCNT1; ?


Вто Апр 05, 2011 10:35 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл
Аватар

Регистриран на: Съб Авг 18, 2007 11:39 am
Мнения: 137
Местоположение: Русе
Мнение 
Здравей и благодаря за съветите. Проблема мисля се отстрани като направих някой корекции в сорса. Също така преди това бях се заблудил нещо и вместо да работи с външен кварц работеше на вътрешен осцилатор. Сега се е укротило след като всичко му е сетнато както трябва. В случая използвам микроС и в него няма дефиниран този регистър TCNT1 като 16 битов а е разделен на 2 регистъра по 8 бита. Преобразуването си е добре и е коректно. Проблем до някъде е, че права много неща в прекъсването, по принцип не е хубаво ама работи перфектно така. Като се опитам да изнеса някой сметки извън прекъсване стават гафове затова засега смятам в прекъсването. Днес дори мигрирах на 16MHz, че преди това работих на 4. Сега остава да навържа още няколко модула към системата без да се скапе нещо.


Вто Апр 05, 2011 10:51 pm
Профил
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Пет Авг 07, 2009 4:58 pm
Мнения: 273
Мнение 
Странно, аз съм имал проблеми с такъв израз, но щом върви, добре е :)


Сря Апр 06, 2011 8:35 am
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Пет Мар 23, 2012 1:38 pm
Мнения: 13
Мнение Re: Проблем на честотомер с Атмега32
Колега радвам се че си пуснал тази тема. Това е нещо което ме интересува живо. Мислех и аз да се захващам с експерименти но за щастие се сетих първо да потърся в нета.
накратко трябват ми повечко такива честотомери за автоматизиране на едни измервания. Бих се радвал ако ти или някой друг който чете тази тема и се се интересува. Се свърже с ме. за да поработим съвместно по въпроса може би ще се наложи да отворя и нова тема но сега очаквам отзиви тук


Пет Мар 23, 2012 1:52 pm
Профил
Ранг: Популярен
Ранг: Популярен

Регистриран на: Сря Яну 25, 2006 12:47 pm
Мнения: 305
Местоположение: Varna
Мнение Re: Проблем на честотомер с Атмега32
Помисли в/у този израз: "count = ((TCNT1H<<8)+TCNT1L);"
Както и да го напишеш на 'C', ако процесора ти е 8 битов реално регистрите ще се прочетат в различно време. И какво ще се случи с крайния резултат, ако точно в момента настъпи пренос от 'L' към 'H'?
Приципът е: Операцията по четенето на променлива, която се изменя в прекъсване или от някакъв външен процес, трябва да бъде АТОМИЧНА.


Нед Апр 01, 2012 10:15 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Яну 19, 2007 9:16 am
Мнения: 1063
Местоположение: путинофили: "иди н***й"
Мнение Re: Проблем на честотомер с Атмега32
bkulev написа:
този израз: "count = ((TCNT1H<<8)+TCNT1L);"
...

на човешки помпилатор, най-вероятно винаги ще е count = TCNT1L;
(ако някой се чуди ... що? - нека се сети че става въпрос за 8-битова аритметика)


Нед Апр 01, 2012 11:20 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юни 10, 2007 2:22 pm
Мнения: 6492
Местоположение: София
Мнение Re: Проблем на честотомер с Атмега32
bkulev написа:
Помисли в/у този израз: "count = ((TCNT1H<<8)+TCNT1L);"
Както и да го напишеш на 'C', ако процесора ти е 8 битов реално регистрите ще се прочетат в различно време. И какво ще се случи с крайния резултат, ако точно в момента настъпи пренос от 'L' към 'H'?
Приципът е: Операцията по четенето на променлива, която се изменя в прекъсване или от някакъв външен процес, трябва да бъде АТОМИЧНА.


А, защо, не непременно. Стандарнтият начин е:
-прочита се старшия
-прочита се младшия
-прочита се старшия
-ако двете прочетени стойности на старшия се различават, повтаря се цялата последователност.

_________________
-------------------
www.tgi-sci.com
-------------------
http://www.flickr.com/photos/didi_tgi/


Нед Апр 01, 2012 1:24 pm
Профил WWW
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Пон Апр 17, 2006 1:44 pm
Мнения: 291
Мнение Re: Проблем на честотомер с Атмега32
Не съм убеден, че това е надежден подход, тъй като между двете четения на старшият байт могат да настъпят промени, при което старшият байт при второто четене отново да е с началната си стойност, но младшия байт вече да е променен...?!


Нед Апр 01, 2012 10:57 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Фев 03, 2005 2:21 am
Мнения: 12765
Местоположение: София
Мнение Re: Проблем на честотомер с Атмега32
...старшият байт винаги е с различна стойност = while(1) ? :D


Нед Апр 01, 2012 11:03 pm
Профил
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Пон Апр 17, 2006 1:44 pm
Мнения: 291
Мнение Re: Проблем на честотомер с Атмега32
Код:
0b11010 11110100 -> 6900
0b11001 11001000 -> 6600
    0b1 00101100 -> 300


Прави ми впечатление, че старшият байт се увеличава точно с едно...


Пон Апр 02, 2012 1:53 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юни 10, 2007 2:22 pm
Мнения: 6492
Местоположение: София
Мнение Re: Проблем на честотомер с Атмега32
itso.t написа:
...старшият байт винаги е с различна стойност = while(1) ? :D


Ти се майтапиш ама май те взеха насериозно :D :D :D

_________________
-------------------
www.tgi-sci.com
-------------------
http://www.flickr.com/photos/didi_tgi/


Пон Апр 02, 2012 2:25 am
Профил WWW
Ранг: Новодошъл
Ранг: Новодошъл
Аватар

Регистриран на: Съб Авг 18, 2007 11:39 am
Мнения: 137
Местоположение: Русе
Мнение Re: Проблем на честотомер с Атмега32
Наистина не е най-добрия вариант за направа на честотомер, но на мен ми свърши работа.
Проблема с отскоците не съм много сигурен, но мисля че беше от кофти кварц, и не добре сетнати fuse битове. Когато имаше проблемите работеше на вътрешен осцилатор а мислех, че работи на кварц, и някъде оттам ми се струва че беше този бъг.
Това преобразуване, което коментирате при други компилатори не би се наложило.В datasheeta има примерен сорс за 16-битовия таймер и там си има посочен 16-битов регистър от който може да се чете директно стойността. AVR Studioto си го познава, но на микро С то не беше добавян този регистър и затова си реших на бързо проблема по този начин.


Пон Апр 02, 2012 10:36 pm
Профил
Ранг: Популярен
Ранг: Популярен

Регистриран на: Сря Яну 25, 2006 12:47 pm
Мнения: 305
Местоположение: Varna
Мнение Re: Проблем на честотомер с Атмега32
Ако няма друг надежден и бърз начин, то най - сигурният е:
Disable Interrupt;
count = ((TCNT1H<<8)+TCNT1L);
Enable Interrupt;

Защото, колега сега може и да не се виждат някакви "отскоци", "несъответствия" или каквото там му викаш, но бъди сигурен ЩЕ ИМА. Друг е въпросът дали ти ще ги забележиш. :)
Така че както е казал нашия мъдър народ: "Вържи попа, та да е мирно селото"


Вто Апр 03, 2012 4:28 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юни 10, 2007 2:22 pm
Мнения: 6492
Местоположение: София
Мнение Re: Проблем на честотомер с Атмега32
Е ако са две 8 бита четения (т.е. два отделни цикъла) маскирането на прекъсванията
няма да върже попа :) .

_________________
-------------------
www.tgi-sci.com
-------------------
http://www.flickr.com/photos/didi_tgi/


Вто Апр 03, 2012 5:07 pm
Профил WWW
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 21 мнения ]  Отиди на страница 1, 2  Следваща

Кой е на линия

Потребители разглеждащи този форум: Google [Bot] и 31 госта


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

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