At90S2313 EEPROM auslesen mit Wartezeit

K

Kai Ebersbach

Guest
Hallo,

bei meinem ersten AVR-Projekt bin ich nun an einer Stelle zum Stehen
gekommen, wo ich nicht mehr weiter weiss und mal um Euren Rat fragen möchte.

Gebaut werden soll eine Motorsteuerung mit einem At90S2313. Zum
Programmieren nutze ich BASCOM AVR, geflasht wird mit WinAVR. Der Motor
ist über einen BUK 100 am PWM Ausgang PB3 angeschlossen. Timer1 ist so
konfiguriert:

Config Timer1 = Pwm , Pwm = 8 , Prescale = 1 , Compare A Pwm = Clear
Down , Compare B Pwm = Clear Down

Durch Verändern des Wertes von Compare1a wird die Motordrehzahl
gesteuert. Einfluss auf die Motordrehzahl haben 2 Tasten UP/DOWN,
ankommende Befehle des UART (RS-232) und 4bit Informationen, die auf
Int0 an den Eingängen PB0,PB1,PB2,PB4. Mit den Tasten wird der gesamte
mögliche Wertebereich für Compare1a (byte) durchschritten, bei den
übrigen Ereignissen wird Compare1a auf einen Wert zwischen 0-255 gesetzt
(Tabelle).

Es läuft soweit alles, die Ansteuerung über Tasten, UART und auch von
extern 4bit+strobe an Int0 klappen.

Als nächstes sollen Geschwindigkeits- und Zeitinformationen als Sequenz
im EEPROM abgelegt werden. Das Schreiben (Writeeeprom) und das Auslesen
(Readeeprom) der Daten funktioniert bereits.

Aber nun kommt das Problem:

Das Programm soll bis zum Auslesen des nächsten Befehls eine definiert
lange Pause machen, bis der nächste Wert geholt wird. Dabei darf aber
der sonstige Programmablauf nicht angehalten werden wie das bei einem
WaitMs der Fall ist. Als Geschwindigkeitsinformation dient das obere
nibble, als Zeitinformmation das untere nibble des im EEPROM
hinterlegten bytes.

Ich suche also eine Möglichkeit, im Hintergrund eine Zeit verstreichen
zu lassen (einstellbare Dauer). Ich habe dabei an den noch vorhandenen
timer0 gedacht... der sollte doch in der Lage sein, unabhängig von allen
anderen Ereignissen einen internen Interupt auszulösen wenn die
voreingestellte Zeit verstrichen ist und so das Übernehmen des nächsten
EEPROM Wertes einleiten können (Subroutine). Aber genau hier komme ich
nicht weiter... Wer hat eine Idee, wie ich das Auslesen des EEPROM in
den Hintergrund legen kann, ohne dass mit einem WaitMS das ganze
Programm angehalten wird?

Hier mein bisheriges Quellcodegewurstel zum Angucken:

http://www.kai-ebersbach.de/avr/12-2313.bas

Für Verbesserungsvorschläge am gesamten Code bin ich natürlich auch
jederzeit dankbar... wie gesagt, es ist mein erstes AVR Projekt und ich
stelle mich bestimmt noch ungeschickt dabei an...

Danke

Kai

--
Die angegebene Mailadresse ist replyfähig, sie verfällt
jedoch zum Ende eines jeden Quartals und wird durch eine
neue nach dem Muster usenetQQYYYY@kai-ebersbach.de ersetzt.
 
Autsch... ich stelle gerade mit Ercshrecken fest, dass wir ein neues
Quartal haben und die alte Mailadresse schon gelöscht ist...

Benutzbar ist nun usenet042003@kai-ebersbach.de

Ich bitte um Entschuldigung!

Kai

--
Die angegebene Mailadresse ist replyfähig, sie verfällt
jedoch zum Ende eines jeden Quartals und wird durch eine
neue nach dem Muster usenetQQYYYY@kai-ebersbach.de ersetzt.
 
Kai Ebersbach <usenet032003@kai-ebersbach.de> schrieb im Beitrag <bljki0$d0c18$1@ID-40159.news.uni-berlin.de>...
bei meinem ersten AVR-Projekt bin ich nun an einer Stelle zum Stehen
gekommen, wo ich nicht mehr weiter weiss und mal um Euren Rat fragen möchte.

Ich hab mir dein 'Quellcodegewurstel' nicht angesehen, aber allgemein:
Im Prinzip besteht jedes uC-Programm aus einer Endlosschleife,
wenn man ein mal durch ist, alles was anstand zu verarbeiten,
kommt die naechste Runde.
Jede Runde dauert entweder gleich lang (kann man z.B. erreichen
in dem NOP und NUllbefehle eingestreut werden bis exakt 1msec
pro Durchlauf entsteht),
oder man kann bei jedem Durchlauf auf einen freilaufenden
Hardwarezahler zugreifen und sich die tatsaechliche Zeit nennen
lassen,
oder (meistens) es kommt nicht so genau drauf an (ob nun ein
Umlauf 0.761 oder 2.133 msec dauert).
Wenn man etwas verzoegern will, braucht man nun nur Durchlaeufe
zu zaehlen (jetzt gab es ein Ereignis, setze Zaehler auf 5, bei
jedem Umaluf Zeahler um 1 verringern, wenn Zaehler 0 ist das
machen, was nach dem Ereignis getan werden sollte).
man kann sogar Schieberegisteraehnlich ganz komplexe Muster
verzoegern.

Loest euch von der Vorstellung, asynchrone Ereignisse ausloesen
uz wollen, es gibt nur eine CPU, und die macht eh alles nacheinander,
und sie muss es auch schaffen was zu tun ist, daher tut es die
simple Schleife meist sehr gut.
--
Manfred Winterhoff, reply-to invalid, use mawin at despammed.com
homepage: http://www.geocities.com/mwinterhoff/
de.sci.electronics FAQ: http://dse-faq.elektronik-kompendium.de/
Read 'Art of Electronics' Horowitz/Hill before you ask.
Lese 'Hohe Schule der Elektronik 1+2' bevor du fragst.
 
On Fri, 03 Oct 2003 12:56:02 +0200, Kai Ebersbach
<usenet032003@kai-ebersbach.de> wrote:

Hallo,

[...]

Hier mein bisheriges Quellcodegewurstel zum Angucken:

http://www.kai-ebersbach.de/avr/12-2313.bas

Für Verbesserungsvorschläge am gesamten Code bin ich natürlich auch
jederzeit dankbar... wie gesagt, es ist mein erstes AVR Projekt und ich
stelle mich bestimmt noch ungeschickt dabei an...

Allgemeinzu Deinem Programm:
Versuch Dich mal von dieser strukturierten Programmierung, wie man das
früher mal gemacht hat, zu lösen und zu einer eventorientierten
Programmierung zuzuwenden. Solche Sachen wie das auslesen der
UART-Daten gehören direkt in die IRQ-Routine der UART, sonst kann es
bei Deinen Waits auch sporadisch mal passieren, das Deine Daten in der
UART überschrieben werden. Kann ja auch mal eine Störung in die UART
kommen und dann ist das Byte weg.

Unter eventorientierten Programmierung verstehe ich, dass man wie bei
einem Betriebssystem kleine Treiber schreibt (UART, Taster, Timer),
die die Hardware managen. In der Regel sind das IRQ-Routinen, aber
auch Routinen zur Initialisierung und zum Setzen und Abfragen von
Werten. Dabei sollte man sich auch gleich angewöhnen, jeden Treiber in
eine eigene Datei zu packen. Ideal ist es, wenn man aus dem
Haptprogramm auf die Hardware nur noch mit "SetValue()" und
"GetValue()" zugreift. Ereignisse, die sofort bearbeitet werden
müssen, macht die IRQ-Routine selbst, die welche mehr Zeit
haben/brauchen (z.B. Taste X wurde gedrückt) trägt jeder Treiber in
eine Liste ein (kann man auch noch priorisieren), die dann von
Hauptprogramm abgearbeitet wird.

Abläufe welche erst mal in jedes Modul schauen, ob irgendwas zu tun
ist, fressen nur sinnlos Zeit. (insbesondere wenn die Programme größer
werden).

-----------------------------------------------------------------

Zu Deinem Timer Problem:
Versuch mal das zu implementieren, dann kannst Du die Funktionen

void setTimer(unsigned int duration, char type);
void killTimers(char type);

verwenden. In diesem Beispiel wird (wenn die Timer-ISR alle 1ms kommt)
wenn setTimer( 100, TIMER_LS_OBEN) aufgerufen wird. die Funktion
processLSoben() nach 100ms gestartet (on_timer wird einfach nur
erweitert). In diesem Beispiel können max. 15 Timer gleichzeitig aktiv
sein (TIMER_BUFFER_SIZE evtl. erweitern).

-----------------------------------------------------------------------------------------------------------

#define TIMER_EMPTY 0
#define TIMER_DELAY 1
#define TIMER_1 2
#define TIMER_2 3
#define TIMER_LS_UNTEN 4
#define TIMER_LS_OBEN 5
#define TIMER_TLE6220 6
#define TIMER_KEY 7
#define TIMER_DISPLAY 8
#define TIMER_TAS_LICHT 10
#define TIMER_LICHT 11
#define TIMER_RECEIVE 12
#define TIMER_SEND 13
#define TIMER_RECEIVE_EXIT 14
#define TIMER_RECEIVE_DELAY 15

#define TIMER_BUFFER_SIZE 15
#define TIMER_IRQ_PRIORITY 1


#pragma INTERRUPT ta0int /* Declares interrupt handler ta0 */


void initTimer( void);
void delay_ms( unsigned int delay);
void on_timer(char type);
void setTimer(unsigned int duration, char type);
void process_timers( void);
void killTimer(char type);

struct TIMER
{
char timer_id;
unsigned int end_time;
};

static struct TIMER timer_queue[TIMER_BUFFER_SIZE] = {0};
unsigned int global_ms_timer;
unsigned char ucDelayTimerOn;



/****************************
* Start of code *
****************************/

void initTimer( void)
{
ta0ic = 0; // disable timer irq
ta0mr = 0x40; // set Timer Mode
ta0ud = 0; // set count down
ta0 = 0x800; // set 1mS
ta0s = 1; //get ready
ta0ic = TIMER_IRQ_PRIORITY;
}

void delay_ms( unsigned int delay)
{

ucDelayTimerOn = 1;
setTimer( delay, TIMER_DELAY);
while( ucDelayTimerOn);
}



void on_timer(char type)
{
switch (type)
{
case TIMER_DELAY: ucDelayTimerOn = 0;
break;
case TIMER_LS_UNTEN: processLSunten();
break;
case TIMER_LS_OBEN: processLSoben();
break;
case TIMER_TLE6220: processTLE6220();
break;
case TIMER_KEY: processKey();
break;
case TIMER_TAS_LICHT: processTasterLicht();
break;
case TIMER_LICHT: processLicht();
break;
case TIMER_DISPLAY: processDisplay();
break;
case TIMER_SEND: processSend();
break;
case TIMER_RECEIVE_EXIT: processReceive( type);
break;
case TIMER_RECEIVE_DELAY: receiveOn();
break;

}
}


void far ta0int(void)
{

global_ms_timer++;
process_timers();


}

void setTimer(unsigned int duration, char type)
{
char i;

ta0ic = 0x00;
// Disable timers

for (i = 0; i < TIMER_BUFFER_SIZE; i++)
{
if (timer_queue.timer_id == TIMER_EMPTY)
// Suche nach freien Timern
{
timer_queue.timer_id = type;
timer_queue.end_time = duration +
global_ms_timer;
ta0ic = TIMER_IRQ_PRIORITY;
// Re-enable timers
return;
}
}

ta0ic = TIMER_IRQ_PRIORITY;
// Re-enable timers

}

void process_timers( void)
{
char i;


for (i=0;i<TIMER_BUFFER_SIZE;i++)
{
if ((timer_queue.end_time == global_ms_timer) &&
(timer_queue.timer_id != TIMER_EMPTY))
{
on_timer(timer_queue.timer_id);
timer_queue.timer_id = TIMER_EMPTY;
timer_queue.end_time = TIMER_EMPTY;
}
}
}

void killTimer(char type)
{
char i;

ta0ic = 0x00; // Disable timers..

for (i = 0; i < TIMER_BUFFER_SIZE; i++)
{// loop through and check for timers of this type, then kill
them...
if (timer_queue.timer_id == type)
{// kill timers...
timer_queue.timer_id = TIMER_EMPTY;
timer_queue.end_time = TIMER_EMPTY;
ta0ic = TIMER_IRQ_PRIORITY; // Re-enable
timers..
return;
}
}


ta0ic = TIMER_IRQ_PRIORITY; // Re-enable timers..

}

---------------------------------------------------------------------------------------------------------------------------------


Tschö
Dirk
 
Hallo MaWin,

MaWin schrieb:

Im Prinzip besteht jedes uC-Programm aus einer Endlosschleife,
wenn man ein mal durch ist, alles was anstand zu verarbeiten,
kommt die naechste Runde.
OK, das finde ich einen guten Ansatz...

Jede Runde dauert entweder gleich lang (kann man z.B. erreichen
in dem NOP und NUllbefehle eingestreut werden bis exakt 1msec
pro Durchlauf entsteht),
oder man kann bei jedem Durchlauf auf einen freilaufenden
Hardwarezahler zugreifen und sich die tatsaechliche Zeit nennen
lassen,
oder (meistens) es kommt nicht so genau drauf an (ob nun ein
Umlauf 0.761 oder 2.133 msec dauert).
Darauf kommt es in meinem Anwendungsfall wirklich nicht an, stimmt.

Wenn man etwas verzoegern will, braucht man nun nur Durchlaeufe
zu zaehlen (jetzt gab es ein Ereignis, setze Zaehler auf 5, bei
jedem Umaluf Zeahler um 1 verringern, wenn Zaehler 0 ist das
machen, was nach dem Ereignis getan werden sollte).
Das werde ich mal ausprobieren.

Loest euch von der Vorstellung, asynchrone Ereignisse ausloesen
uz wollen, es gibt nur eine CPU, und die macht eh alles nacheinander,
und sie muss es auch schaffen was zu tun ist, daher tut es die
simple Schleife meist sehr gut.
Gute Idee, ich werde mal versuchen, das so einzubauen.

Vielen Dank und schönen Feiertag!

Kai

--
*** homepage: http://www.erosoft.de ***
Die angegebene Mailadresse ist replyfähig, sie verfällt
jedoch zum Ende eines jeden Quartals und wird durch eine
neue nach dem Muster usenetQQYYYY@kai-ebersbach.de ersetzt.
 
Hallo Dirk,

Dirk Ruth schrieb:

Allgemeinzu Deinem Programm:
Versuch Dich mal von dieser strukturierten Programmierung, wie man das
früher mal gemacht hat, zu lösen und zu einer eventorientierten
Programmierung zuzuwenden.
Leichter gesagt, als getan ;-) Ich bin ja schon froh, dass der Atmel
erst mal das tut, was ich möchte... wenn auch noch nicht alle Wünsche
implementiert sind...

Solche Sachen wie das auslesen der
UART-Daten gehören direkt in die IRQ-Routine der UART, sonst kann es
bei Deinen Waits auch sporadisch mal passieren, das Deine Daten in der
UART überschrieben werden. Kann ja auch mal eine Störung in die UART
kommen und dann ist das Byte weg.
Hmmm... wird denn der Wert nicht bis zur nächsten Abfrage im
entsprechenden Register gehalten? Wie das bei Störungen aussieht kann
ich natürlich nicht beurteilen...

Abläufe welche erst mal in jedes Modul schauen, ob irgendwas zu tun
ist, fressen nur sinnlos Zeit. (insbesondere wenn die Programme größer
werden).
OK, das sehe ich ein... ich muss es jetzt "nur noch" verstehen und
umsetzen können...

[Quellcode (war es C?) gelöscht]

Uih... schwere Kost ;-) Das muss ich erst noch 20-30 mal lesen und
begreifen, was Du damit gemeint hast...

Vielen Dank für Deine Anregungen und einen schönen Feiertag!

Kai

--
*** homepage: http://www.erosoft.de ***
Die angegebene Mailadresse ist replyfähig, sie verfällt
jedoch zum Ende eines jeden Quartals und wird durch eine
neue nach dem Muster usenetQQYYYY@kai-ebersbach.de ersetzt.
 
On Fri, 03 Oct 2003 15:20:59 +0200, Kai Ebersbach
<usenet042003@kai-ebersbach.de> wrote:

Hallo Dirk,

Dirk Ruth schrieb:

Allgemeinzu Deinem Programm:
Versuch Dich mal von dieser strukturierten Programmierung, wie man das
früher mal gemacht hat, zu lösen und zu einer eventorientierten
Programmierung zuzuwenden.

Leichter gesagt, als getan ;-) Ich bin ja schon froh, dass der Atmel
erst mal das tut, was ich möchte... wenn auch noch nicht alle Wünsche
implementiert sind...

Wird schon noch.

Solche Sachen wie das auslesen der
UART-Daten gehören direkt in die IRQ-Routine der UART, sonst kann es
bei Deinen Waits auch sporadisch mal passieren, das Deine Daten in der
UART überschrieben werden. Kann ja auch mal eine Störung in die UART
kommen und dann ist das Byte weg.

Hmmm... wird denn der Wert nicht bis zur nächsten Abfrage im
entsprechenden Register gehalten? Wie das bei Störungen aussieht kann
ich natürlich nicht beurteilen...

Schon richtig. Aber wenn ein neuer Wert kommt (worst case: Störung)
oder Du Dich bei Deinen Wartezeiten vertan hast, dann ist es weg.

Abläufe welche erst mal in jedes Modul schauen, ob irgendwas zu tun
ist, fressen nur sinnlos Zeit. (insbesondere wenn die Programme größer
werden).

OK, das sehe ich ein... ich muss es jetzt "nur noch" verstehen und
umsetzen können...
Viele Designs arbeiten auch mit Batterieversorgung, dann frist das
polling auch nur sinnlos Strom.

[Quellcode (war es C?) gelöscht]
Es war C.
Uih... schwere Kost ;-) Das muss ich erst noch 20-30 mal lesen und
begreifen, was Du damit gemeint hast...

Was ich da gepostet hatte war ein Entwurfsmuster (Pattern) für eine
Timerroutine (hier für einen M16C). Du must lediglich die
Timer-Initialisierung anpassen, dann läuft die auf jedem
Microcontroller. Brauchst also nicht mehr jedesmal von vorn anfangen
und die Fehler da zu suchen.

Kann man natürlich noch erweitern, dass auch Callback-Funktionen
möglich sind, aber das gibt's in Basic ohnehin nicht.

Tschö
Dirk
 
Kai Ebersbach wrote:

Hallo,

snip

nicht weiter... Wer hat eine Idee, wie ich das Auslesen des EEPROM in
den Hintergrund legen kann, ohne dass mit einem WaitMS das ganze
Programm angehalten wird?
In meinem Projekt habe ich all diese Geschichten mit einem Timer gelöst, der
immer mitläuft und jede ms ausgelöst wird. Wann immer das Hauptprogramm
eine Aktion ausführen will, macht sie das nicht selbst, sondern setzt ein
Flag (z.B. updateLCD). Wenn der Timer überläuft, wird der Flagwert
dekriminiert (falls > 0). Ist er null, wird die entsprechende Routine
aufgerufen und führt die Aktion aus. Wenn man keine Boolean-Variablen
verwendet (gibt's beim AVR sowieso nicht), kann man auch festlegen, daß
eine Aktion z.B. nur alle 10ms ausgeführt wird (Flag auf 10 setzen, 9 Timer
verstreichen ohne Aktion, bei der 10. wird ausgeführt). Außerdem läßt sich
die Aktion damit auch mehrfach ausführen (Aktionsroutine setzt selbst das
Flag wieder auf 10). Zur Initialisierung muß dann nur einmalig das Flag
gesetzt werden. Außerdem kann das Hauptprogramm ein Update "außer der
Reihe" anordnen, indem das Flag auf 1 gesezt wird (Update beim nächsten
Timer, unabhängig vom aktuellen Zählerstand).

Zusätzlich kann man natürlich noch Queues einbauen (jede Aktion führt genau
einen Queue-Befehl aus). Etwas haushalten sollte man nur mit den Zähl- bzw.
Flagvariablen (ich muß CF lesen, brauche also von den 1024 Bytes allein 512
für den Sektorbuffer, variable Strings etc. brauchen auch ganz schön);
schließlich müssen das globale Variablen sein und belegen dauerhaft
Speicher. Also char verwenden (evtl. unsigned, mehr als 256 Timer-Ticks
wird man nicht brauchen - sonst paßt man die Timerfrequenz entsprechend
an).

Wenn Du magst, kann ich Dir auch gerne meinen Quellcode schicken (AVR-GCC,
ist auch nur rudimentär kommentiert, form follows function ;o)) --> PM

Sebastian
 
Hallo Sebastian,

Sebastian Voitzsch schrieb:

In meinem Projekt habe ich all diese Geschichten mit einem Timer gelöst, der
immer mitläuft und jede ms ausgelöst wird. Wann immer das Hauptprogramm
eine Aktion ausführen will, macht sie das nicht selbst, sondern setzt ein
Flag (z.B. updateLCD). Wenn der Timer überläuft, wird der Flagwert
dekriminiert (falls > 0). Ist er null, wird die entsprechende Routine
aufgerufen und führt die Aktion aus.
So in der Form hatte ich es auch mal überlegt... das Ganze wurde dann
allerdings so aufwendig, dass Bascom AVR in der Demo Version streikte,
weil da nur 1024 byte Code zulässig sind...

Ich habe nun erst einmal MaWins Vorschlag verfolgt und es funktioniert
momentan so wie es soll. Da das ganze Projekt allerdings noch nicht
endgültig ausgetüftelt ist, kann und wird sich sicher noch einiges
ändern und ich versuche dabei auch gern andere Ansätze, man wird ja
nicht dümmer dadurch ;-)

Nun muss ich mir erst mal BASCOM AVR in der Vollversion kaufen, damit
ich auch die 2048 byte voll nutzen kann ;-) Kennt da jemand noch eine
Bezugsquelle ausser den auf der MSCELEC-Homepage genannten Distributoren?

Wenn Du magst, kann ich Dir auch gerne meinen Quellcode schicken (AVR-GCC,
ist auch nur rudimentär kommentiert, form follows function ;o)) --> PM
Ich würde mich sehr darüber freuen, die Adresse
usenet042003nospam@kai-ebersbach.de ist gültig. Ich habe allerdings wie
wohl fast jeder Usenetteilnehmer mit einer Masse von Swens zu kämpfen,
die das Mailen nicht gerade schöner macht :-(, daher der Wechsel (hoffe
Swen verschont die Mailadresse weil "spam" drin vorkommt). Die alte
Adresse ist aber auch noch eine Weile gültig.

Viele Grüsse

Kai

--
Die angegebene Mailadresse ist replyfähig, sie verfällt
jedoch zum Ende eines jeden Quartals und wird durch eine
neue nach dem Muster usenetQQYYYYnospam@kai-ebersbach.de ersetzt.
 
Hallo Dirk,

Dirk Ruth schrieb:

Wird schon noch.
Ja, mühseelig ernährt sich das Eichhörnchen ;-)
Momentan bin ich am 1024 byte Limit der Demo-Version von BASCOM AVR
angekommen...

Hmmm... wird denn der Wert nicht bis zur nächsten Abfrage im
entsprechenden Register gehalten? Wie das bei Störungen aussieht kann
ich natürlich nicht beurteilen...

Schon richtig. Aber wenn ein neuer Wert kommt (worst case: Störung)
oder Du Dich bei Deinen Wartezeiten vertan hast, dann ist es weg.
Bei einigen kritschen Anwendungen sicherlich ein wichtiger Aspekt...
wenn bei meinem Projekt ein Zeichen verloren geht, muss es eben noch mal
gesendet werden... Ich behalte Deine Anregung aber im Hinterkopf.

Viele Designs arbeiten auch mit Batterieversorgung, dann frist das
polling auch nur sinnlos Strom.
So weit habe ich noch gar nicht gedacht... aber Du hast völlig recht,
für eine Optimierung ein wichtiger Punkt.

Was ich da gepostet hatte war ein Entwurfsmuster (Pattern) für eine
Timerroutine (hier für einen M16C). Du must lediglich die
Timer-Initialisierung anpassen, dann läuft die auf jedem
Microcontroller. Brauchst also nicht mehr jedesmal von vorn anfangen
und die Fehler da zu suchen.
Ich habe es mir in meinen Sammelordner abgelegt, aus dem ich mir immer
mal häppchenweise etwas zum Verarbeiten raushole... Manchmal qualmt mir
allerdings als Hobbyist der Kopf, dann lege ich das alles erst mal zur
Seite ;-).

Viele Grüsse

Kai

--
Die angegebene Mailadresse ist replyfähig, sie verfällt
jedoch zum Ende eines jeden Quartals und wird durch eine
neue nach dem Muster usenetQQYYYYnospam@kai-ebersbach.de ersetzt.
 
Kai Ebersbach wrote:

Hallo Sebastian,
snip

Nun muss ich mir erst mal BASCOM AVR in der Vollversion kaufen, damit
ich auch die 2048 byte voll nutzen kann ;-) Kennt da jemand noch eine
Bezugsquelle ausser den auf der MSCELEC-Homepage genannten Distributoren?
Nimm halt AVR-GCC und Du bist die Lizenzquerelen los. Mich würde es auch
nicht wundern, wenn C zu kleinerem Code führt.

Wenn Du magst, kann ich Dir auch gerne meinen Quellcode schicken
(AVR-GCC, ist auch nur rudimentär kommentiert, form follows function ;o))
--> PM

Ich würde mich sehr darüber freuen, die Adresse
usenet042003nospam@kai-ebersbach.de ist gültig. Ich habe allerdings wie
wohl fast jeder Usenetteilnehmer mit einer Masse von Swens zu kämpfen,
die das Mailen nicht gerade schöner macht :-(, daher der Wechsel (hoffe
Swen verschont die Mailadresse weil "spam" drin vorkommt). Die alte
Adresse ist aber auch noch eine Weile gültig.
SWEN dürfte eher interessieren, ob er die Adresse in irgendwelchen
Adreßbüchern oder im Web findet, nicht, ob SPAM drin vorkommt. Von mir
jedenfalls gibt's keinen SWEN, IMHO ist KMail dafür nicht anfällig ;o)

Sebastian
 
On Sat, 04 Oct 2003 18:19:14 +0200, Kai Ebersbach
<usenet042003nospam@kai-ebersbach.de> wrote:

Hallo Dirk,

Dirk Ruth schrieb:

Wird schon noch.

Ja, mühseelig ernährt sich das Eichhörnchen ;-)
Momentan bin ich am 1024 byte Limit der Demo-Version von BASCOM AVR
angekommen...
Vergiss das mit dem Basic. Bei Microcontroller wird es hin und wieder
notwendig sein "Low Level" zu programmieren, also auf Adressen
zuzugreifen, zu verschieben und überhaupt mit Zeigern zu arbeiten. Mit
Basic wirst Du da auf die Dauer nicht glücklich. Und wenn Du die
Grundlagen erstmal kapiert hast, dann willst Du auch schnell mehr
versuchen.

Besorg Dir einen richtigen Compiler zum programmieren. Der GCC ist
dafür nicht schlecht, oder wenn Du Geld ausgeben möchtest, dann kann
ich Dir auch den ICC-AVR empfehlen. Da gibt's dann auch die richtigen
Librarys im Quellcode dazu.

Basic ist, wie der Name schon sagt, wirlich nur Basic.

Tschö
Dirk
 
Dirk Ruth wrote:

On Sat, 04 Oct 2003 18:19:14 +0200, Kai Ebersbach
usenet042003nospam@kai-ebersbach.de> wrote:

Hallo Dirk,

Besorg Dir einen richtigen Compiler zum programmieren. Der GCC ist
dafür nicht schlecht, oder wenn Du Geld ausgeben möchtest, dann kann
ich Dir auch den ICC-AVR empfehlen. Da gibt's dann auch die richtigen
Librarys im Quellcode dazu.
Wobei auch für den GCC dank der weiten Verbreitung einiges zu haben ist. Und
die meisten Leute, die Libs dafür machen, geben die auch unter der GPL
weiter. Ich habe immer den Eindruck, daß es nichts gibt, was nicht auch für
den GCC zu haben ist - ist allerdings nur meine Hobby-Erfahrung.
Industriell mag das anders aussehen (v.a. Support etc.).

Basic ist, wie der Name schon sagt, wirlich nur Basic.
Jepp...

Sebastian
 
Hallo Dirk,

Dirk Ruth schrieb:

Vergiss das mit dem Basic. Bei Microcontroller wird es hin und wieder
notwendig sein "Low Level" zu programmieren, also auf Adressen
zuzugreifen, zu verschieben und überhaupt mit Zeigern zu arbeiten.
Ich habe mich nun entschlossen, dasselbe Programm noch einmal zu
schreiben und zwar gleich in Assembler. Dazu kann ich auch die
kostenlosen Werkzeuge, die Atmel verfügbar macht, benutzen.

Basic ist, wie der Name schon sagt, wirlich nur Basic.
Bevor ich mich in eine weitere Hochsprache einarbeite, nehm ich gleich
den harten Weg ;-) Da ich ja Zeit habe, kann ich mich da langsam Schritt
für Schritt durchwühlen und lerne dabei sicher gleich mehr über den
inneren Aufbau der Mikrocontroller.

Herzlichen Dank für alle Anregungen und viele Grüsse

Kai

--
Die angegebene Mailadresse ist replyfähig, sie verfällt
jedoch zum Ende eines jeden Quartals und wird durch eine
neue nach dem Muster usenetQQYYYYnospam@kai-ebersbach.de ersetzt.
 
Hallo Sebastian,

Sebastian Voitzsch schrieb:

Nimm halt AVR-GCC und Du bist die Lizenzquerelen los. Mich würde es auch
nicht wundern, wenn C zu kleinerem Code führt.
Wie ich schon zu Dirks Posting schrieb, wähle ich nun den harten Weg und
schreibe das Programm Schritt für Schritt in Assembler neu.

SWEN dürfte eher interessieren, ob er die Adresse in irgendwelchen
Adreßbüchern oder im Web findet, nicht, ob SPAM drin vorkommt.
In d.a.n.a.m wird z.Zt. diskutiert und ausprobiert, ob Mailadressen die
"spam" enthalten verschont werden... daher der Versuch.

Von mir jedenfalls gibt's keinen SWEN, IMHO ist KMail dafür nicht anfällig ;o)
Von mir gibts auch keinen, selbst Mozilla führt <iframe> Tags nihct
einfach aus ;-). Gemeint war aber, dass Swen neben lokalen Adressbüchern
und HTML-Files auch Newsgroups auf Mailadressen durchforstet und sich
dann innerhalb kürzester Zeit mehrfach an die gefundenen Adressen
verschickt. Es hat gerade mal eine Stunde gedauert nachdem ich mit der
frischen Adresse usenet042003@kai-ebersbach.de gepostet hatte und die
ersten Swens kamen herein :-(. Egal... das ist hier eh OT.

Vielen Dank für Deine Anregungen und viele Grüsse

Kai

--
Die angegebene Mailadresse ist replyfähig, sie verfällt
jedoch zum Ende eines jeden Quartals und wird durch eine
neue nach dem Muster usenetQQYYYYnospam@kai-ebersbach.de ersetzt.
 

Welcome to EDABoard.com

Sponsor

Back
Top