Hi
Ich sehe kein print_mem.
Vielleicht mal ein "volatile unsigned char mem_main[256];"
Vielleicht solltest du die Variable nicht nur deklarieren sondern auch initialisieren.
"for (;; _delay_ms(1000))" das meinst du nicht ernst oder?
Moin,
bei meinem Versuch, einen Kartenleser für einfache Speicherkarten zu entwerfen, bin ich über ein Softwareproblem gestolpert. Es scheint, als würde mein Array mem_main sich ständig verändern.
Hier der Code (relevanter Ausschnitt):
Seltsamerweise ändern sich vereinzelte Bytes in mem_main[...] anscheinend bei jeder Ausführung von print_mem(), obwohl keine schreibenden Zugriffe mehr stattfinden. Was könnte ich übersehen haben?Code:#include <avr/io.h> #include <util/delay.h> #include "uart.h" #define SM_RST PC0 #define SM_CLK PC1 #define SM_IO PC2 #define SM_PORT PORTC #define SM_PIN PINC #define SM_DDR DDRC unsigned char mem_main[256]; int main() { uart_init(); sm_init(); sm_read(); for (;; _delay_ms(1000)) { for (unsigned int i = 0; i < 256; i++) { uart_putc(mem_main[i]); } } return 0; } void sm_init() { SM_DDR = (1 << SM_RST) | (1 << SM_CLK); SM_DDR &= ~(1 << SM_IO); SM_PORT = (1 << SM_IO); } void sm_read() { sm_command(0x30, 0x00, 0x00); // Kommando zum Lesen senden SM_PORT &= ~(1 << SM_CLK); SM_DDR &= ~(1 << SM_IO); SM_PORT |= (1 << SM_IO); _delay_us(100); for (unsigned int i = 0; i < 256; i++) { // Byte-Schleife unsigned char temp_byte; // Temporäres Byte for (unsigned char k = 0; k < 8; k++) { // Bit-Schleife SM_PORT |= (1 << SM_CLK); // Taktleitung auf H setzen if (SM_PIN & (1 << SM_IO)) // I/O-Pin abfragen temp_byte |= (1 << k); _delay_us(100); SM_PORT &= ~(1 << SM_CLK); // Taktleitung auf L setzen _delay_us(100); } mem_main[i] = temp_byte; // Temporäres Byte in Hauptspeicher schreiben } } void uart_init() { UBRR0H = (unsigned char) (UBRR_VAL >> 8); UBRR0L = (unsigned char) (UBRR_VAL); UCSR0B = (1 << TXEN0); UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); // Asynchron 8N1 } void uart_putc(unsigned char c) { while (!(UCSR0A & (1 << UDRE0))) { } UDR0 = c; }
Hi
Ich sehe kein print_mem.
Vielleicht mal ein "volatile unsigned char mem_main[256];"
Vielleicht solltest du die Variable nicht nur deklarieren sondern auch initialisieren.
"for (;; _delay_ms(1000))" das meinst du nicht ernst oder?
Erstmal vielen Dank für die Antwort.
Stimmt, ist beim Zusammenkopieren für das Minimalbeispiel abhanden gekommen, sorry...Ich sehe kein print_mem.![]()
Also der bisherige Code sieht so aus:
Ich habe deine Vorschläge umgesetzt, leider ohne Ergebnis. Die Hex Dumps sehen z.B. so aus:Code:#include <avr/io.h> #include <util/delay.h> #include "reader.h" #include "uart.h" #include "smartcard.h" volatile unsigned char mem_main[256] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; int main() { uart_init(); sm_init(); _delay_us(100); sm_read(); // Dummy readout _delay_us(500); sm_read(); for (;; _delay_ms(1000)) { print_mem(); } return 0; } void sm_init() { SM_DDR = (1 << SM_RST) | (1 << SM_CLK); SM_PORT = (1 << SM_IO); } void sm_command(unsigned char b, unsigned char a, unsigned char d) { // gekürzt } void sm_read() { sm_command(0x30, 0x00, 0x00); SM_PORT &= ~(1 << SM_CLK); SM_DDR &= ~(1 << SM_IO); SM_PORT |= (1 << SM_IO); _delay_us(100); for (unsigned int byte = 0; byte < 256; byte++) { // Byte-Schleife unsigned char temp_byte = 0x00; // Temporäres Byte for (unsigned char bit = 0; bit < 8; bit++) { // Bit-Schleife SM_PORT |= (1 << SM_CLK); // Taktleitung auf H setzen if (SM_PIN & (1 << SM_IO)) // I/O-Pin abfragen temp_byte |= (1 << bit); _delay_us(100); SM_PORT &= ~(1 << SM_CLK); // Taktleitung auf L setzen _delay_us(100); } mem_main[byte] = temp_byte; // Temporäres Byte in Hauptspeicher schreiben } } void uart_init() { // gekürzt } void uart_putc(unsigned char c) { // gekürzt } void print_mem() { for (unsigned int i = 0; i < 256; i++) { uart_putc(mem_main[i]); } }
Eine ganze Reihe an Bytes unterscheidet sich leider.Code:Erster Aufruf von print_mem(): 0000: A2 13 10 91 46 0B 81 15 - 42 45 00 23 09 05 5E 2F 0010: 2E AA FF FF FF D2 76 00 - 00 63 01 FF FF FF FF FF 0020: 30 30 30 39 32 36 30 30 - 30 30 30 30 00 00 00 A8 0030: 64 64 00 01 00 B6 E4 D6 - 18 00 3F 02 FF FF FF FF 0040: 11 56 7C 07 04 01 12 58 - 04 0D 00 92 58 08 A0 B2 0050: 4F 00 18 03 04 0D 00 4D - 4A 00 E4 4D 08 00 15 59 0060: 04 0E 12 80 05 32 06 90 - 27 08 14 25 04 0D 00 AC 0070: 05 00 4A 08 00 09 12 24 - 04 0D 00 08 00 00 FD 4E 0080: 08 00 16 00 00 10 00 00 - 00 49 00 90 06 11 15 58 0090: 03 03 14 80 01 00 08 90 - FF FF FF FF FF FF FF FF 00A0: FF FF FF FF FF FF FF FF - FF FF FF FF FF FF FF FF 00B0: FF FF FF FF FF FF FF FF - FF FF FF FF FF FF FF FF 00C0: FF FF FF FF FF FF FF FF - FF FF FF FF FF FF FF FF 00D0: FF FF FF FF FF FF FF FF - FF FF FF FF FF FF FF FF 00E0: FF FF FF FF FF FF FF FF - FF FF FF FF FF FF FF FF 00F0: FF FF FF FF FF FF FF FF - FF FF FF FF FF FF FF FF Zweiter Aufruf von print_mem(): 0000: A2 13 10 91 46 0B 81 15 - 42 45 00 23 09 05 5E 2F 0010: 2E AA FF FF FF D2 76 00 - 00 00 00 FF FF FF FF FF 0020: 30 30 30 39 32 36 30 30 - 30 30 30 30 00 00 E0 4C 0030: 08 64 00 4E 08 17 E4 D6 - 18 00 AC 4D 08 00 FF FF 0040: 11 56 7C 07 04 01 12 58 - 04 0D 00 00 A0 21 59 08 0050: A0 B2 4F 00 18 0D 00 52 - 05 00 52 90 05 08 15 59 0060: 04 0E 12 80 05 32 06 90 - 27 08 14 25 04 0D 00 80 0070: 05 00 06 90 01 09 12 24 - 04 0D 00 00 00 00 06 90 0080: 02 11 18 22 03 0B 28 80 - 03 32 06 90 06 11 15 58 0090: 03 03 14 80 01 00 06 90 - FF FF FF FF FF FF FF FF 00A0: FF FF FF FF FF FF FF FF - FF FF FF FF FF FF FF FF 00B0: FF FF FF FF FF FF FF FF - FF FF FF FF FF FF FF FF 00C0: FF FF FF FF FF FF FF FF - FF FF FF FF FF FF FF FF 00D0: FF FF FF FF FF FF FF FF - FF FF FF FF FF FF FF FF 00E0: FF FF FF FF FF FF FF FF - FF FF FF FF FF FF FF FF 00F0: FF FF FF FF FF FF FF FF - FF FF FF FF FF FF FF FF
Ähm, das war nur auf die Schnelle zum Testen..."for (;; _delay_ms(1000))" das meinst du nicht ernst oder?![]()
Was bitte soll denn daran auszusetzen sein?Zitat von TobiKa
@ Trabukh:
Welcher Controller?
Und den Code für uart_init und uart_putc würde ich auch gerne mal sehen.
MfG
Stefan
Der Code der Funktionen steht oben im ersten Post!
Ups, übersehen. Ich habe nur unter dem "Also der bisherige Code sieht so aus:" die "gekürzt" gesehen.Zitat von TobiKa
EDIT: Und der Controller-Typ steht im Titel. Nicht mein Tag.
Ich vermute, dass gar nicht wirklich der immer gleiche Speicherinhalt in einer Endlosschleife ausgegeben wird, sondern dass es zwischendurch einen Reset gibt, und dass sich die damit immer neu von der Karte gelesenen Daten unterscheiden. Meine erste Vermutung "Interrupt ohne ISR" hat sich nicht bestätigt. Nächster Versuch: Watchdog?
MfG
Stefan
Leider trifft beides nicht zu. Ich habe aus Jux einfach mal nach dem ersten Aufruf von print_mem() die Speicherkarte herausgezogen, am Ausgang meiner "Experimente" hat das jedoch nichts geändert.
Watchdog habe ich sicherheitshalber auch nochmal überprüft, der ist definitiv aus.
EDIT: Folgender Code läuft im Übrigen anstandlos:
EDIT 2: Wenn ich in meinem Programm die Baudrate auf 300 Stelle, scheint alles korrekt anzukommen. Wie kann sowas sein?Code:// µC: ATmega644 #include <util/delay.h> #include <avr/io.h> #ifndef F_CPU #define F_CPU 14745600UL #endif #define BAUD 9600UL #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) volatile unsigned char mem_main[256]; int main() { uart_init(); for (unsigned int i = 0; i < 256; i++) { mem_main[i] = i; } for (;; _delay_ms(1000)) { for (unsigned int i = 0; i < 256; i++) { uart_putc(mem_main[i]); } } return 0; } void uart_init() { UBRR0H = (unsigned char) (UBRR_VAL >> 8); UBRR0L = (unsigned char) (UBRR_VAL); UCSR0B = (1 << TXEN0); UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); // Asynchron 8N1 } void uart_putc(unsigned char c) { while (!(UCSR0A & (1 << UDRE0))) { } UDR0 = c; }
EDIT 3: Zugegeben, ein dritter Edit ist schon peinlich, aber ich wurde das ungute Gefühl nicht los, dass mein Terminalprogramm nichts taugt. Die Vermutung hat sich bestätigt, mit hTerm funktioniert alles, wie es soll.![]()
Ich bitte somit um Verzeihung, dass an der völlig falschen Stelle gesucht werde und danke euch beiden für eure Hilfe.![]()
Mich wundert das nur ein Teil der Variable falsch übertragen wird...
Wie dem auch sei, ich benutze auch HTerm und das ist einfach das beste.
Lesezeichen