Timer probléma

Hogyan programozzak AVR chipet? Programozók beállításai...
Bascom nyelvű programok...
Avatar
lesliewednesday
Újonc
Újonc
Hozzászólások: 13
Csatlakozott: 2007. október 2. kedd, 6:00

HozzászólásSzerző: lesliewednesday » 2009. április 16. csütörtök, 18:22

Nos, a következő programot írtam:

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

$regfile = "m8def.dat"                                      ' Mega8
$crystal = 8000000                                          ' 8MHz RC osc
$hwstack = 32                                               ' default use 32 for the hardware stack
$swstack = 10                                               ' default use 10 for the SW stack
$framesize = 4



Config Portb.1 = Output                                     'impulzus kimenet
Config Pind.2 = Input                                       'INT0 a bemenet
Dim Pulse As Word
Dim Pulse1 As Long
Dim A As Word


Set Portb.1                                                 'impulzus kimenet bekapcsoláskor magasban
Set Portd.2                                                 'INT0 bemenet pull up

Config Int0 = Change
Config Timer1 = Timer , Prescale = 64                       'előosztott időzítő/számláló
Start Timer1


'Config Watchdog = 512

On Int0 Indul Nosave
On Ovf1 Vege Nosave
Enable Interrupts
Enable Int0
Enable Timer1
'Start Watchdog

Do
'Reset Watchdog
A = Getadc(0)                                               'időtöltésnek
Waitms 50
Loop

End




Vege:                                                       'Timer1 túlcsordult
Set Portb.1                                                 'kimenet 1-be, imp. vége
Gifr = 64
'Reset Watchdog
Return





Indul:
'Reset Watchdog
If Pind.2 = 0 Then                                          'lefutó él?
   Reset Timer1                                             'igen
   Reset Portb.1                                            'kimenet 0-ba, imp kezdődik
   Else                                                     'felfutó él
   'Set Portb.1
   Pulse = Timer1                                           'Timer1 értéke rögzítve
   Shift Pulse , Right , 3                                  '8-ad részre osztva (12,5%)
   Timer1 = 65535 - Pulse                                   'Timer1 feltöltése
End If
Gifr = 64
Return


Nagyjából jó, de ha bekapcsoláskor a bemeneti freki magasabb kb 16 Hz-nél vagy hirtelen freki ugráskor, a kimenet folyamatosan 0-ban marad, reset-re viszont észhez tér és 1kHz felett is korrekt módon generálja a kimeneti impulzusokat. Sajnos csak 50%-os kitöltési tényezőjű generátorjellel tudtam meghajtani. Próbálkoztam watchdog-gal kikerülni az indulási problémát, de ez nem jó, mert reset állapot nem lehet üzem közben (impulzusok kimaradnak). Van -e tippetek? 4MHz-ről járatva fele volt (8Hz) a felső határfreki az induláshoz. Mit ronthatok el? Esetleg Bascom fordít valamit rosszul? Gyanúm, hogy a Timer1-nél lehet valami gubanc. Mintha nem akarna túlcsordulni a Timer1, ha az INT0 lábon "túl magas" a freki. INT0 és ovf1 rutinoknál Nosave illetve Gifr=64 nélkül is ugyan ez a helyzet.

Avatar
herc1234
Bitfaragó
Hozzászólások: 459
Csatlakozott: 2007. február 9. péntek, 7:00
Tartózkodási hely: Törökbálint

HozzászólásSzerző: herc1234 » 2009. április 16. csütörtök, 18:41

A Timer-t én mindig feltöltöm indulás elött és a reset helyett
is load timer-t használok...Valahol a helpben is ezt preferálja..

Avatar
lesliewednesday
Újonc
Újonc
Hozzászólások: 13
Csatlakozott: 2007. október 2. kedd, 6:00

HozzászólásSzerző: lesliewednesday » 2009. április 16. csütörtök, 19:03

Jelentem, sajnos nem segített. Induláskor is és reset helyett is load-ot használtam.

Avatar
lesliewednesday
Újonc
Újonc
Hozzászólások: 13
Csatlakozott: 2007. október 2. kedd, 6:00

HozzászólásSzerző: lesliewednesday » 2009. április 16. csütörtök, 19:41

A Timer1 feltöltésénél van a baj! Ha fix értéket írok a Timer1-be, akkor bármilyen frekire azonnal ad kimenő jelet. A word típusú adat (Pulse) elvileg 0-65535 között lehet. Ha Timer1=65535-Pulse értékadást használok, minden pozitív egész Pulse értékre a Timer1-nek is jónak kell lennie, nem?

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

HozzászólásSzerző: Robert » 2009. április 16. csütörtök, 20:01

NOSAVE parameter hasznalataval INTben valtozokkal nem dolgozhatsz! Nem ment el jopar regisztert, igy a SRAMok keveredhetnek!

Avatar
lesliewednesday
Újonc
Újonc
Hozzászólások: 13
Csatlakozott: 2007. október 2. kedd, 6:00

HozzászólásSzerző: lesliewednesday » 2009. április 16. csütörtök, 20:50

Világos. Írtam, hogy az eredeti progiban nem segített, ha a Nosave paramétert kivettem.

Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3349
Csatlakozott: 2008. augusztus 29. péntek, 6:00
Tartózkodási hely: Újkígyós

HozzászólásSzerző: kapu48 » 2009. április 17. péntek, 8:37

Esetleg próbáld meg így is:

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


Indul:
'Reset Watchdog
Stop Timer1
If Pind.2 = 0 Then                                          'lefutó él?
   Reset Timer1                                             'igen
   Reset Portb.1                                            'kimenet 0-ba, imp kezdődik
   Else                                                     'felfutó él
   'Set Portb.1
   Pulse = Timer1                                           'Timer1 értéke rögzítve
   Shift Pulse , Right , 3                                  '8-ad részre osztva (12,5%)
   Timer1 = 65535 - Pulse                                   'Timer1 feltöltése
End If
Start Timer1                                                'Timer1 ujra indítása
Gifr = 64
Return

:idea:

Avatar
lesliewednesday
Újonc
Újonc
Hozzászólások: 13
Csatlakozott: 2007. október 2. kedd, 6:00

HozzászólásSzerző: lesliewednesday » 2009. április 17. péntek, 18:12

Próba megvolt. Így az eredetileg kb 16Hz "határfreki" (ami felett nincs kimenő impulzus, ha táp bekapcs után ráadom a bemenetre) leesett kb 5Hz-re. Idáig bármely variációban a freki folyamatos csökkentéskor a határ frekinél a kimenő impulzus megjelenik, majd a frekit növelve 1-2kHz-ig is tökéletesen megy, de ha egyből ráadok bármilyen frekit , ami nagyobb a határnál, nem ad impulzust a kimeneten. Azt hiszem, valami más megoldást kell választanom.

Avatar
lesliewednesday
Újonc
Újonc
Hozzászólások: 13
Csatlakozott: 2007. október 2. kedd, 6:00

HozzászólásSzerző: lesliewednesday » 2009. április 17. péntek, 18:16

Pwm-nél megoldható-e annak a szinkronizálása pl. az INT0/INT1 bemenethez?

Avatar
herc1234
Bitfaragó
Hozzászólások: 459
Csatlakozott: 2007. február 9. péntek, 7:00
Tartózkodási hely: Törökbálint

HozzászólásSzerző: herc1234 » 2009. április 17. péntek, 18:32

Az inkább a capture nem?Ami kéne neked.
És a bekapcsolási időzítés?
Vagy esetleg rakj mellé egy kontrollálható reset áramkört..
Sőt jobb rakj a bejövő elé valami kapcsoló fokozatot
amit te avr másik lábbal tudsz bekapcsolni..

Avatar
lesliewednesday
Újonc
Újonc
Hozzászólások: 13
Csatlakozott: 2007. október 2. kedd, 6:00

HozzászólásSzerző: lesliewednesday » 2009. április 17. péntek, 19:39

Még egy kísérletet tettem. Így jónak látszik. Többek között köszönet Kapu48 Capture program átdolgozásának és többi ötletének. Összehasonlítottam a Timer Start/Stop utasításokat és párat még betettem. Most azonnal generálja a kimeneti impulzusokat bármilyen (a szükséges tartományon belüli) bemenő frekire. A megszakítás rutin változott.(Sallangok eltávolítva). Nosave paraméterrel is próbáltam és működik!
Így már a sima osztás (most pl. Pulse/10-ot próbáltam) is használható.
Jöhet a többi apróság. (bill. vagy AD értéktől függő hosszabbítás, valami kijelzés, körítések stb). Köszönöm a segítségeteket.
Itt a teljes kód, hátha valaki hasznát veszi:

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

$regfile = "m8def.dat"                                      ' Mega8
$crystal = 8000000                                          ' 8MHz RC osc
$hwstack = 32                                               ' default use 32 for the hardware stack
$swstack = 10                                               ' default use 10 for the SW stack
$framesize = 4



Config Portb.1 = Output                                     'impulzus kimenet
Config Pind.2 = Input                                       'INT0 a bemenet
Dim Pulse As Word
Dim Pulse1 As Word
Dim A As Word


Set Portb.1                                                 'impulzus kimenet bekapcsoláskor magasban
Set Portd.2                                                 'INT0 bemenet pull up

Config Int0 = Change
Config Timer1 = Timer , Prescale = 64                       'előosztott időzítő/számláló
Start Timer1

On Int0 Indul Nosave
On Ovf1 Vege Nosave
Enable Interrupts
Enable Int0
Enable Timer1

Do
A = Getadc(0)                                               'időtöltésnek
Waitms 50
Loop

End




Vege:                                                       'Timer1 túlcsordult
Set Portb.1                                                 'kimenet 1-be, imp. vége
Gifr = 64
Return



Indul:
Stop Timer1                                                 'amíg itt van, ne számoljon
If Pind.2 = 0 Then                                          'lefutó él?
   Timer1 = 0                                               'igen
   Start Timer1                                             'na, most kezdjen számolni!
   Reset Portb.1                                            'kimenet 0-ba, imp kezdődik
   Else                                                     'felfutó él
   Pulse = Timer1                                           'Timer1 értéke rögzítve
   Stop Timer1                                              'Amíg kalkulálja az értéket, ne számoljon
   Pulse = Pulse / 10                                       '1/10-ed értékkel növeli a hosszt
   Pulse1 = 65535 - Pulse                                   'új Timer1 érték kiszámítása
   Timer1 = Pulse1                                          'Timer1 feltöltése
End If
Start Timer1                                                'Mehet tovább a számolás
Gifr = 64
Return

Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3349
Csatlakozott: 2008. augusztus 29. péntek, 6:00
Tartózkodási hely: Újkígyós

HozzászólásSzerző: kapu48 » 2009. április 18. szombat, 10:51

Egész ügyesen megoldottad, végül nem kelet két bemenet. Az L és H szint figyeléséhez.
De! Ha már a nosavet is beveteted az időnyerés érdekében! Akkor kiszedném a felesleges start-stop Timer1-eket is!

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

Indul:
Stop Timer1                                                 'amíg itt van, ne számoljon
If Pind.2 = 0 Then                                          'lefutó él?
   Timer1 = 0                                               'igen
   Start Timer1                                             'na, most kezdjen számolni!
   Reset Portb.1                                            'kimenet 0-ba, imp kezdődik
   Else                                                     'felfutó él
   Pulse = Timer1                                           'Timer1 értéke rögzítve
   Pulse = Pulse / 10                                       '1/10-ed értékkel növeli a hosszt
   Timer1 = 65535 - Pulse                                   'új Timer1 érték kiszámítása és Timer1 feltöltése
   Start Timer1                                                'Mehet tovább a számolás
End If
Gifr = 64
Return

Más. Mi van ha az L szint olyan hosszú, hogy túlcsordul a Timer1? És Vege: megszakítást generál időellőt? Ha felgyorsítod az órajelet ez a hiba még hamarabb előjön.
Ide kellene valami ellenőrzés!
:idea:

Avatar
lesliewednesday
Újonc
Újonc
Hozzászólások: 13
Csatlakozott: 2007. október 2. kedd, 6:00

HozzászólásSzerző: lesliewednesday » 2009. április 18. szombat, 21:50

Köszönöm. Ahogy időm engedi összetákolok 555-ös IC-vel egy imp. szélesség és frekvencia változtatásra is alkalmas egyszerű generátort és azzal lepróbálom az összes szóbajöhető üzemódot. A felső freki tartományhoz igazítottam (kb ott is van most) a Prescale értéket, az alsó freki pedig fizikailag behatárolt. Elvileg nem gond, ha Timer1 túlcsordulásakor a kimenet 1-be visszamegy. Korábban már írtam, kb milyen tartományra kell. Ezen belül viszont üzembiztosan kell tudnia a kimenő jelet. Egyébként szándékomban áll a szükséges védelmeket ezen felül még beletenni. A pár darab start/stop éppen az, ami megoldotta a korább bajt. De lehet, valahol még felesleges. Majd ezt is tesztelem még.

Avatar
Bence
Tranzisztorgyógyász
Hozzászólások: 166
Csatlakozott: 2007. október 30. kedd, 6:00
Tartózkodási hely: Budapest

HozzászólásSzerző: Bence » 2009. június 25. csütörtök, 17:39

Sziasztok!
Csináltam egy áramkört ami méri az időt. INT1-el indul a mérő, INT0-val megáll. A program itt van (az LCD-re kiírja, hogy hány túlcsordulás volt és hogy mennyi a TIMER1 értéke):

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

$regfile = "m8def.dat"
$crystal = 4000000

Config Pind.2 = Input
Config Pind.3 = Input
Config Int0 = Falling
Config Int1 = Falling
Config Timer1 = Timer , Prescale = 8


Config Lcd = 20 * 4 , Chipset = Ks077
Config Lcdpin = Pin , Rs = Portc.0 , E = Portc.1 , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5
Config Lcdmode = Port

Dim Tulcsordulas As Word
Dim Timerertek As word
Const Szamlalo = 15537 'a timernek 49998 órajel kell a túlcsorduláshoz (így egy túlcsordulás 0,1 mp)



Tulcsordulas = 0

On Timer1 Tulcsordul
On Int0 Allj
On Int1 Indit



Enable Interrupts
Enable Timer1
Stop Timer1
Timer1 = Szamlalo
Disable Int0
Enable Int1


Cls
Initlcd
Cls
Initlcd
Cursor Off

Lcd "Kesz!"

Do
Loop

End

Tulcsordul:
  Stop Timer1
  Timer1 = Szamlalo
  Tulcsordulas = Tulcsordulas + 1
  Start Timer1
Return

Indit:
  Timer1 = Szamlalo
  Start Timer1
  Cls
  Lcd "Meres"
  Disable Int1
  Enable Int0
  Gifr = 64
Return

Allj:
  Stop Timer1
  Disable Int0
  Gosub Kiiras:
  Gifr = 128
Return

Kiiras:
  Cls
  Timerertek = Timer1
  Locate 1 , 1
  Lcd "Tulcs.: " ; Tulcsordulas 'kiírja, hogy hány túlcsordulás volt
  Locate 2 , 1
  Lcd "Timer: " ; Timerertek 'kiírja a timer értékét
  Timer1 = Szamlalo
  Tulcsordulas = 0
  Wait 5
  Cls
  Lcd "Kesz!"
  Enable Int1
Return


Van egy másik áramkör amivel teszteltem. A teszt áramkör PORTD.3-as lábát rákötöttem a mérő INT1-re, a PORTD.2-t rákötöttem az INT0-ra. A tesz áramkör programja:

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

$regfile = "attiny2313.dat"
$crystal = 4000000

Config Pind.2 = Output
Config Pind.3 = Output
Config Timer1 = Timer , Prescale = 8

Set Portd.2
Set Portd.3


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


Dim Tulcsordulas As Word
Const Szamlalo = 55543                               



On Timer1 Tulcsordulas:



Enable Interrupts
Enable Timer1
Stop Timer1

Timer1 = Szamlalo


Cls
Initlcd
Cls
Initlcd
Cursor Off


Lcd "Ready!"

Wait 3
Cls
Lcd "Start"

Start Timer1
Reset Portd.3
Waitms 10
Set Portd.3

Do
  'Set Portd.6
  'Waitms 500
  'Reset Portd.6
  'Waitms 500
Loop


End



Tulcsordulas:
  Timer1 = Szamlalo
  Tulcsordulas = Tulcsordulas + 1
  If Tulcsordulas = 5 Then Goto Ide:
  'Cls
  'Locate 2 , 1
  'Lcd Tulcsordulas
Return




Ide:
  Reset Portd.2
  Stop Timer1
  Waitms 10
  Set Portd.2
  Cls
  Lcd "Stop"
  Wait 5
Return


Ha a teszt programban Szamlalo = 55543, akkor a mérő kijelzőn ezek az értékek: Tulcs.: 1, Timer: 15551 (ez rendben van).
Ha a Szamlalo = 55544, akkor a mérő kijelzőn ezek az értékek: Tulcs.: 0, Timer: 4. (Ez a probléma nem mér túlcsodulást látszik hogy a timer átpördült, mivel az értéke 4, de nincs túlcsordulás!).
Ha Szamlalo = 55545, akkor Tulcs.: 0, Timer: 65535 (ami így rendben van).
Hogyan lehet megoldani? A válaszokat előre is köszi!
Bence

Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3349
Csatlakozott: 2008. augusztus 29. péntek, 6:00
Tartózkodási hely: Újkígyós

HozzászólásSzerző: kapu48 » 2009. június 25. csütörtök, 19:02

Első tanács: megszakításból vegyél ki minden LCD-re írást.
2.: Használj a megszakításban jelző biteket, ha kikel írni bebillented.
3.: Do – Loop -ban írjál LCD-re.
4.: Itt figyeled a jelzőt, ha kel kiírsz . Így nem áll meg a megszakítás kiírás közben.
Mert do – loop -ból el tudja kérni a vezérlést.
Ha megtörtént a kiírás visszabillented a jelzőt és jöhet az újabb ciklus.
Ha ez megvan, jöhetsz újra tanácsért!
:wink:


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