PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Asuro und eeprom



izaseba
11.11.2007, 11:48
Hallo,
Ich habe endlich meinen Asuro zum Leben erweckt und Ihm einen ISP Adapter spendiert (Bericht folgt heute noch).
Da ich mich zur Zeit mit der EEPROM Nutzung auf dem Asuro beschäftige,
würde mich interessieren, ob der Originale M8 den eeprom Inhalt nach erneutem Chip Erase behält oder nicht :-k
Da ich selber den Originalen M8 nicht mehr besitze, würde ich mich freuen, wenn einer von Euch mal mein(e) Programm(e) ausprobiert.
Programm 1:


#include<avr/io.h>
#include<avr/eeprom.h>
#include<avr/pgmspace.h>
#include<avr/interrupt.h>
#include<util/delay.h>
#include<string.h>
#include<stdlib.h>

#define BAUD 2400
#define BAUDSELECT (F_CPU/(BAUD*16L))-1

#define TRUE 1
#define FALSE 0

volatile uint8_t tastendruck = FALSE;
uint16_t tasten[6] EEMEM;


void init(void);
void push_flash(const char *);
void push_ram(char *);
static inline void push_char(char);

ISR (INT1_vect){
tastendruck = TRUE;
}

int main(void){
char stringpuffer[6];
uint16_t temp;
uint8_t tastennummer;

init();
PORTB |=(1<<PB0);
push_flash(PSTR("--= Asuro Tasten kalibrieren =--\r\n"));
for (tastennummer=1;tastennummer<7;tastennummer++) {
push_flash(PSTR("\r\nDruecke Taste "));
push_char((char)tastennummer+'0');
while(tastendruck == FALSE);
tastendruck = FALSE;
GICR = 0;
cli();
DDRD |=(1<<PD3);
PORTD |=(1<<PD3);
_delay_ms(10);
_delay_ms(10);
ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADSC)|(1<<ADIF);
while (!(ADCSRA & (1<<ADIF)));
temp = ADCW;
temp -= 5;//Testweise
PORTD &=~(1<<PD3);
DDRD &=~(1<<PD3);
_delay_ms(10);
GIFR = (1<<INTF1);
GICR = (1<<INT1);
sei();
itoa(temp,stringpuffer,10);
push_flash(PSTR("\r\nTastenwert "));
push_ram(stringpuffer);
eeprom_write_word(&tasten[tastennummer-1],temp);
}
push_flash(PSTR("\r\nTastenwerte wurden gespeichert\r\n"));
PORTB &=~(1<<PB0);
PORTD |=(1<<PD2);
while(1);
return 0;
}




void init(void) {
/*Statusled Init*/
DDRB |=(1<<PB0);
DDRD |=(1<<PD2);
/*Uart init*/
UBRRL = BAUDSELECT;
UCSRB = (1<<TXEN);
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
/*INT1 loest bei falling Edge aus*/
MCUCR = (1<<ISC11);
GICR = (1<<INT1);
/*ADC*/
ADCSRA=(1<<ADEN)|(1<<ADPS1)|(1<<ADPS2);
ADMUX = (1<<REFS0) | (1<<MUX2);
sei();
}

void push_flash(const char *string){
char zeichen;
while((zeichen = pgm_read_byte(string))) {
push_char(zeichen);
string++;
}
}
void push_ram(char *string){
char zeichen;
while ((zeichen=*string)){
push_char(zeichen);
string++;
}
}

static inline void push_char(char zeichen){
while(!(UCSRA&(1<<UDRE)));
UDR = zeichen;
}


Funktion:
Man wird aufgefordert alle Tasten nacheinander zu drücken, wichtig ist nur das man links anfängt, also Taste neben der IR-schnittstelle und sich dann nach rechts Richtung Schalter durchtastet.
Wenn das erledigt ist Flasht man Programm Nr. 2


#include<avr/io.h>
#include<avr/eeprom.h>
#include<avr/pgmspace.h>
#include<avr/interrupt.h>
#include<util/delay.h>
#include<string.h>
#include<stdlib.h>

#define BAUDSELECT (F_CPU/(BAUD*16L))-1

#define TRUE 1
#define FALSE 0

volatile uint8_t tastendruck = FALSE;
uint16_t tasten[6] EEMEM;


void init(void);
uint8_t taste_auswerten(uint16_t);
void push_flash(const char *);
void push_ram(char *);
static inline void push_char(char);

ISR (INT1_vect){
tastendruck = TRUE;
}

int main(void){
char stringpuffer[6];
uint16_t temp;
uint8_t a;

init();
push_flash(PSTR("--Asuro Tasten aus EEPROM auswerten--\r\n"));
while(1){
while(tastendruck == FALSE);
tastendruck = FALSE;
cli();
GICR = 0;
DDRD |=(1<<PD3);
PORTD |=(1<<PD3);
_delay_ms(10);
_delay_ms(10);
ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADSC)|(1<<ADIF);
while (!(ADCSRA & (1<<ADIF)));
temp = ADCW;
PORTD &=~(1<<PD3);
DDRD &=~(1<<PD3);
_delay_ms(10);
GIFR = (1<<INTF1);
GICR = (1<<INT1);
sei();
a=taste_auswerten(temp);
itoa(a,stringpuffer,10);
push_ram(stringpuffer);
push_flash(PSTR("\r\n"));
}

return 0;
}




void init(void) {
/*Uart init*/
UBRRL = BAUDSELECT;
UCSRB = (1<<TXEN);
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
/*INT1 loest bei falling Edge aus*/
MCUCR = (1<<ISC11);
GICR = (1<<INT1);
/*ADC*/
ADCSRA=(1<<ADEN)|(1<<ADPS1)|(1<<ADPS2);
ADMUX = (1<<REFS0) | (1<<MUX2);
sei();
}

uint8_t taste_auswerten(uint16_t adcwert){
uint8_t tastenwert = 1;
uint8_t a;
uint16_t eepromwert = eeprom_read_word(&tasten[0]);
if (adcwert < eepromwert)
return 0;
for (a=1;a<6;a++) {
eepromwert = eeprom_read_word(&tasten[a]);
if (adcwert < eepromwert)
return tastenwert;
else
tastenwert <<=1;
}
return tastenwert;
}


void push_flash(const char *string){
char zeichen;
while((zeichen = pgm_read_byte(string))) {
push_char(zeichen);
string++;
}
}
void push_ram(char *string){
char zeichen;
while ((zeichen=*string)){
push_char(zeichen);
string++;
}
}

static inline void push_char(char zeichen){
while(!(UCSRA&(1<<UDRE)));
UDR = zeichen;
}

Wenn man jetzt auf die Tasten drückt, und der Asuro sein eeprominhalt behält, sollte man je nach Taste Zweierpotenzen im Terminal angezeigt bekommen, also die gleiche Reihenfolge 1,2,4,8,16,32

Also, wer kann das bitte für mich testen ?

Danke Euch

Sebastian

damaltor
11.11.2007, 12:31
ich hab das vor einigen wochen bereits ausprobiert, und ich meine dass der eeprom-inhalt erhalten wurde... mein asuro ist gerade ne baustelle, kanns deshalb nicht testen.

so könnte man zB werte der myasuro.h hier reinspeichern...

izaseba
11.11.2007, 12:59
so könnte man zB werte der myasuro.h hier reinspeichern...

Ja genau, das ist auch mein Gedanke, deswegen auch diese Anfrage hier, ich weiß ja nicht, wie der M8 auf dem Asuro konfiguriert ist...
Standardmäßig ist ja EEPROM save Fuse nicht programmiert, womit der Inhalt nach jedem brennen flöten geht, und das wäre natürlich ein K.O. Kriterium für die Idee :-(

Gruß Sebastian

damaltor
11.11.2007, 13:30
das ist wahr. wie gesagt, wirste wohl noch bissl warten müssn.. ich häte ja meinen eeprom mal ausgelesen, aber da man per isp ja an den prozi gar nicht rankommt... :(

Sternthaler
11.11.2007, 13:32
Hallo izaseba,

ich bin dabei die beiden Programm zu übersetzten.
Scheinbar habe ich eine andere Version der Compiler usw.
Bis auf die Funktion _delay_ms bekomme ich ja nun ein Übersetzten hin, aber wo kommt die her? Bzw. was muss eingebunden werden?

Auch EEMEM wird angemeckert.

Gruß Sternthaler

izaseba
11.11.2007, 13:47
Scheinbar habe ich eine andere Version der Compiler usw.
Bis auf die Funktion _delay_ms bekomme ich ja nun ein Übersetzten hin, aber wo kommt die her? Bzw. was muss eingebunden werden?

Auch EEMEM wird angemeckert.

:-k Das ist nicht gut...
Ich habe hier die neueste libavr...
Hast Du Problemme mit ISR ?
_delay_ms liegt jetzt in util/delay.h früher war die ohne util mein ich..
EEMEM kommt von avr/eeprom.h , wo hat die früher gelegen :-k
Welche avr-gcc Version hast Du, ich könnte das eben schnell anpassen, damit man solche Probleme nicht mehr hat.

Gruß Sebastian

Edit:
Habe gerade in der Doku nachgesehen EEMEM sieht so aus:


#define EEMEM __attribute__((section(".eeprom")))

meckert der mit eeprom_write_word ?

m.a.r.v.i.n
11.11.2007, 13:58
Hallo izaseba,

ich habe es mal ausprobiert. Allerdings fehlt in deinem Programm noch die Initialisierung von Timer2. Damit läuft die Infrarot Schnittstelle nicht.

Nachdem ich das korrigiert hatte, funktionierte alles prima. Die Werte werden dauerhaft im EEPROM gespeichert, wenn ich das 2 .Testprogramm brenne, werden die korrekten Taster erkannt und ausgegeben :)


Hier noch meine Änderungen (für beide Testprogramme):


ISR (TIMER2_OVF_vect)
{
TCNT2 += 0x25;
}
...

void init(void) {
/* Timer2 Init */
TCCR2 = (1<<WGM20) | (1<<WGM21) | (1<<COM20) | (1<<COM21) | (1<<CS20);
OCR2 = 0x91; // duty cycle fuer 36kHz
TIMSK |= (1<<TOIE2); // 36kHz counter

/*Statusled, IRLED Init*/
DDRB =(1<<PB0) | (1<<PB3);
...


@sternthaler _delay_ms ist als Funktion eigentlich schon lange implementiert. In früheren AVR Versionen stand die Header Datei im avr Ordner. Probier mal:


#include<avr/delay.h>


F_CPU muß allerdings auch noch definiert sein, damit es funktioniert. Das habe ich im Makefile geändert:


CFLAGS = -g -O$(OPT) -DF_CPU=8000000UL -I../../lib/inc\
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \
-Wall -Wstrict-prototypes \
-Wa,-ahlms=$(<:.c=.lst)

izaseba
11.11.2007, 14:07
ich habe es mal ausprobiert. Allerdings fehlt in deinem Programm noch die Initialisierung von Timer2. Damit läuft die Infrarot Schnittstelle nicht.

#-o Stimmt, das habe ich völlig vergessen...
Kommt davon, daß ich Rx und Tx direkt per Kabel angeschlossen habe :-(


F_CPU muß allerdings auch noch definiert sein, damit es funktioniert.

Ja, das müsste man mit #ifndef abfangen, man sollte nicht davon ausgehen, dass es in Makefile angegeben ist :oops:


Die Werte werden dauerhaft im EEPROM gespeichert, wenn ich das 2 .Testprogramm brenne, werden die korrekten Taster erkannt und ausgegeben Smile

Das freut mich \:D/ jetzt muß man nur was brauchbares mit anfangen 8-[

Gruß Sebastian

Sternthaler
11.11.2007, 14:14
Na dann muss ich wohl doch mal einen Update ziehen.
Ich kann sowohl EEMEM als auch delay_ms in keiner Datei meiner Installion finden.
Sonst hatte ich ähnlich Anpassungen wie m.a.r.v.i.n gemacht.

Die Frage ist aber nun von m.a.r.v.i.n beantwortet.
Jetzt ist es noch für die Asuro-Lib interessant welcher Vorraussetzungen notwendig sind. Denn die Idee ist ja nun mal schon seit einiger Zeit da einiges im EEPROM abzulegen.

Gruß Sternthaler

[EDIT 14:40]
avr-gcc-Version ist 3.3.1
Ja, mit ISR gab es auch Probleme. Hatte ich gegen SIGNAL + alte Interruptschreibweise getauscht.

[EDIT 14:45]
Version WinAVR20070525 mal gerade von SourceForge geholt.

Sternthaler
11.11.2007, 15:30
So, nun bin ich auch wieder Up-To-Date.
Kombination aus Original und Änderungen von m.a.r.v.i.n. funktionieren auch bei mir perfekt.

Kleine Geschichte zur Installation und der Kombination mit dem AVR-Studio.
M1.R und ich hatten unter dem Lotto-Programm (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=326643#326643) schon Merkwürdigkeiten. Sie sieht die gcc-Lib's ohne explizite Pfad-Angabe, ich musste den Pfad eintragen.
Lösung zur Kombination avr-gcc und AVR-Studio.
Immer erst avr-gcc installieren, dann erst AVR-Studio
Eine Nachinstallation von avr-gcc nur in das gleiche Verzeichnis.

Beste, und sicherste, Kombination scheint ein deinstallieren von beiden Umgebungen zu sein. Neuinstallation vom AVR-Studio findet dann immer den korrekten Lib-Pfad.

Gruß Sternthaler

izaseba
11.11.2007, 17:56
Jetzt ist es noch für die Asuro-Lib interessant welcher Vorraussetzungen notwendig sind. Denn die Idee ist ja nun mal schon seit einiger Zeit da einiges im EEPROM abzulegen.

Ich werde mir als nächstes die neueste Asurolib installieren(gut daß Du irgendwo eine Beschreibung gepostet hast, ich habe nähmlich bis jetzt noch keine libs gebaut) und dieses Programm was die Werte für myasuro.h selbst ermitelt.
Dann versuche ich das ganze ein wenig umzuschreiben.
Das einzigste Problemchen ist ja, daß der Zugriff auf eeprom etwas langsammer ist, als Zugiff auf SRAM, ich meine aber das fällt nicht so ins Gewicht.
Anders ist es, wenn die Werte in myasuro.h liegen, da werden sie ja als Konstante behandelt und müssen nicht extra aus Sram oder Eeprom geladen werden.
Mal sehen, werde jetzt mal die lib installieren.

Gruß Sebastian

damaltor
11.11.2007, 18:33
kleiner tipp zum eeprom:

wenn man es einfach haben will, kann man die demo-funktionen aus dem datenblatt des mega8 direkt übernehmen, sie funktionieren ohne anpassung.

izaseba
11.11.2007, 18:40
Hallo Damaltor, leider kann ich Dir nicht folgen, wie meinst Du das mit 'ohne Anpassung'
in avr-gcc gibt es doch fertige Lösungen, die unter eeprom.h zu finden sind,
warum soll man nach dem Dattenblatt gehen, bei Assembler gib ich Dir recht, aber bei C ?

Gruß Sebastian

damaltor
11.11.2007, 19:26
hmm na wenn man den gcc nicht bemühen will ;) da sind zwei kurze funktionen drin, die man eins zu eins kopieren kann. die nehm ich meistens. aber interessant wäre mal eine interruptgesteuerte ansteuerung des eeproms..

mmh..

ich liebe interrupts... bei mir läuft i2c und uart auch schon mit einem ringpuffer mit je 32 bytes, die dann interruptgesteuert abgeschickt werden...

da müsste auch eeprom-mäßig was machbar sein. werd mich mal dransetzen, falls du sowas möchtest/brauchen kannst.

vorteil: während der eeprom geschrieben wird, kann der prozessor sinnvolleres tun als das ready-bit zu pollen. nachteil: 32bytes sram sind weg (oder jede andere menge die du möchtest...)

izaseba
11.11.2007, 20:02
hmmm,
ich habe mal im Assembleroutput gewühlt und die Implementierung von eeprom_read_word gefunden, hier der Auszug:


00000206 <__eeprom_read_word_1C1D1E>:
206: 04 d0 rcall .+8 ; 0x210 <__eeprom_read_byte_1C1D1E>
208: e0 2d mov r30, r0
20a: 02 d0 rcall .+4 ; 0x210 <__eeprom_read_byte_1C1D1E>
20c: f0 2d mov r31, r0
20e: 08 95 ret

00000210 <__eeprom_read_byte_1C1D1E>:
210: e1 99 sbic 0x1c, 1 ; 28
212: fe cf rjmp .-4 ; 0x210 <__eeprom_read_byte_1C1D1E>
214: bf bb out 0x1f, r27 ; 31
216: ae bb out 0x1e, r26 ; 30
218: e0 9a sbi 0x1c, 0 ; 28
21a: 11 96 adiw r26, 0x01 ; 1
21c: 0d b2 in r0, 0x1d ; 29
21e: 08 95 ret


Es wird, wer hätte das gedacht eeprom_read_byte verwendet und zwar


00000210 <__eeprom_read_byte_1C1D1E>:
210: e1 99 sbic 0x1c, 1 ; 28
212: fe cf rjmp .-4 ; 0x210
214: bf bb out 0x1f, r27 ; 31
216: ae bb out 0x1e, r26 ; 30
218: e0 9a sbi 0x1c, 0 ; 28
21a: 11 96 adiw r26, 0x01 ; 1
21c: 0d b2 in r0, 0x1d ; 29

Also ganz nach Dattenblatt, es wird am Anfang wohl eepromready gepollt,
da hast Du recht.
Ringpuffer und Interruptsteuerung ist natürlich was feines, kostet aber auch Zeit, vielleicht ist es sinnvoller die eepromdaten beim Programmstart in Ram zu laden, so viele sind es nicht...
Naja ich kämpfe im Moment noch mit der neuen lib
( :-$ Meine liebste Frau hat mir einen neuen Laptop geschenkt \:D/ da dachte ich mir Win Nixda(vista) eine Chance zu geben, deswegen ist es doppelt so schwer für mich, als Linux User)

Gruß Sebastian

damaltor
11.11.2007, 20:07
na dafür lohnt sich das nicht, aber allgemein fürs eeprom schreiben/lesen.

izaseba
11.11.2007, 21:07
Naja ich kämpfe im Moment noch mit der neuen lib
So ein Shit, man braucht nach wie vor die asuro.c(es lebe die Forumsuche ;-) ),
jetzt klappt es, die lib steht :-)
weiter geht es mit der myasuro.h ...

Gruß Sebastian