Hi, ich arbeite an ein gerät das eine ROM Karte ausliest (512 kb). Das auslesen funktioniert anscheinend ohne probleme, nur das UART muckt rum ;) Ich benutze das usb dev board aus dem shop hier, d.h. mein AVR läuft auf 10 mhz und zur Übertragung benutze ich den USB<->rs232 konverter FT232BM. Also Übertragungsgeschwindigkeit habe ich 312500 baud gewählt (das ergibt sich aus der Mhz-taktung des AVRs) weil... 1 = 10000000 / (a*16) - 1 a = 312500 Baud Das übertragen funktioniert auch sehr flott, allerdings ist die Datei nicht 100%ig korrekt (zum größten teil sieht alles ok und richtig aus) und das geht beim Auslesen von Programmcode natürlich gar nicht das da fehler drin sind! Anstatt 512kb (524288 byte) zu lesen, werden 525899 byte gelesen (513kb)... noch schlimmer wird es wenn ich die Geschwindigkeit runter schraube, da kommen bei 15625 baud nur noch 277kb beim PC an :( Hier ist der source code meiner momentanen firmware mit reichlich kommentaren damit ihr wisst was ich da eigentlich machen will: #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> #include <stdint.h> //#define UART_BAUD_CALC(UART_BAUD_RATE) ((F_CPU)/((UART_BAUD_RATE)*16L)-1) #define N_PROG 0x80 #define HADR 0x20 #define LADR 0x10 #define OUTPUT_ENABLE 0x4 #define LED_GREEN (1<<2) #define LED_RED (1<<3) //#define BAUDRATE 9600 void uart_send(unsigned char c); int main(void) { //port A als eingang (active high) DDRA = 0x00; PORTA = 0x00; //port B und C sind ausgänge zur Speicherkarte //port D wird nur für status LEDs benutzt DDRB = 0xFF; DDRC = 0xFF; DDRD = 0xFF; //"power on" LED ein PORTD = (~LED_GREEN); //UART setup //Interrupt bei Daten-Empfang //Empfang (RX) und Senden (TX) aktivieren UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN); UCSRC = (1<<URSEL)|(3<<UCSZ0); //Asynchron 8N1 (8 bit, 1 stop bit) //UBRRH=(uint8_t)(UART_BAUD_CALC(BAUDRATE)>>8); //UBRRL=(uint8_t)UART_BAUD_CALC(BAUDRATE); UBRRH = 0; UBRRL = 1; //1 = 10000000 / (a*16) - 1 //a = 312500 Baud //Interrupts aktivieren sei(); //wie geht man in den sleep mode? while(1); } //ISR für USART receive SIGNAL(SIG_USART_RECV) { uint32_t addr; uint8_t addh; // Command-Byte überprüfen if(UDR == 0x10) { //voller ROM dump wurde angefordert //LEDs ein schalten PORTD = (~LED_GREEN) & (~LED_RED); //524288b / 1024 = 512kb auslesen for(addr=0;addr<524288;addr++) { //erster Teil der addresse (high part der Addresse) PORTB = (addr >> 10) & 0xFF; addh = (addr >> 18) & 0x3; PORTC = addh | N_PROG; PORTC = addh | N_PROG | HADR; PORTC = addh | N_PROG; //zweiter Teil der addresse (low part der Addresse) PORTB = addr & 0xFF; addh = (addr >> 8) & 0x3; PORTC = addh | N_PROG; PORTC = addh | N_PROG | LADR; PORTC = addh | N_PROG; //Ausgabe aktivieren PORTC = addh | N_PROG | OUTPUT_ENABLE; //Ergebnis von Port A per UART an PC senden uart_send(PINA); } //Grüne LED aus schalten PORTD = (~LED_GREEN); } } //Sendefunktion void uart_send(unsigned char c) { while (!(UCSRA & (1<<UDRE))); // warten bis Senden moeglich UDR = c; // sende Zeichen } Nur zur Info für alle die es vlt interessiert: Bei der Speicherkarte handelt es sich um ein Mask-ROM mit einen multiplexed address bus. Diese Karte stammt von einem elektronik spielzeug von Nintendo (Pokemon Mini heißt das ding und die Produktion ist mitlerweile eingestellt) - mehr infos gibt es auf unserer website http://pokeme.shizzle.it/ werbung mach ;D Vielen Dank für eure Hilfe! Mfg, Marius Als Dateianhang noch das Programm was ich auf der PC seite verwendet habe (VB 6.0), es kann gut sein das dort der Fehler liegt...
bevor mir einer sagt ich soll den internen oszilator aus schalten - ich habe folgende fuse bits gesetzt: - BOOTSZ1 - BOOTSZ0 - BODLEVEL - BODEN Weiß einer was die bedeuten? (ich weiß, rtfm...) Kann man den FT232BM eigentlich reseten, wenn das Programm welches als letztes zum FT232BM verbunden hat beim beenden die Verbindung zum chip nicht beendet hat? Jedes mal wenn ich vergesse die Verbindung zu beenden muss ich nämlich einmal kurz das USB kabel entfernen und neu einstöpseln. (meine eigentliche frage ist mir aber momentan wichtiger... :))
es handelt sich um einen ATmega16. jetzt sollte alles geklärt sein ;)
Hallo, hab mir dein programm nur kurz angesehen, aber warum kommentierst du die berechnung der Bautrate aus? Und wie kommst du auf so einen seltsame Baudrate? Es gibt meines wissesn nur gewisse Standartbaudraten, die bei verschiedenen Taktraten verscheiden hohe fehlerraten erzeugen. http://www.mikrocontroller.net/forum/read-4-186948.html#new versuchs mal mit 19200, das ergibt bei 10 Mhz 0,2% fehler. mfg Max
a=10000000 / (19200*16) - 1 a=31.55208333 wie soll ich denn diese zahl in das UBRR register schreiben? Ich habe meine Baud rate extra so ausgewählt das ich für UBRR ein ganz-zahliges Ergebnis habe damit die baud rate eindeutig definiert ist.
also, du gibst am anfang einfach #define XTAL 10000000UL #define USART_BAUD_RATE 9600 #define USART_BAUD_SELECT (XTAL/(USART_BAUD_RATE*16l)-1) ein, damit wird der richtige wert schon beim compilieren berechnet. und die werte werden dann mit UBRR0L = USART_BAUD_SELECT; UBRR0H = USART_BAUD_SELECT >> 8; in die register geschrieben. Wenn du einen anderen Quarz oder eine Andere Baudrate haben willst dann änderst du die Werte einfach bei den defines. lass einfach mal die 9600 eingestellt, damit hast du die geringste fehlerwerte. mfg Max
Jetzt ist alles ganz schlimm :( Jedes mal wenn ich meine Speicherkarte verbinde kommen nur noch wirre zeichen (ich habe nur noch ein Test Programm auf den AVR das einfach nur ein zeichen sendet), wenn ich die Karte wieder raus nehme und einen chip reset durchführe ist alles normal und mein test zeichen wird gesendet. Kann das mit dem Stromverbrauch zusammen hängen? Ich habe glaube ich nur 100mA zur Verfügung... aber dann ist das doch irgendwie komisch, das es gestern fast noch funktioniert hat :(
> PORTC = addh | N_PROG | OUTPUT_ENABLE; > uart_send(PINA); Wenn das ein Tiny oder Mega ist, dann hat der einen Synchronizer an den Inputs dran. Der bewirkt, dass hier der Zustand von PINA ungefähr vom gleichen Zeitpunkt gelesen wird, zu dem PORTC die letzte Änderung erfährt. Siehe Datasheet unter I/O-Ports. Also: Da muss mindestens 1 Befehl zwischen die entsprechenden OUT und IN Befehle.
ich glaube es liegt am interface zwischen AVR und FT232BM. Ich habe einfach mal ein zeichen * 512kb ausgegeben und man sieht daran deutlich das da was nicht stimmt, ab und zu kommen immer 4 bytes (immer 0x08 0x00 0x80 0x0F) und ich nehme mal an das da etwas mit dem timing nicht stimmt und dort die fehlerwahrscheinlichkeit einsetzt... das ist natürlich nur ein gedanke von mir :/ Am ende hat mein Programm dann anstatt 512kb zeichen ~1kb mehr gespeichert... es liegt definitiv am USART bzw USB. Ich melde mich nochmal wenn ich meinen quarz habe, falls das immer noch nichts bringt werde ich mal einen schaltplan machen, vielleicht stimmt da ja irgendwas nicht (was eigentlich nicht sein kann, da der speicher der Karte richtig gelesen wird - das was an kommt ist richtig, bis auf diese 4 bytes die immer wieder auf tauchen)
Neugierig: wenn du sowieso nur USB willst, warum dann erst noch einen FT232 und die ganze Ärgerei mit der Baudrate und nicht stattdessen gleich einen FT245?
Weil ich nicht weiß wie man den benutzt und ich habe auch nur noch einen port frei (...dabei hat der ATmega16 ja schon 32 IO pins) und außerdem war der FT232 bei dem dev board aus den Shop schon mit dabei Welche Vorteile hat der FT245 denn gegenüber den FT232 außer das man sich nicht mit Baudraten rum ärgern muss? Also wenn man an seinen AVR Komponenten anschließt die mit einen parallel bus angesteuert werden kann es schon eng werden denke ich.
Problem gelöst! Wer hätte das gedacht? Visual Basic war schuld! Ich habe das Programm in C++ neu geschrieben und es klappt auf anhieb! Tut mir leid eure Zeit verschwendet zu haben, das nächste mal bin ich schlauer. Und vielen dank für die guten Tipps :)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.