Stránka 1 z 1
Přetečení SRAM
Napsal: 03 bře 2012, 08:12
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

Napsal: 03 bře 2012, 08:26
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.
Napsal: 03 bře 2012, 08:33
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
Napsal: 03 bře 2012, 09:03
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ěť.
Napsal: 03 bře 2012, 09:10
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
Napsal: 03 bře 2012, 10:05
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
Napsal: 03 bře 2012, 16:57
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
Napsal: 03 bře 2012, 18:57
od Vojrik
Máte pravdu, tak Vám děkuji, už to konečně funguje a já se můžu pustit do chůze

...snad se povede