megszakítások !! egy pici elakadás!

Hogyan programozzak AVR chipet? Programozók beállításai...
Bascom nyelvű programok...
Válasz küldése
Avatar
nobody_hun
Bitfaragó
Hozzászólások: 425
Csatlakozott: 2005. november 14. hétfő, 7:00

Hozzászólás Szerző: nobody_hun »

Nos akkor az első szabály:
Először feltételt vizsgálunk, ha azon átmegy, akkor változtatjuk a fényerőt:

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

M1:
'Ha teljes fényerő, akkor nem kell csinálni semmit, vissza a főprogramba
If Feny=255 Then Goto Main
'Ha nem max a fényerő, akkor növeljük a fényerőt maximumig
Do 
Feny = Feny + 1 
Pwm0b = Feny 
If Feny > 255 Then Goto Main 
Waitms 8 
Loop 
Goto Main 
Főprogramban is előbb feltételt vizsgálunk, majd azután ugrálunk a megfelelő helyre:

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

Main: 

Do 
   If Pinb.2 = 0 Then
'Kell-e egyáltalán növelni a fényerőt?
If Feny<255 Then
   Waitms 200 
      Do 
         If Pinb.2 = 0 And A = 0 Then 
            A = 1 
            Goto M1 
         End If 
'Do-Loopból kilehet lépni Exit-tel, nem pazaroljuk a memóriát
         If Pinb.2 = 1 Then Exit Do 
         A = 1 
      Loop
End If
   End If 

   If Pinb.2 = 1 Then 
      A = 0
'Ha nincs megnyomva a gomb, akkor megnézzük, hogy kell-e csökkenteni a fényerőt?
      If Feny>0 Then Goto M2 
   End If
Loop 
Az M2 rendben van szerintem.

PS: Robert elvitt a határig, járunk-e már Nizzánál?
"Az IC-k füsttel működnek. Ha kijön belőlük a füst, nem működnek tovább." - ismeretlen szerző
"Az ID:FFFFFF egyenlő az Atmel még nem kiadott processzorával."
Avatar
szepnorbee
Bitmanipulátor
Hozzászólások: 122
Csatlakozott: 2009. augusztus 31. hétfő, 6:00

Hozzászólás Szerző: szepnorbee »

Köszi szépen! Megérkeztünk!! :)

Még egy csibeszájat kellett kicserélni egenlőre, mert túl tudott csordulni a fény változóm 256-ra.

Íme a kód:

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

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

Dim A As Bit
Dim Ok As Bit
Dim Feny As Integer
A = 0


Config Portb.1 = Output                                     'pwm
Config Pinb.2 = Input                                       'kapcs

Config Timer0 = Pwm , Prescale = 64 , Compare B Pwm = Clear Up
Enable Timer0

Main:

Do
   If Pinb.2 = 0 Then
'Kell-e egyáltalán növelni a fényerőt?
If Feny < 255 Then
   Waitms 200
      Do
         If Pinb.2 = 0 And A = 0 Then
            A = 1
            Goto M1
         End If
'Do-Loopból kilehet lépni Exit-tel, nem pazaroljuk a memóriát
         If Pinb.2 = 1 Then Exit Do
         A = 1
      Loop
End If
   End If

   If Pinb.2 = 1 Then
      A = 0
'Ha nincs megnyomva a gomb, akkor megnézzük, hogy kell-e csökkenteni a fényerőt?
      If Feny > 0 Then Goto M2
   End If
Loop


M1:
'Ha teljes fényerő, akkor nem kell csinálni semmit, vissza a főprogramba
If Feny = 255 Then Goto Main
'Ha nem max a fényerő, akkor növeljük a fényerőt maximumig
Do
Feny = Feny + 1
Pwm0b = Feny
If Feny = 255 Then Goto Main
Waitms 8
Loop
Goto Main

M2:
Do
Feny = Feny - 1
Pwm0b = Feny
If Feny = 0 Then Goto Main
Waitms 8

Loop
A hozzászólást 1 alkalommal szerkesztették, utoljára szepnorbee 2011. január 20. csütörtök, 13:29-kor.
Avatar
ampervadasz
Bitmanipulátor
Hozzászólások: 119
Csatlakozott: 2008. január 19. szombat, 7:00

Hozzászólás Szerző: ampervadasz »

Szervusztok AVR istenei!

Pici gondokkal küszködök egy M88-as kontrollerrel. Ha jól tudom 2 INT lába van ennek a típusnak, meg egy csomó PCINT lába. Az INT lábak figyelését meg tudom oldani, viszont BASCOM alól a PCINT-t hogyan tudom leprogramozni?
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Bascom/Samples/PCINT.bas :P
Avatar
ampervadasz
Bitmanipulátor
Hozzászólások: 119
Csatlakozott: 2008. január 19. szombat, 7:00

Hozzászólás Szerző: ampervadasz »

Robert írta:Bascom/Samples/PCINT.bas :P
Már vagy 100-szor átnéztem különböző problémák miatt a SAMPLE könyvtárat... bezzeg most!
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

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

'---------------------------------------------------------------------------
'                       (c) 1995-2005, MCS Electronics
'                             PCINT_CHANGE.BAS
' This sample shows how to use the PC interrupts
'---------------------------------------------------------------------------

$regfile = "m88def.dat"
$crystal = 8000000
$baud = 19200

Print "{027}[2J";                                           ' when you have a terminal emulator, this will clear the screen
Print "Test M88 ints"                                       ' init message

'The M88 and M168 can detect a level change on all port pins.
'We will just check on portB, pins 0-3

Config Portb = Input
Portb = &HF                                                 'activate pull up

Enable Interrupts                                           'enable global ints
Enable Pcint0                                               'we enable pcint0 as this has pcint0-pcint7
On Pcint0 Isr_pcint0                                        'we jump to this label when one of the pins is changed
Pcmsk0 = &B00001111                                         'enable pcint0-pcint3  (portb.0-portb.3)
'With pcmsk you individual select which pins must react on a logic level
'When you write a 1, the change in logic level will be detected.

Do
  nop
  'you can do anything here
  'But we show how to use the pin level change in manual mode without interrupts
  'Say we want to detect logic level change of pin 23, (PINC.0) / INT8
  Config Pinc.0 = Input                                     'you can also detect output changes but we use input
  Pcmsk1 = &B00000001                                       ' enable the bit of PCINT8 which is in PCMSK1
  If Pcifr.pcif1 = 1 Then                                   ' change detected
      Print "pinc.0 has changed"                            'in this case it must be pinc.0
      Pcifr.pcif1 = 1                                       ' write a 1 to clear the flag so we can detect it again
  End If
Loop


Isr_pcint0:
  Print "Pin change " ; Bin(pcmsk0) ; Spc(3) ; Bin(pinb)
  'As you see the mask does not change, so to find out which pin changed,
  'you need to read the PINB register.
Return

End
Avatar
szepnorbee
Bitmanipulátor
Hozzászólások: 122
Csatlakozott: 2009. augusztus 31. hétfő, 6:00

Hozzászólás Szerző: szepnorbee »

Újabb problémával jelentkezem, mert sajnos nem tudom megoldani. Még egy utolsó opciót szeretnék tenni a programomba, miszerint ha a gomb be van nyomva (vagyis M2 bekapcsolta a ledet), akkor induljon egy számláló, ami minden megszakításkor növeli a 'Ido' változó értékét. Ha 'Ido' értéke 750, akkor M2: programrészre ugorjon és benyomott gombállapottól függetlenül sötétedjen el a led. Így valósítottam meg, sajnos sikertelenül:

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

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

Dim A As Bit
Dim Ok As Bit
Dim Feny As Integer
A = 0

'Timer1
Dim Ido As Integer
Ido = 1
Dim B As Byte
B = 1

'Timer1

Config Portb.1 = Output                                     'pwm
Config Pinb.2 = Input                                       'kapcs

Config Timer0 = Pwm , Prescale = 64 , Compare B Pwm = Clear Up
Enable Timer0

'Timer1
Config Timer1 = Timer , Prescale = 1024

On Timer1 Novel
Enable Timer1
Enable Interrupts
'Timer1


Main:

Do
   If Pinb.2 = 0 Then
'Kell-e egyáltalán növelni a fényerőt?
If Feny < 255 Then
   Waitms 200
      Do
         If Pinb.2 = 0 And A = 0 Then
            A = 1
            Goto M1
         End If
'Do-Loopból kilehet lépni Exit-tel, nem pazaroljuk a memóriát
         If Pinb.2 = 1 Then Exit Do
         A = 1
      Loop
End If
   End If

   If Pinb.2 = 1 Then
      A = 0
'Ha nincs megnyomva a gomb, akkor megnézzük, hogy kell-e csökkenteni a fényerőt?
      If Feny > 0 Then Goto M2
   End If
Loop


M1:
Start Timer1

'Ha teljes fényerő, akkor nem kell csinálni semmit, vissza a főprogramba
If Feny = 255 Then Goto Main
'Ha nem max a fényerő, akkor növeljük a fényerőt maximumig
Do
Feny = Feny + 1
Pwm0b = Feny
If Feny = 255 Then Goto Main
Waitms 8
Loop

Goto Main

M2:
Stop Timer1
Ido = 1

Pwm0b = 255
Wait 6

Do
Feny = Feny - 1
Pwm0b = Feny
If Feny = 0 Then Goto Main
Waitms 8

Loop


'Timer1
Novel:

Ido = Ido + 1

If Ido = 750 Then Goto M2
'Timer1

Return
A hibajelenség, hogy semmi nem változik 'Feny' feltétel teljesülésekor.
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

Már 1001* leírtuk „MEGSZAKÍTÁSBÓL NEM LEHET KIUGRANI!”
Mert verem túlcsordulást okoz, és a további megszakítások letiltva maradnak!
8O 8O 8O

Az idő túllépést, tessék valahol a főprogramban vizsgálni!
8)

És nagyon ajánlanám ezt az összevissza GOTO-zást felejtsd el!
Illetve jobb lenne, ha rá sem szoknál!
Én 1000 sor programot is megírok 1etlen GOTO nélkül!
Tessék úgy szervezni a programot, hogy ne legyenek benne felesleges ugrálások!
Mert ilyen stílusban lehetetlen lesz a későbbi hibakeresést megoldani!
:!:
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Gosub-Return részről GOTO kiugrás NINCS!

Do-Loopból sem. Ott max ExitDo van. For-Next alapon is csak ExitFor!

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

Config Pinb.2 = Input                                       'kapcs 
NINCS!
PortB.2 van!

Szóval a javaslat:
Program kidob.

Szubrutinban a fény növelést/csökkentsét.
Nem Gotoval ugrálunk hanem jelzőbit és annak megfelelően rutinhívás.
Avatar
szepnorbee
Bitmanipulátor
Hozzászólások: 122
Csatlakozott: 2009. augusztus 31. hétfő, 6:00

Hozzászólás Szerző: szepnorbee »

Sziasztok. Na itt az új programom (Sirleslie alapkódja átalakítva a váza)

Adtam hozzá olyat ,hogy ha nyomom a gombot és Ido > 750 akkor kapcsolja le a lámpát (OCR0B = 0) , de sajnos nem teszi. Idő leteltekor nem csinál semmit. Lehet azért mert többször is ráfut a Start Timer1 parancsra? Help

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

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

' pwm beállítása
Config Timer0 = Pwm , Prescale = 64 , Compare B Pwm = Clear Up
'időzítő
Config Timer1 = Timer , Prescale = 1024

Config Portb.1 = Output                                     'pwm kimenet
Config Pinb.2 = Input                                       'ajtókapcsoló

Dim Ajtozaras As Bit
Dim A As Byte
'időzítő
Dim Ido As Integer
Ido = 1

Config Int0 = Rising
On Int0 Ajtokapcsolo
On Timer1 Novel                                             'időzítő
Enable Int0

Enable Timer0
Enable Timer1
Start Timer0
Start Timer1
Enable Interrupts

Ocr0b = 0

Do
If Ido > 750 Then
      Ocr0b = 0
      Ido = 1
      Stop Timer1
    End If
If Pinb.2 = 0 And Ido < 750 Then                            ' ajtonyitáskor...
   Start Timer1
   Ocr0b = 255
   Waitms 10

      If Ajtozaras = 1 And Pinb.2 = 1 Then                  ' ajtózáráskor...

          Wait 5                                            ' lámpa késleltetés

            For A = 255 To 1 Step -1

              Ocr0b = A
              Waitms 10

              If Pinb.2 = 0 Then Exit For                   ' esetleges ajtónyitáskor kilép

            Next A

            Reset Ajtozaras

          Ocr0b = 0
          Stop Timer1
      End If

End If
nop

Loop



Ajtokapcsolo:

  Set Ajtozaras

Return

Novel:

Incr Ido

Return
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

Nem egészen világos! Mikor mit is akarsz tenni?

Ezen az egy PB.2 = INT0 bemeneten akarod vezérelni a Nyitás ,Zárást, Lámpaoltást?

Kellenének jelző Bitek, hogy tudjad hól, tartasz.
Nyitás > Nyitva = 1
Zárás > Zárva = 1
Lámpaoltás > Nyitva = 0, Zárva = 0

És ezeket a jelzőket figyelve döntöd el melyik művelet következik!
Hogy mind csak 1* fusson le.
Például lámpaoltás megtörtént de még mindig nyomják a gombot?
Akkor ügye ráfut a zárásra! Itt kellene figyelni, hogy elengedték a gombot?
Csak aztán tovább meni.

Persze ez csak vázlat, jobban átkel gondolnod a folyamatot!
Avatar
SirLeslie
Pákabűvész
Hozzászólások: 247
Csatlakozott: 2005. április 14. csütörtök, 6:00

Hozzászólás Szerző: SirLeslie »

szepnorbee írta:Sziasztok. Na itt az új programom (Sirleslie alapkódja átalakítva a váza)

Adtam hozzá olyat ,hogy ha nyomom a gombot és Ido > 750 akkor kapcsolja le a lámpát (OCR0B = 0) , de sajnos nem teszi. Idő leteltekor nem csinál semmit. Lehet azért mert többször is ráfut a Start Timer1 parancsra? Help

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

Config Timer1 = Timer , Prescale = 1024
Ebben timer1 beállításban több mint 1mp-ként indul újra a megszakítás (ha jól emlékszem)... kivárod a legalább 750mp időt? Tegyél ledet/ledmeghajtást a T1 rutinjába.
Továbbá nem nullázod ki sehol a itt növelt változó értékét (vagy nem vettem észre, így hirtelen ;-) ), ajtózárás illetve időtúlfutás esetén kellene.
Avatar
szepnorbee
Bitmanipulátor
Hozzászólások: 122
Csatlakozott: 2009. augusztus 31. hétfő, 6:00

Hozzászólás Szerző: szepnorbee »

a tiny45-ben a timer1 is 8 bites, szóval eléggé gyorsan túlcsordul. Itt fut fél napja élesben a programom az asztalon és mégse alszik el. Szal tuti kivártam már :D A dolog már működik, csak az időmérés nem jó valamiért. Emiatt nem akarnám újraírni :S Főleg ha én írom csak rosszabb lesz. Nem nagyon látom át még ezeket a jelzőbiteket, nagyon belekavarodok. Pedig szeretném megtanulni.
Avatar
SirLeslie
Pákabűvész
Hozzászólások: 247
Csatlakozott: 2005. április 14. csütörtök, 6:00

Hozzászólás Szerző: SirLeslie »

szepnorbee írta:a tiny45-ben a timer1 is 8 bites, szóval eléggé gyorsan túlcsordul. Itt fut fél napja élesben a programom az asztalon és mégse alszik el. Szal tuti kivártam már :D
oké... nem emlékeztem rá ;-)

Akkor csinálj külön egy csak timer kezelő/tesztelő programot, ami ledet aktivál...aztán ha kész, akkor csak be kell illeszteni a többi közé.
Avatar
szepnorbee
Bitmanipulátor
Hozzászólások: 122
Csatlakozott: 2009. augusztus 31. hétfő, 6:00

Hozzászólás Szerző: szepnorbee »

Pontosan így tettem. Működik is! Olyan 30 mp alatt állapotot vált a led. (direkt ilyen kevés most)

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

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

Dim Feny As Integer
Feny = 1

Led Alias Portb.1
Config Led = Output

Config Timer1 = Timer , Prescale = 1024

On Timer1 Novel
Enable Timer1
Enable Interrupts
Start Timer1

Main:

Do
'nop
Loop


Novel:

Feny = Feny + 1

If Feny = 750 Then Goto Pulse

Return

Pulse:

Toggle Led

Return
Csak képtelen vagyok belekeverni az eredeti progiba. Tudom a DO...LOOP-ban is figyelhetném Feny értékét és akkor nemkéne a GOTO, bár az csak apróság ebben a példában.
Válasz küldése