Přetečení SRAM

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Odpovědět
Zpráva
Autor
Uživatelský avatar
Vojrik
Příspěvky: 8
Registrován: 03 bře 2012, 00:00

Přetečení SRAM

#1 Příspěvek od Vojrik »

Zdravím. Požívám mikroprocesor atmega32 a mám problémy s zaplněním paměti, která se při každé další smyčce programu víc zapňuje místo toho, aby se jen přepsala....následuje pád programu. Nevíte někdo co s tím? Napadlo mě donutit ho nějak, aby při zaplnění začal paměť přepisovat zase od začátku, ale nemám tušení, jak na to. Dík za radu :wink:
Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 00:00

#2 Příspěvek od Andrea »

"On" dělá jen to, co ty mu v programu řekneš, aby dělal. A co mu v tom programu říkáš, víš jen ty.
Uživatelský avatar
Vojrik
Příspěvky: 8
Registrován: 03 bře 2012, 00:00

#3 Příspěvek od Vojrik »

nevím, jestli se v tom někdo vyzná, ale když to řeknu stručně, tak různým servům přiřazuji proměnné. Pokud se nerovná požadované hodnotě, tak skočí na část programu, kde se zvýší nebo zmenší o 1 po 5 ms intervalech (abych dosáhl zpomalení otáčení serv,které jakoby krokuje po 5ti ms)...jakmile jsou podmínky splněny, tak skočí dál, kde chci přiřadit proměnným jiné hodnoty a tak zase přičítá nebo odečítá. Tohle všechno pak dělá stále dokola, ale zároveň přitom pořád zaplňuje paměť, dokud není plná, pak se sekne a zblázní. Přikládám program a hned se neděste, bylo to už mnohokrát přepisováno...ve výsledku by to měl být robot.



$regfile = "m32def.dat" ' mikroprocesor
$crystal = 16000000 ' frekvence v Hz


Config Servos = 12 , Servo1 = Portd.0 , Servo2 = Portd.1 , Servo3 = Portd.2 , Servo4 = Portd.3 , Servo5 = Portd.4 , Servo6 = Portd.5 , Servo7 = Portc.2 , Servo8 = Portc.3 , Servo9 = Portc.4 , Servo10 = Portc.5 , Servo11 = Portc.6 , Servo12 = Portc.7 , Reload = 10
Config Portd.0 = Output
Config Portd.1 = Output
Config Portd.2 = Output
Config Portd.3 = Output
Config Portd.4 = Output
Config Portd.5 = Output
Config Portc.2 = Output
Config Portc.3 = Output
Config Portc.4 = Output
Config Portc.5 = Output
Config Portc.6 = Output
Config Portc.7 = Output
Config Porta.7 = Output ' nastavení portů --> IN, OUT

Led Alias Porta.7 ' přiřazení názvu ---> LED na PORTA.7

Enable Interrupts ' povolení přerušení
' proměnná
Dim Nskd As Byte ' proměnná
Dim Nskm As Byte ' proměnná
Dim Nskc As Byte ' proměnná
Dim Nskk As Byte ' proměnná
Dim Nskp As Byte ' proměnná
Dim Nskl As Byte ' proměnná
Dim Psc As Byte ' proměnná --> směrovací číslo návěstí

Declare Sub Rozcest ' návěstí --> rozcestí
Declare Sub Postaveni ' návěstí
Declare Sub Postaveni_jedna ' návěstí
Declare Sub Postaveni_dva ' návěstí
Declare Sub Postaveni_tri ' návěstí
Declare Sub Postaveni_ctyri ' návěstí
Declare Sub Sed ' návěstí
Declare Sub Sed_jedna ' návěstí
Declare Sub Sed_dva ' návěstí
Declare Sub Sed_tri ' návěstí
Declare Sub Nskm_plus ' návěstí
Declare Sub Nskm_minus ' návěstí
Declare Sub Nskc_plus ' návěstí
Declare Sub Nskc_minus ' návěstí
Declare Sub Nskk_plus ' návěstí
Declare Sub Nskk_minus ' návěstí

'-------------------------------- program --------------------------------------
Nskd = 34 ' přiřazení hodnot proměnným ---> min. krajní výchylka serva
Nskm = 81 ' přiřazení hodnot proměnným ---> střední poloha serva
Nskc = 143 ' přiřazení hodnot proměnným ---> max. krajní výchylka serva
Nskp = 95 ' přiřazení hodnot proměnným ---> natočení serva ke konci
Nskk = 120 ' přiřazení hodnot proměnným ---> natočení serva ke konci
Nskl = 107 ' přiřazení hodnot proměnným ---> natočení serva ke konci

Rozcest:
Sed:
Psc = 1 'psc návěstí sed je 1
Servo(1) = Nskm
Servo(4) = Nskm + 7
Servo(7) = Nskm
Servo(10) = Nskm
Servo(2) = Nskc - 5
Servo(5) = Nskc
Servo(8) = Nskc - 7
Servo(11) = Nskc
Servo(3) = Nskk
Servo(6) = Nskk - 5
Servo(9) = Nskk - 7
Servo(12) = Nskk + 5 ' přiřazení proměnných servův
Sed_jedna:
Psc = 2 ' psc návěstí sed1 je 2
If Nskm < 81 Then Nskm_plus: ' pokud je nskm < 81 skoč na nskm_plus
If Nskm > 81 Then Nskm_minus: ' pokud je nskm > 81 skoč na nskm_minus
Sed_dva:
Psc = 3 ' psc návěstí sed2 je 3
If Nskk < 117 Then Nskk_plus: ' pokud je nskk < 120 skoč na nskk_plus
If Nskk > 117 Then Nskk_minus: ' pokud je nskk > 120 skoč na nskk_minus
Sed_tri:
Psc = 4 ' psc návěstí sed3 je 4
If Nskc < 143 Then Nskc_plus: ' pokud je nskc < 143 skoč na nskc_plus
If Nskc > 143 Then Nskc_minus: ' pokud je nskc > 143 skoč na nskc_minus
Wait 1 'čekání na nastavení serv
Goto Postaveni: ' když jsou splněny podmínky výše, skoč na návěstí...

'-------------------------------------------------------------------------------

Nskm_plus:
Incr Nskm
Waitms 5
If Psc = 2 Then Sed_dva: ' nskm + 1,počkej pár ms a podle psc skoč dál

Nskm_minus:
Decr Nskm
Waitms 5
If Psc = 2 Then Sed_dva: ' nskm - 1,počkej pár ms a podle psc skoč dál

Nskc_plus:
Incr Nskc
Waitms 5
If Psc = 4 Then Sed:
If Psc = 9 Then Postaveni_dva: ' nskc + 1,počkej pár ms a podle psc skoč dál

Nskc_minus:
Decr Nskc
Waitms 5
If Psc = 4 Then Sed:
If Psc = 9 Then Postaveni_dva: ' nskc - 1,počkej pár ms a podle psc skoč dál

Nskk_plus:
Incr Nskk
Waitms 5
If Psc = 3 Then Sed_tri:
If Psc = 6 Then Postaveni:
If Psc = 8 Then Postaveni_ctyri: ' nskk + 1,počkej pár ms a podle psc skoč dál

Nskk_minus:
Decr Nskk
Waitms 5
If Psc = 3 Then Sed_tri:
If Psc = 6 Then Postaveni:
If Psc = 8 Then Postaveni_ctyri: ' nskk - 1,počkej pár ms a podle psc skoč dál
Goto Nskk_minus

'-------------------------------------------------------------------------------

Postaveni:
Psc = 5 ' psc návěstí postaveni je 5
Servo(3) = Nskk
Servo(6) = Nskk - 5
Servo(9) = Nskk - 7
Servo(12) = Nskk + 5
Postaveni_jedna:
Psc = 6 ' psc návěstí postaveni je 6
If Nskk < 110 Then Nskk_plus: ' pokud je nskk < 110 skoč na nskk_plus
If Nskk > 110 Then Nskk_minus: ' pokud je nskk > 110 skoč na nskk_minus
Waitus 200
Postaveni_dva:
Psc = 7
Servo(2) = Nskc - 5
Servo(5) = Nskc
Servo(8) = Nskc - 7
Servo(11) = Nskc
Servo(3) = Nskk
Servo(6) = Nskk - 5
Servo(9) = Nskk - 7
Servo(12) = Nskk + 5
Postaveni_tri:
Psc = 8 ' psc návěstí postaveni je 8
If Nskk < 95 Then Nskk_plus: ' pokud je nskk < 95 skoč na nskk_plus
If Nskk > 95 Then Nskk_minus: ' pokud je nskk > 95 skoč na nskk_minus
Postaveni_ctyri:
Psc = 9 ' psc návěstí postaveni je 9
If Nskc < 95 Then Nskc_plus: ' pokud je nskc < 95 skoč na nskc_plus
If Nskc > 95 Then Nskc_minus: ' pokud je nskc > 95 skoč na nskc_minus
Wait 1
Goto Rozcest:

End
Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 00:00

#4 Příspěvek od Andrea »

Já tedy v Bascomu neprogramuju, ale předpokládám, že když napíšeš
If Nskc < 95 Then Nskc_plus:
Tak to Nsck_plus je volání procedury s tím názvem (nikoliv skok, ten je GOTO) a protože ta procedura není nikde ukončená (není napsaná jako procedura), nedojde k uvolnění návratové adresy ze zásobníku a ten se postupně zaplňuje až zaplní celou paměť.
Uživatelský avatar
Vojrik
Příspěvky: 8
Registrován: 03 bře 2012, 00:00

#5 Příspěvek od Vojrik »

to už jsem ověřil a tím to není ...dělá to příkaz DECR, proměnná (1 - preměnná) a INCR; proměnná (1+ proměnná) ...tyhle dva příkazy mi neustále zaplňují paměť, jak jsem před chvílí zjitil
Uživatelský avatar
Crifodo
Příspěvky: 14779
Registrován: 11 říj 2005, 00:00

#6 Příspěvek od Crifodo »

Vojrik píše:Napadlo mě donutit ho nějak, aby při zaplnění začal paměť přepisovat zase od začátku

A nebylo by lepší postavit program tak, aby k žádnému zaplnění nedocházelo a program korektně pracoval s proměnnými, jak má?
Ty deklaruješ podprogramy, ale v programu je nemáš definovány jako
Sub
..........
..........
End Sub,
takže jako by tam nebyly a ty názvy jsou tam fakt jen jako labely, nic víc. Příslušná pasáž programu pokračuje jen podle podmínky. Návrat z podprogramu za původní příkaz se nikdy nekoná.
K definování jednotlivých bitů portu n je příkaz Config PINn.x, příkaz Config PORTn nastaví všechny bity v portu.
nebo nastav celý port příkazem DDRn =&Bxxxxxxxx , n je název portu, x=1 je výstup, 0 je vstup
Uživatelský avatar
AB1
Příspěvky: 312
Registrován: 23 lis 2009, 00:00

#7 Příspěvek od AB1 »

to už jsem ověřil a tím to není

Jistěže je. Stačí v simulátoru sledovat jak pěkně roste stack.

Celý program mi svým stylem připomíná první programy které se začaly objevovat v Amatérském rádiu někdy v sedmdesátých letech.

Basic udělal od té doby značný pokrok.
Dnes už není třeba poskakovat po kódu sem a tam příkazem goto.

Příklad zápisu programu:
(Všimni si jak správně napsat proceduru.)

Kód: Vybrat vše

$regfile = "m8def.dat"
$crystal = 8000000
$hwstack = 68
$swstack = 32
$framesize = 32

'deklarace proměnných
Dim I As Long

'deklarace procedur a funkcí
Declare Sub Cekej             ' deklarace procedury Cekej

 ''''''''''''''' HLAVNI PROGRAM '''''''''''''''''''''''''''''''''''''''''''''''
    'různé konfigurace,
    'kód který se nemusí opakovat při každém běhu hlavní smyčky
    Config Portb.1 = Output

    '--------------------------------------------------------------------------
    Do                        ' hlavní smyčka Do-Loop
      Set Portb.1
      Cekej                   ' nebo Call Cekej
      Reset Portb.1
      Cekej
    Loop                      ' jdi na Do

 ''''''''''''''' KONEC HLAVNIHO PROGRAMU ''''''''''''''''''''''''''''''''''''''
 End
'kód podprogramů, procedur a funkcí píšeme až za koncové "End"

'procedura Cekej
Sub Cekej
   For I = 1 To 200000
   Next
End Sub
Uživatelský avatar
Vojrik
Příspěvky: 8
Registrován: 03 bře 2012, 00:00

#8 Příspěvek od Vojrik »

Máte pravdu, tak Vám děkuji, už to konečně funguje a já se můžu pustit do chůze :D :D :D ...snad se povede
Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“