PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : mehrere "Dateien" auf atmega speichern



Snaper
02.05.2010, 09:48
OK gegebenes Setup ist folgendes:
-Atmega32
-16Mhz Quarz

Und zwar ist es so, dass ich ein Main-Programm habe welches ein paar Schemata abrattert. Er geht also nach Tabellen und kann so verschiede Schemata abarbeiten. Nun habe ich dass Problem, dass ich bisher immer nur ein Schema implementieren konnte. Dies habe ich gemacht indem ich eine txt datei in Bascom included habe welche über Data eine Tabelle der Main zu verfügung stellt. Nun würde ich aber gerne verschiedene Tabellen einbringen, die im Betrieb umgeschaltet werden. Wie mache ich das? Include ich einfach noch mehr Textfiles und Schalte die Tabellen über Variablen durch oder können sie anders gespeichert werden? Nun möchte ich wie gesagt im Betrieb Modis umschalten können, nun ist aber mein Problem, dass bedingt durch die Tatsache meine Main-Loop hauptsächlich zugange ist meine Taster "debounce" funktion blockiert wird und nur jeder 3-4 Tastendruck erkannt wird. Wie kann man dies am besten ändern?

Also im letztlich 2 Fragen:
1. Wie kann ich verschiedene Tabellen und somit auch Schemata auf den mega32 laden ?
2. Wie kann ich sowohl Tabellen als auch komplette Modis damit meine ich einen wechsel der Mainloop z.b. von Funkgesteuert auf autonom mit Hilfe eines Tasters umschalten ohne dass meine Main mich blockt?

Wäre über Tipps äußerst dankbar.
Gruß,
Snaper

for_ro
02.05.2010, 11:00
1. Wie kann ich verschiedene Tabellen und somit auch Schemata auf den mega32 laden ?
Die Werte der Data Befehle liegen nachher im Flash. Du kannst also soviele Werte abspeichern, wie du noch Flash frei hast.
Unterteilne kannst du dies durch verschiedene Label, bei denen du die zusammengehörigen Daten findest. Also so:
Tabelle_1:
Data ...
Data ...
Tabelle_2:
Data ...
Data ...

Im Programm kannst du dir auch die Startadressen der Tabellen merken und diese als Offset in eine große Tabelle verwenden.
Tabelle:
Data ... '1. Tabelle 10 Werte
Data ... '1. Tabelle 10 Werte
Data ... '2. Tabelle 10 Werte

Offset(1)=0
Offset(2)=20


2. Wie kann ich sowohl Tabellen als auch komplette Modis damit meine ich einen wechsel der Mainloop z.b. von Funkgesteuert auf autonom mit Hilfe eines Tasters umschalten ohne dass meine Main mich blockt?
Debounce hat die unangenehme Eigenschaft, die Ausführung zu blockieren, wenn die Bedingung der Taste erfüllt ist. Und zwar solange, wie mit Config Debounce festgelegt ist.
Wenn du dies umgehen willst, kannst du einen Timer laufen lassen und die zu überwachenden Pins dort abfragen. Haben die dann mehrfach ihren Zustand gehalten, hat der Taster die Prellphase beendet. Die Unterbrechung durch den Interrupt sollte immer noch kürzer sein als mit Debounce.

Snaper
02.05.2010, 11:10
Okay, das mit den Tabellen klingt schonmal gut. Einziges Problem wird sein, dass ich während des kompilierens die Anzahl und Namen der Tabellen bekannt sein müssen und von Hand includiert werden müssen, oder sehe ich das falsch?



Debounce hat die unangenehme Eigenschaft, die Ausführung zu blockieren, wenn die Bedingung der Taste erfüllt ist. Und zwar solange, wie mit Config Debounce festgelegt ist.
Wenn du dies umgehen willst, kannst du einen Timer laufen lassen und die zu überwachenden Pins dort abfragen. Haben die dann mehrfach ihren Zustand gehalten, hat der Taster die Prellphase beendet. Die Unterbrechung durch den Interrupt sollte immer noch kürzer sein als mit Debounce.

Okay also wenn ich das jetzt richtig verstanden habe, dann setze ich einen Timer in dem ich den Status des Pins abfrage, richtig? Habe ich dann nicht das Problem, dass sofern ich eine Variable erhöhe eine 2-x malige erhöhung durch längeren drückens des Schalters möglich ist? Denn genau dies würde ich gerne vermeiden. Oder habe ich etwas falsch verstanden? Tut mir leid dass ich so doofe Fragen stelle aber in Basic bin ich relativ ahnungslos.

for_ro
02.05.2010, 12:10
Einziges Problem wird sein, dass ich während des kompilierens die Anzahl und Namen der Tabellen bekannt sein müssen und von Hand includiert werden müssen, oder sehe ich das falsch?
Klar, aber ist das ein Problem? Was meinst du mit "... von Hand includiert werden ..."?


Habe ich dann nicht das Problem, dass sofern ich eine Variable erhöhe eine 2-x malige erhöhung durch längeren drückens des Schalters möglich ist?
Das kannst du verhindern, indem du feststellst, ob der Taster nach Erkennung des einen Zustands auch einmal den anderen für einen längeren Zeitraum angenommen hat.
Z.B. so:
Du setzt den aktuellen Wert z.B. eine 1 in eine Variable in Bit 0 rein. (Variable.0 = Pinx.y)
Dann überprüfst du, ob du 8 mal den gleichen Wert bekommen hast, also alle Bits 1 sind (Variable = 255, oder 0, falls gerade dauernd 0 kommen). [list:9db8242986]Wenn der Taster prellt, wirst du evtl. auch mal eine 0 mit drin haben.Dann schiebst du den Wert der Variable um eine Stelle nach links. (Shift Variable, Left)[/list:u:9db8242986]
Wenn dein Taster z.B. 20ms prellt und du jede ms den Timer aufrufst, hast du spätestens nach 28ms einen konstanten Wert. Hast du mehrere Taster, dauert es aber nicht länger, wie dies bei Debounce der Fall wäre.
Für diese Überprüfung benötigst du eine Variable zum Speichern der 8 Werte des Tasters und eine weitere, um den letzten erkannten Zustand zu speichern. Dadurch kannst du erkennen, ob sich der Taster geändert hat und vermeidest mehrfach Auslösen der Aktion.

Snaper
02.05.2010, 14:06
Und wie bewältige ich am besten das Problem, dass Lookup keine Variable akzeptiert sondern eine Tabelle haben möchte? Denn sonst müsste ich ja alle Lookups mehrfach einbauen und die entsprechenden Tabellennamen einbauen.

for_ro
02.05.2010, 15:53
Ich habe noch nicht so genau verstanden, wie dein Programm aussehen soll.
Aber oben habe ich dir beschrieben, wie du es mit einer großen Tabelle anstellen kannst. Dann brauchst du ja keinen variablen Tabellennamen.

Snaper
02.05.2010, 20:34
Problem ist dass ich mehrere Schema auf verschiedene .txt dateien aufgeteilt habe also ein schema pro textdatei. Wäre natürlich auch ne möglichkeit das alles in eine große zu laden und dann über Offsets zu arbeiten. Aber dann wird es denke ich wieder etwas umständlicher nur ein spezielles schema ablaufen zu lassen.

Snaper
13.05.2010, 20:41
Einziges Problem wird sein, dass ich während des kompilierens die Anzahl und Namen der Tabellen bekannt sein müssen und von Hand includiert werden müssen, oder sehe ich das falsch?
Klar, aber ist das ein Problem? Was meinst du mit "... von Hand includiert werden ..."?


Habe ich dann nicht das Problem, dass sofern ich eine Variable erhöhe eine 2-x malige erhöhung durch längeren drückens des Schalters möglich ist?
Das kannst du verhindern, indem du feststellst, ob der Taster nach Erkennung des einen Zustands auch einmal den anderen für einen längeren Zeitraum angenommen hat.
Z.B. so:
Du setzt den aktuellen Wert z.B. eine 1 in eine Variable in Bit 0 rein. (Variable.0 = Pinx.y)
Dann überprüfst du, ob du 8 mal den gleichen Wert bekommen hast, also alle Bits 1 sind (Variable = 255, oder 0, falls gerade dauernd 0 kommen). [list:8a53126868]Wenn der Taster prellt, wirst du evtl. auch mal eine 0 mit drin haben.Dann schiebst du den Wert der Variable um eine Stelle nach links. (Shift Variable, Left)[/list:u:8a53126868]
Wenn dein Taster z.B. 20ms prellt und du jede ms den Timer aufrufst, hast du spätestens nach 28ms einen konstanten Wert. Hast du mehrere Taster, dauert es aber nicht länger, wie dies bei Debounce der Fall wäre.
Für diese Überprüfung benötigst du eine Variable zum Speichern der 8 Werte des Tasters und eine weitere, um den letzten erkannten Zustand zu speichern. Dadurch kannst du erkennen, ob sich der Taster geändert hat und vermeidest mehrfach Auslösen der Aktion.

Wäre es möglich da einen kleinen Pseudocode zu bekommen? Denn so 100% habe ich es noch nicht verstanden... Frage mich auch wofür der Links Shift am ende dienen soll

for_ro
13.05.2010, 20:57
Dies ist nur ein Vorschlag für ein Entprellen einer Taste. Es gibt sicherlich noch zig andere Wege. Aber diese ist schnell und verursacht keine Wartezeit.

Du schiebst den aktuellen Wert des Pins in eine Variable und kontrollierst dann, ob z.B. 8 mal der gleiche Wert gekommen ist. Wenn ja machst du eine Aktion.


Port_Status.0 = Pina.0 'dies speichert den aktuellen Zustand in bit 0 ab
If Port_status = 255 Then '8 mal eine 1
If Port_status_alt = 0 Then 'vorher hatte er alles 0
Port_status_alt = 255 'neuen Status abspeichern
'irgendeine Aktion für Taster = 1
Endif
Elseif Port_status = 0 Then '8 mal eine 0
If Port_status_alt = 255 Then 'vorher hatte er alles 1
Port_status_alt = 0 'neuen Status abspeichern
'irgendeine Aktion für Taster = 0
End If
End If
Shift Port_status, Left 'schafft Platz für das nächste Abfragen

Wenn du dies in einer Timer Routine z.B. alle 1ms aus, dann hast du nach der Prellzeit des Tasters + 8ms eine Aktion.

Snaper
13.05.2010, 21:26
ahh okay. Jetzt wo ich es so sehe ist das alles total logisch.
Vielen dank.

Hättest du denn auch noch eine Idee für die Sache mit den Tabellen?
Also ich habe verschiedene Tabellen, gehen wir mal von 4 Stück aus.
Und es soll möglich sein, dass nur eine Tabelle verwendet wird, dabei kann nur eine Tabelle drüber bzw. drunter gewählt werden oder alle Tabellen hintereinander.

for_ro
13.05.2010, 21:52
Bei deinen tabellen, da sitze ich irgendwie auf der leitung. Da habe ich noch nicht verstanden, wo dein Problem ist.
Nehmen wir mal an, du hättest eine solche Tabelle mit 256 Werten:

Crc8_daten:
Data 0 , 94 , 188 , 226 , 97 , 63 , 221 , 131 , 194 , 156
Data 126 , 32 , 163 , 253 , 31 , 65 , 157 , 195 , 33 , 127
Data 252 , 162 , 64 , 30 , 95 , 1 , 227 , 189 , 62 , 96
Data 130 , 220 , 35 , 125 , 159 , 193 , 66 , 28 , 254 , 160
Data 225 , 191 , 93 , 3 , 128 , 222 , 60 , 98 , 190 , 224
Data 2 , 92 , 223 , 129 , 99 , 61 , 124 , 34 , 192 , 158
Data 29 , 67 , 161 , 255 , 70 , 24 , 250 , 164 , 39 , 121
Data 155 , 197 , 132 , 218 , 56 , 102 , 229 , 187 , 89 , 7
Data 219 , 133 , 103 , 57 , 186 , 228 , 6 , 88 , 25 , 71
Data 165 , 251 , 120 , 38 , 196 , 154 , 101 , 59 , 217 , 135
Data 4 , 90 , 184 , 230 , 167 , 249 , 27 , 69 , 198 , 152
Data 122 , 36 , 248 , 166 , 68 , 26 , 153 , 199 , 37 , 123
Data 58 , 100 , 134 , 216 , 91 , 5 , 231 , 185 , 140 , 210
Data 48 , 110 , 237 , 179 , 81 , 15 , 78 , 16 , 242 , 172
Data 47 , 113 , 147 , 205 , 17 , 79 , 173 , 243 , 112 , 46
Data 204 , 146 , 211 , 141 , 111 , 49 , 178 , 236 , 14 , 80
Data 175 , 241 , 19 , 77 , 206 , 144 , 114 , 44 , 109 , 51
Data 209 , 143 , 12 , 82 , 176 , 238 , 50 , 108 , 142 , 208
Data 83 , 13 , 239 , 177 , 240 , 174 , 76 , 18 , 145 , 207
Data 45 , 115 , 202 , 148 , 118 , 40 , 171 , 245 , 23 , 73
Data 8 , 86 , 180 , 234 , 105 , 55 , 213 , 139 , 87 , 9
Data 235 , 181 , 54 , 104 , 138 , 212 , 149 , 203 , 41 , 119
Data 244 , 170 , 72 , 22 , 233 , 183 , 85 , 11 , 136 , 214
Data 52 , 106 , 43 , 117 , 151 , 201 , 74 , 20 , 246 , 168
Data 116 , 42 , 200 , 150 , 21 , 75 , 169 , 247 , 182 , 232
Data 10 , 84 , 215 , 137 , 107 , 53

Von diesen hast du jetzt 4 Stück im Flash liegen.
Also

Crc8_daten:
...
Crc8_daten1:
...
Crc8_daten2:
...
Crc8_daten3:
...

Dein Programm soll jetzt mal die eine mal die andere Tabelle für die Bearbeitung benutzt werden.
Die tabellen können natürlich auch in Include Files stehen. Im Programm sähe das dann so aus:

$include "Crc8_daten.inc"
$include "Crc8_daten1.inc"
$include "Crc8_daten2.inc"
$include "Crc8_daten3.inc"

In jedem File steht dann ein Label und ein Satz von 256 Daten.

Ist dies soweit korrekt?

Snaper
13.05.2010, 22:00
genau ich habe 4 Tabellen die per Include reingeschrieben werden.
Die Anzahl der Daten in der Tabelle sind aber variabel.

Nun müsste ich sowas wie

Mein Problem ist, dass ich ja im Lookup Aufruf keine Variable sondern direkt ein Label angeben muss.

Aber um die Frage ob deine bisherige Aufführung korrekt ist kurz zu beantworten: Ja bis auf die Tatsache, dass die Anzahl der Daten variieren kann.

for_ro
13.05.2010, 22:18
Wenn du die daten per Lookup holen willst, ist es sehr lästig, wenn du 4 verschiedene Label hast. Es hindert dich aber niemand, einfach alles über das erste Label zu machen. Dann sehe ich zwei Möglichkeiten, wie du an die nötigen Offsets kommst:
1. Du weißt, wieviele Werte bei jedem Label abgespeichert sind und kannst die Anzahl in einem Array abspeichern.

Anzahl(1) = 100
Anzahl(2) = 200
Anzahl(3) = 300
Anzahl(4) = 400

Dann würde ich mir noch die Start Offsets abspeichern, damit du zwischendrin nicht soviel rechnen musst:

Offset(1) = 0
Offset(2) = Anzahl(1)
Offset(3) = Offset(2) + Anzahl(2)
Offset(4) = Offset(3) = Anzahl(3)

Das 97. Element der tabelle 4 bekommst du dann mit:

Aktuelle_tabelle = 4 'wird irgendwo in deinem Programm gesetzt
Aktuelles_Element = 97 'wird in einer Schleife hochgezählt
Index = Offset(aktuelle_Tabelle) + aktuelles_element
Wert=Lookup(Index,Label1)

2. Wenn du die Anzahl der Elemente nicht kennst, kannst du sie zur Compilezeit berechnen lassen. Das geht über Loadlabel(Label).

Offset(1) = 0
Offset(2) = Loadlabel(label2) - loadlabel(label1)
Offset(3) = Loadlabel(label3) - loadlabel(label1)
Offset(4) = Loadlabel(label4) - loadlabel(label1)

Danach geht es genau so weiter wie oben.

Snaper
13.05.2010, 22:25
Du sagtest dass es über Lookup sehr lästig wäre. Das sagt mir, dass es 'ne andere Möglichkeit gibt welche vielleicht leichter ist. Welche wäre das denn?
Denn Lookup habe ich nur benutzt da ich keine gute/besser Alternative kannte bzw. kenne.

for_ro
13.05.2010, 22:39
Ich würde Lookup() nur benutzen, wenn ich wahlfrei auf die Daten zugreifen möchte. Also an beliebige Stellen, nicht die Daten einen nach dem anderen so wie sie gespeichert wurden.
Ich habe es mir zwar noch nicht anzeigen lassen, aber ich denke, dass ein Restore mit anschliessendem Read schneller sein sollte. Das geht aber nur sequentiell durch alle Daten.

Snaper
13.05.2010, 22:47
Es ist gewissermaßen sequentiell und zwar wie folgt:

Portd = Lookup(offset , Schema)
Offset = Offset + 1
Porta = Lookup(offset , Schema)

Dann kommt der nächste Datensatz. Tabelle sieht bspw. so aus:
Data &B00000100 , &B00000000
Data &B00001000 , &B00000000
Data &B00010000 , &B00010000

Data &B00000100 , &B00000000
Data &B00001000 , &B00010000
Data &B10010000 , &B11111111