Frekvencia mérés

Hogyan programozzak AVR chipet? Programozók beállításai...
Bascom nyelvű programok...
Avatar
joda
DrótVégénSzéndarab
Hozzászólások: 47
Csatlakozott: 2011. március 23. szerda, 6:00

HozzászólásSzerző: joda » 2011. április 17. vasárnap, 10:03

Robert írta:Én amit csinálnék:

Timer számláló bemenetére kötném a mérendő jelet. A timer 1 0...65535ig mér. Másik timerrel meg órajelalapot hozok létre. És két ilyen órajelalappal mérek. 0. órajelalap: timer1=0. 1. órajelalap: timer1 kiolvas.

Frekvencia:
Timer1 értéke/órajelalap hossza :)

NINCS állandó INT ami beterhel, tisztán HW alapú a mérés.


Sziasztok,

Demóbordom: EasyAVR5A
Programnyelv: Bascom
CPU: ATmega16
AVR ismeretem: kezdő

próbálkozom megvalósítani a Robert által adott program tervet de valahogy leakadtam.
Így gondoltam a dolgot a freki mérésre:

Ahogy a Robert javasolta, a Timer1 lábra bekötöm a mérendő jelforrást.
A Timer0-át meg időalapnak állítom be, tehát:

Timer1 = Counter
Timer0 = Timer

itt a kódom amit csináltam de nem müxik valamiért :(

Kód: Egész kijelölése

$regfile = "m16def.dat"
$crystal = 8000000

Config Portb.1 = Input

Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcd = 16 * 2
Config Timer0 = Timer , Prescale = 1024
Config Timer1 = Counter , Edge = Rising

Const Timer0reload = 250

Cls
Cursor Off

Load Timer0 , Timer0reload
Load Timer1 , 0
On Ovf0 Timer0_isr
On Ovf1 Timer1_isr

Enable Timer0
Enable Timer1

Start Timer0
Start Timer1

Timer0_isr:
Load Timer0 , Timer0reload
Cls
Locate 1 , 1
Lcd Timer1
Wait 1
Timer1 = 0
Return

Timer1_isr:
Load Timer1 , 0
Return


ha a Portb.1 lábra rákötöm az 1KHz jelet ami a Timer1 láb, az LCD-n megjelenik 3-as 4-es szám. Nem létezik, hogy csak 3-4-ig számol el a számláló...

Na most, láttam az adat lappab, hogy a TCNT1 regiszterben őrzi a Timer1 a számolt számokat amit kapott a bemenetelén.

Próbáltam

Kód: Egész kijelölése

LCD = Timer1


helyett a

Kód: Egész kijelölése

LCD = TCNT1


kiolvasni ami egyfórma eredményt adott vissza.

Valami hozzászólást kérnék nálam jártasabbaktól ebben a témában.

Köszi.

Avatar
winnerbt
Chipfüstölő
Hozzászólások: 897
Csatlakozott: 2007. március 25. vasárnap, 6:00
Tartózkodási hely: Kecskemét

HozzászólásSzerző: winnerbt » 2011. április 17. vasárnap, 11:25

Ha jól számolom, 8MHz/1024/6= 1302Hz a megszakítás Timer0-nál. Ha túlcsordul, akkor még az INT-ben van LCD meg WAIT... Szóval szerintem lazán magárafut, Talán egy STOP Timer0 jó lenne bele (egyelőre).
Hirtelen, első ránézésre...

Avatar
joda
DrótVégénSzéndarab
Hozzászólások: 47
Csatlakozott: 2011. március 23. szerda, 6:00

HozzászólásSzerző: joda » 2011. április 17. vasárnap, 14:16

Valamit nem jó csinálok.
Probáltam a stop timer0 opcíóval is és nem katam eredményt, csak valami számot pl. 4 maj 305 és csak váltakoztak...

Nem tudok rá jönni mi a bibi...

Elméletileg ha pl.
a Timer0 - át használom mind stopperóra
a Timer1 - et meg számláló akkor az kellene, hogy történyen, hogy
a stopperora elindul és elindul a számlálás is.
Ha a stopperóra túlcsórdul, kiírja az LCD-n a számláló regiszterében levő
számot és lenullázza a számlálót, vár 1s majd törli az lcd-t majd indul minden újra...

Dúrván ez az elképzelésem de nem jön ossze...

Kód: Egész kijelölése

Config Timer0 = Timer , Prescale = 1024    '<-- konfigurálom a TIMER0-át
Config Timer1 = Counter , Edge = Rising    '<-- konfigurálom a TIMER1-et

Const Timer0reload = 125                         '<-- TIMER0 start értéke

Cls                                     '<-- tőrlöm az LCDt
Cursor Off                           '<-- kurzor az LCDn kikapcsolva
Load Timer0 , Timer0reload                  '<-- TIMER0 értékét beállítja 131-re

On Ovf0 Timer0_isr               '<-- ha TIMER0 túlcsordul megy Timer0_isr sorba

Enable Timer0                      '<-- TIMER0 engedélyezve
Enable Timer1                      '<-- TIMER1 engedélyezve

Start Timer0                         '<-- TIMER0 indul a számlálás 256-ig
Start Timer1                         '<-- TIMER1 indul a számlás

Timer0_isr:
Stop Timer0                     '<-- TIMER0 megáll - stopperóra kikapcsolva
Stop Timer1                     '<-- TIMER1 megáll - bejövő jelek számolása megall

Load Timer0 , Timer0reload
Cls                                           '<-- LCD tőrlés
Locate 1 , 1                               '<-- karakterek helye beállítása az LCDn
Lcd Timer1                                '<-- LCDre kiírja a TIMER1 értéket
Timer1 = 0                                '<-- TIMER1 értékét nullázza
Wait 2                     '<-- 2s vár, hogy le lehessen olvasni az LCDt
Return                                       '<-- vissza a fő programba


és miért ír ki az LCDre 4est, 5öst, 3ast stb...?

Freki mérőmön szépen kiírja, hogy a jelforrásom 1000.068Hz.

2 magas szint az 1 periódusnak felel meg ami 1Hz ha 1s az eltelt idő ha nem tévedek.
Tehát, ha megszámolom 1 bizonyos idő alatt mennyi magas szint keletkezett és elosztom 2vel akkor megkapom mennyi a periódusok száma/az eltelt idő alatt ami meg tudná határozni a frekit.

Vagy?

Avatar
Robert
Elektronbűvölő
Hozzászólások: 10054
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

HozzászólásSzerző: Robert » 2011. április 17. vasárnap, 15:51

ISR-ben Wait? Időigényes mindenféle?

A Timer0 ISR 1 sec lenne. Mit keres benne egy Wait 2 sor?????

Avatar
winnerbt
Chipfüstölő
Hozzászólások: 897
Csatlakozott: 2007. március 25. vasárnap, 6:00
Tartózkodási hely: Kecskemét

HozzászólásSzerző: winnerbt » 2011. április 17. vasárnap, 15:55

A 8MHz/1024/(256-125)=59Hz a Timer 0 periódusidőd, nem?
(T0 8-bites CT)
A programod meg az Enable Timer... után ráfut az ISR-re.
Ha jól látom.

JAni
16:55

Avatar
joda
DrótVégénSzéndarab
Hozzászólások: 47
Csatlakozott: 2011. március 23. szerda, 6:00

HozzászólásSzerző: joda » 2011. április 17. vasárnap, 17:32

Robert:
kijavítottam a hibát, köszi.

Új kód ami csak egy szál nullát ír ki az LCD-re

Kód: Egész kijelölése

Cls
Cursor Off

Load Timer0 , 125

On Ovf0 Timer0_isr

Enable Timer0
Enable Timer1

Start Timer0
Start Timer1

Do
Locate 1 , 1
Lcd Timer1
Loop


Timer0_isr:
Timer1 = 0
Return


nem tudok mit csinálni tovább... :( :?

Avatar
Robert
Elektronbűvölő
Hozzászólások: 10054
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

HozzászólásSzerző: Robert » 2011. április 17. vasárnap, 18:13

A Timer1 melyik lábára kötöd a bemeneti jelet?

Az ISR-ben csak azt írasd ki, ha változás van (jelzőbit beállítás ISR-ben!)


Az utolsó programod a legrosszabb:( .


Gondold végig, lépésenként mit kell tenned....
Lépésenként írdd le, és próbálj mellé prg-t tenni....

Avatar
joda
DrótVégénSzéndarab
Hozzászólások: 47
Csatlakozott: 2011. március 23. szerda, 6:00

HozzászólásSzerző: joda » 2011. április 17. vasárnap, 20:53

Robert írta:Az utolsó programod a legrosszabb:( .


Útközben, találtam még egy problémát amit nem vettünk észre.
Sehol se nem engedélyeztem az interaptok használatát.

Kód: Egész kijelölése

Enable Interrupts


ez hiányzott.

Tudom, hogy az utolsó progim a leg gagyibb de sajna már elfogyott a tudományom és már lottóztam... :)

A Portb.1 - es lábra van kötve a bemeneti jel...

Avatar
joda
DrótVégénSzéndarab
Hozzászólások: 47
Csatlakozott: 2011. március 23. szerda, 6:00

HozzászólásSzerző: joda » 2011. április 20. szerda, 14:42

Sziasztok, itt az új kódom:

Kód: Egész kijelölése

$regfile = "m16def.dat"
$crystal = 8000000

Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Cursor Off
Config Debounce = 30

Config Timer1 = Counter , Edge = Rising
Config Timer0 = Timer , Prescale = 256
Enable Ovf0
On Ovf0 Timer0_isr

Dim Count As Word
Dim Count_max As Word
Dim Timer0_flag As Bit


Cls
Config Portb.1 = Input           
Config Portb.2 = Input
Config Portb.3 = Input
Enable Interrupts

Time_1s:
Count_max = 122
Do

Debounce Pinb.2 , 1 , Time_500ms
   If Timer0_flag = 1 Then
      Timer0_flag = 0
      Cls
      Lcd "F=" ; Timer1
      Locate 1 , 15
      Lcd "Hz"
      Locate 2 , 1
      Lcd "Smpl = 1s"
      Timer1 = 0
      Locate 2 , 15
      Lcd "P1"
      Start Timer0
      Start Timer1
   End If
Loop

Time_500ms:
Count_max = 244
Do

Debounce Pinb.3 , 1 , Time_1s
   If Timer0_flag = 1 Then
      Timer0_flag = 0
      Cls
      Lcd "F=" ; Timer1
      Locate 1 , 15
      Lcd "Hz"
      Locate 2 , 1
      Lcd "Smpl=1/2s"
      Timer1 = 0
      Locate 2 , 15
      Lcd "P2"
      Start Timer0
      Start Timer1
   End If
Loop
End
'----------------------------------------

Timer0_isr:
   Incr Count

   'If Count = 122 Then
   If Count = Count_max Then
      Stop Timer1
      Stop Timer0
      Count = 0
      Timer0 = 0
      Timer0_flag = 1
   End If

Return


Nos, itt minden ok eddig, szépen dolgozik amikor teszteltem stb...
A probléma ami felmerült az a gombnyomás.
Néha egyszerűen leblokkol a szofi. Mikor váltok az egyik do-loop ból a másikra.

Nemigen jó megoldás. Valami hozzászólás jól jönne.

Előre is köszi.

Avatar
Robert
Elektronbűvölő
Hozzászólások: 10054
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

HozzászólásSzerző: Robert » 2011. április 20. szerda, 15:27

debounce-t felejtsd el. neked itt nem jó. a 2 gombnyomást különböztessed meg, hogy nINCS 2 egymás után. Valami flaggal jelezd, hogy a gombot megnyomták, és 500 msecig nincs még 1 nyomkodás...

Van még 1 szabad TIMER-ed :P OK, vad, de jobb nem jutott eszembe...

Avatar
joda
DrótVégénSzéndarab
Hozzászólások: 47
Csatlakozott: 2011. március 23. szerda, 6:00

HozzászólásSzerző: joda » 2011. április 27. szerda, 14:59

Ok.
Itt a frekimérő szofim ATmega16-al megoldva.

Eddig müködik.

Kód: Egész kijelölése

$regfile = "m16def.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 8
$framesize = 16


Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Portb.1 = Input

Config Timer1 = Counter , Edge = Rising
Config Timer0 = Timer , Prescale = 256
Enable Ovf0
Enable Ovf1
On Ovf0 Timer0_isr
On Ovf1 Timer1_isr

Dim Count As Word
Dim Timer0_flag As Bit
Dim Timer1_flag As Bit
Dim Frequency As Single
Dim Metric As String * 1
Dim Frequency_str As String * 6
Dim Count_t1 As Single

Frequency = 0
Count_t1 = 0
Timer0_flag = 0
Timer1_flag = 0

Cursor Off
Cls

Enable Interrupts

Do

   If Timer0_flag = 1 Then
      Timer0_flag = 0

      If Timer1_flag = 1 Then
            Incr Count_t1
            Frequency = Count_t1 * 65536
            Timer1_flag = 0
            Count_t1 = 0
      Else
            Frequency = Timer1
      End If


      '================= Freki Hz =====================
      If Frequency < 1000 Then
         Metric = "H"
         Frequency_str = Fusing(frequency , "###.##")
      End If
      '================================================


      '================= Freki KHz ===================
      If Frequency > 999 And Frequency < 999999 Then
         Metric = "K"
         Frequency = Frequency / 1000
         Frequency_str = Fusing(frequency , "###.##")
      End If
      '===============================================


      '================= Freki MHz =========================

      If Frequency > 999999 And Frequency < 999999999 Then
         Metric = "M"
         Frequency = Frequency / 1000000
         Frequency_str = Fusing(frequency , "###.##")

      End If
      '======================================================


      Cls

      Lcd "F=" ; Frequency_str

      Locate 1 , 15
      Lcd Metric


      Timer1 = 0
      Start Timer0
      Start Timer1

   End If

Loop


Timer0_isr:
   Incr Count

   If Count = 122 Then

      Stop Timer1
      Stop Timer0
      Count = 0
      Timer0 = 0
      Timer0_flag = 1

         If Count_t1 > 0 Then
            Timer1_flag = 1
         End If

   End If

Return

Timer1_isr:
  Incr Count_t1
  Return

End


Várom a kommentárokat és hozzászólásokat esetleg mit kellene másképpen megoldani, kritikák stb.

Köszi mindenkinek aki segített eddig eljutnom.
Külön hálával tartozom:
Robertnek
Winnerbtnek
meg Kapu48nak.

üdv.

Avatar
sytex
DrótVégénSzéndarab
Hozzászólások: 36
Csatlakozott: 2010. június 10. csütörtök, 6:00
Tartózkodási hely: Pilisszentiván

HozzászólásSzerző: sytex » 2011. augusztus 9. kedd, 12:15

Sziasztok, előbb kérdezek itt, mint elkezdek agyalni és elmegyek teljesen rossz irányba.

Egy max. 15Mhz-es 50%-os négyszögjel frekvenciáját kéne mérnem. Van erre bármi esély, vagy ne is kezdjek bele?
A hozzászólást 2 alkalommal szerkesztették, utoljára sytex 2011. augusztus 9. kedd, 12:21-kor.

Avatar
Robert
Elektronbűvölő
Hozzászólások: 10054
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

HozzászólásSzerző: Robert » 2011. augusztus 9. kedd, 12:20

AVR-rel ami frekvencia mérhető: max órajel/4 : ~ 5 MHz).
DE: ha van előosztó chiped (valamelyik CMOS IC, pl. CD4017) akkor azzal csinálsz egy 10-es előosztást. :P Szóval mérhető....


Az alapev: adott ideig számolod a bejövő impulzusokat....

Avatar
sytex
DrótVégénSzéndarab
Hozzászólások: 36
Csatlakozott: 2010. június 10. csütörtök, 6:00
Tartózkodási hely: Pilisszentiván

HozzászólásSzerző: sytex » 2011. augusztus 9. kedd, 12:23

Köszi. Utánanézek ennek a "tizedelésnek"

Avatar
winnerbt
Chipfüstölő
Hozzászólások: 897
Csatlakozott: 2007. március 25. vasárnap, 6:00
Tartózkodási hely: Kecskemét

HozzászólásSzerző: winnerbt » 2011. augusztus 9. kedd, 13:46

Szia!
Asszem a CD sorozat nem fog menni 5V-nál 15MHz-et (de nem biztos).
74LS393-t hsználj, akkor van egy 256-os osztód és ha van portod, akkor be tudod olvasni a számláló értékét is. Ha jól rémlik, van tri-state kimenetű 2x4-bites számláló ebben a családban, akkor kevesebb portláb kell.
JAni


Vissza: “Bascom-AVR nyelvű programozás (AVR programozásának lehetőségei)”

Ki van itt

Jelenlévő fórumozók: nincs regisztrált felhasználó valamint 1 vendég