Wer kann mir helfen. Ein Atmega 32, ein LCD 2x16 und ein SD Karten Modul. Ich habe den Beispiel Quellcode aus dem Buch "AVR Hardware und Programmierung in C" sd-karte.c für ein Projekt verwendet. Ich zeichne die Temperatur mit Zeit und Datum auf je Stunde. Mit einen Taster kann ich die Aufzeichnung stoppen und die Karte im Programm wechseln. Die Aufzeichnung funktioniert sehr gut alles OK. Weiter habe ich ein umfangreiches Programm mit Ausgabe und Untermenüs auf einen 2x16 LCD für Temperatur-Max -Min Datum- Zeit- Batteriespannungsanzeige....und Auswertungen ....mit einen Programmteil zur Einstellung der des Datums und der Uhr erstellt. Alles funktioniert sehr gut. Mein Problem ich schaffe es nicht die beiden Programme zusammenzuführen. Die SD Karten Aufzeichnung funktioniert störungsfrei aber das LCD geht nicht es zeigt sinnlose Zeichen an nach der Initialisierung der SD Karte und ist nicht mehr ansprechbar. Hier der C Code. Ich habe ein einfaches Beispiel erzeugt zur Demonstration. Die erste Zeile Datensatz 1 wird fehlerfrei angezeigt. Nach der Programmstelle timer0_init(); Geht das LCD noch richtig und gibt fehlerfrei die zweite Zeile aus. Nach dem nächsten Programmschritt uinit();// uart config ist Schluss danach geht es nicht mehr. Aber wie gesagt die Aufzeichnung auf die SD Karte funktioniert fehlerfrei. Mein erster Verdacht war die Variable str[20] im C Code SD Karte und die gleiche Variable str[5] im C Code des LCD, aber nach der Änderung str[5] in strl[5] für das LCD ist der Fehler nicht behoben. Ich denke es ist ein Zeiger Konflikt? Im C Code und den Bibliotheken der SD Karte sind viele static Variablen und in der #include <util/LCD_display_free_int_pins.h> für das LCD keine static? Vielen Dank , Ich bin noch Anfänger zwei dicke Bücher habe ich schon gelesen aber hier komme ich nicht weiter. hier der C code Beispiel und die #include <util/LCD_display_free_int_pins.h> und #include "uart.h" und uart.c
1 | /**
|
2 | * Greift auf eine SD Karte per SPI zu
|
3 | *
|
4 | * Doku, siehe http://www.mikrocontroller.net/articles/AVR_FAT32
|
5 | * Neuste Version: http://www.mikrocontroller.net/svnbrowser/avr-fat32/
|
6 | *
|
7 | *
|
8 | */
|
9 | |
10 | #define F_CPU 8000000UL
|
11 | #include <avr/io.h> |
12 | #include <util/delay.h> // definiert _delay_ms() |
13 | |
14 | |
15 | #include <avr/interrupt.h> |
16 | #include <stdio.h> |
17 | #include <mmc_config.h> // Hier werden alle noetigen Konfigurationen vorgenommen, umbedingt anschauen ! |
18 | #include <file.h> |
19 | #include <fat.h> |
20 | #include <mmc.h> // Hardware abhaengig |
21 | #include <uart.h> // Hardware abhaengig, es kann auch eine eigene eingebunden werden ! |
22 | |
23 | #include <avr/BitUtilities.h> |
24 | |
25 | #include <util/LCD_display_free_int_pins.h> |
26 | |
27 | char strl [5]; |
28 | int xx = 0; // Zähler Datensatz |
29 | |
30 | |
31 | //"""" SD Karte """"""""""""""""""""""""""""""""""""""""""""""""""""
|
32 | |
33 | // prototypen von funktionen in dieser datei
|
34 | static void timer0_init(void); |
35 | int main(void); |
36 | |
37 | // timer0 einstellungen, werte mit http://www.avrcalc.com/download.html berechnet!
|
38 | // aus diesen 3 werten ergibt sich die tick zeit, hier 10ms.
|
39 | // 4 = prescaler 256, 3 = prescaler 64, 5 = prescaler 1024, 2 = prescaler 8. wenn prescaler 0 = prescaler dann stoppt der timer
|
40 | #if(F_CPU == 4000000) // error 0.16%
|
41 | #define TOP_OCR 0x9B
|
42 | #define START_TCNT 0x64
|
43 | #define PRESCALER 0x04
|
44 | #endif
|
45 | |
46 | #if(F_CPU == 8000000) // error 0,16%
|
47 | #define TOP_OCR 0x4D
|
48 | #define START_TCNT 0xB2
|
49 | #define PRESCALER 0x05
|
50 | #endif
|
51 | |
52 | #if(F_CPU == 10000000) // error 0.351%
|
53 | #define TOP_OCR 0x61
|
54 | #define START_TCNT 0x9E
|
55 | #define PRESCALER 0x05
|
56 | #endif
|
57 | |
58 | #if(F_CPU == 12000000) // error 0.16%
|
59 | #define TOP_OCR 0x74
|
60 | #define START_TCNT 0x8B
|
61 | #define PRESCALER 0x05
|
62 | #endif
|
63 | |
64 | #if(F_CPU == 16000000) // error 0,16%
|
65 | #define TOP_OCR 0x9B
|
66 | #define START_TCNT 0x64
|
67 | #define PRESCALER 0x05
|
68 | #endif
|
69 | |
70 | #if(F_CPU == 20000000) // error 0.16%
|
71 | #define TOP_OCR 0x4D
|
72 | #define START_TCNT 0xB2
|
73 | #define PRESCALER 0x04
|
74 | #endif
|
75 | |
76 | // timer0 variable
|
77 | volatile uint8_t TimingDelay; // fuer mmc.c |
78 | |
79 | ISR (TIMER0_COMP_vect) |
80 | {
|
81 | TimingDelay = (TimingDelay==0) ? 0 : TimingDelay-1; |
82 | }
|
83 | |
84 | static void timer0_init() |
85 | {
|
86 | // timer0 config
|
87 | // initialisierung, auf jeden fall vor mmc_init(),
|
88 | // denn da wird der timer benoetigt!
|
89 | |
90 | TimingDelay = 0; // initialisierung der zaehl variable |
91 | |
92 | TCCR0 = 1<<WGM01; // timer0 im ctc mode |
93 | TIMSK = 1<<OCIE0; // compare interrupt an |
94 | |
95 | TCNT0 = START_TCNT; // ab wo hochgezaehlt wird, |
96 | OCR0 = TOP_OCR; // maximum bis wo gezaehlt wird bevor compare match |
97 | |
98 | TCCR0 = PRESCALER; // wenn prescaler gesetzt wird, lauft timer los |
99 | sei(); // interrupts anschalten, wegen compare match |
100 | }
|
101 | |
102 | |
103 | // ***** Haupt Programm ************************************************************************************************************
|
104 | |
105 | |
106 | int main(void) |
107 | |
108 | {
|
109 | |
110 | lcd_init(); lcd_send(COMMAND, LCD_CLEAR); //LCD |
111 | lcd_set_cursor (1, 1);lcd_write ("Datensatz"); //LCD |
112 | sprintf(strl,"%02d",xx); lcd_set_cursor (1, 12); lcd_write (strl); //LCD |
113 | |
114 | |
115 | //""""" SD Karte Aktivierung """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
116 | |
117 | uint8_t file_name [] = "Temp.txt"; |
118 | char str [20]; |
119 | |
120 | timer0_init(); // Timer initialisieren bevor FAT Library genutzt wird |
121 | |
122 | |
123 | lcd_set_cursor (2, 1);lcd_write ("Datensatz"); //LCD letze funktionierende Stelle |
124 | sprintf(strl,"%02d",xx); lcd_set_cursor (2, 12); lcd_write (strl); //LCD letze funktionierende Stelle |
125 | |
126 | |
127 | uinit(); // uart config |
128 | |
129 | uputs((uint8_t*)"Start"); |
130 | |
131 | // sd/mmc config
|
132 | if( FALSE == mmc_init() ) |
133 | {
|
134 | uputs((uint8_t*)" -> Fehler Init. Ende\n"); |
135 | return -1; |
136 | }
|
137 | |
138 | // fat config
|
139 | if( FALSE == fat_loadFatData() ) |
140 | {
|
141 | uputs((uint8_t*)" -> Fehler loadFatData. Ende\n"); |
142 | return -1; |
143 | }
|
144 | |
145 | uputs((uint8_t*)" OK\n"); |
146 | |
147 | |
148 | |
149 | // ********************** Datei schreiben auf SD **********************
|
150 | |
151 | for (unsigned char i = 0; i <= 9; i++) |
152 | {
|
153 | xx++; |
154 | |
155 | if( MMC_FILE_OPENED == ffopen(file_name,'r') ) // Oeffne existierende Datei zum anhaengen von Daten. Wenn geklappt |
156 | {ffseek(file.length);} // Gehe ans Ende der Datei und LED2 an |
157 | |
158 | else
|
159 | {ffopen(file_name,'c');} |
160 | |
161 | sprintf (str, "Datensatz %2d\r\n",xx); // DOS Zeilenumbruch |
162 | ffwrites ((uint8_t*)str); |
163 | ffclose(); |
164 | }
|
165 | |
166 | lcd_set_cursor (2, 1);lcd_write ("Datensatz"); //LCD |
167 | sprintf(strl,"%02d",xx); lcd_set_cursor (2, 12); lcd_write (strl); //LCD |
168 | |
169 | return(0); |
170 | }
|
und die #include <util/LCD_display_free_int_pins.h>
1 | // LCD Output for HD44780 compatible displays
|
2 | // Pinning adapted to set interrupt pins free
|
3 | // Target: ATMEGA8
|
4 | |
5 | #include "BitUtilities.h" |
6 | |
7 | // LCD control cmmands
|
8 | #define LCD_CLEAR 0x01 /*Clear display: 0b 0000 0001 */ |
9 | #define LCD_HOME 0x02 /*Cursor home: 0b 0000 0010 */ |
10 | #define LCD_ON 0x0C /*Cursor invisible: 0b 0000 1100 */ |
11 | #define LCD_OFF 0x08 /*Display off: 0b 0000 1000 */ |
12 | #define POS_01 0x80 /*Line 1 - Column 0 0b 1000 0000 */ |
13 | #define POS_02 0xC0 /*Line 2 - Column 0 0b 1100 0000 */ |
14 | // definitions of port pins
|
15 | #define LCDPORT PORTD
|
16 | #define LCDDDR DDRD
|
17 | #define LCD_PIN_RS 0
|
18 | #define LCD_PIN_E 3
|
19 | #define LCD_PIN_D4 4
|
20 | #define LCD_PIN_D5 5
|
21 | #define LCD_PIN_D6 6
|
22 | #define LCD_PIN_D7 7
|
23 | |
24 | #define COMMAND 0
|
25 | #define DATA 1
|
26 | |
27 | void toggle_enable_pin(void) |
28 | {
|
29 | sbi(LCDPORT, LCD_PIN_E); cbi(LCDPORT, LCD_PIN_E); |
30 | }
|
31 | |
32 | void lcd_send(unsigned char type, unsigned char c) |
33 | {
|
34 | unsigned char sic_c; // backup for c |
35 | |
36 | // send high nibble
|
37 | sic_c = c; // save original c |
38 | sic_c &= ~0x0f; // set bit 0-3 == 0 |
39 | if (type==DATA) sic_c |= (1<<LCD_PIN_RS); // data: RS = 1 |
40 | LCDPORT = sic_c; toggle_enable_pin(); // send high nibble |
41 | |
42 | // send low nibble
|
43 | sic_c = c; // save original c |
44 | sic_c = sic_c<<4; // exchange nibbles |
45 | sic_c &= ~0x0f; // set bit 0-3 == 0 |
46 | if (type==DATA) sic_c |= (1<<LCD_PIN_RS); // data: RS = 1 |
47 | LCDPORT = sic_c; toggle_enable_pin(); // send low nibble |
48 | _delay_ms(5); // Wait for LCD controller |
49 | }
|
50 | |
51 | // set cursor to line x and column y
|
52 | void lcd_set_cursor(uint8_t line, uint8_t col) |
53 | { uint8_t i; |
54 | switch (line) |
55 | { case 1: i=0x80+0x00+col; break; // 1. line |
56 | case 2: i=0x80+0x40+col; break; // 2. line |
57 | default: return; // invalid line |
58 | }
|
59 | lcd_send(COMMAND, i); |
60 | }
|
61 | |
62 | // write string to LCD
|
63 | void lcd_write(char *data) |
64 | { while(*data) {lcd_send(DATA, *data); data++;} |
65 | }
|
66 | |
67 | // Initializing LCD controller - see data sheet for details
|
68 | void lcd_init() |
69 | {
|
70 | /* Set Port to Output */
|
71 | LCDPORT = 0x00; LCDDDR = 0xFF; |
72 | _delay_ms(50); // Wait for LCD |
73 | |
74 | /* 4-bit Modus config */
|
75 | sbi(LCDPORT, LCD_PIN_D5); cbi(LCDPORT, LCD_PIN_D4); |
76 | |
77 | /* 4-Bit Modus start */
|
78 | sbi(PORTD, LCD_PIN_E); cbi(PORTD, LCD_PIN_E); _delay_ms(5); |
79 | |
80 | /* 2 Lines, 4-Bit Mode */
|
81 | lcd_send(COMMAND, 0x28); |
82 | lcd_send(COMMAND, LCD_OFF); lcd_send(COMMAND, LCD_CLEAR); |
83 | lcd_send(COMMAND, 0x06); lcd_send(COMMAND, LCD_ON); |
84 | }
|
hier die #include "uart.h"
1 | *
|
2 | * Doku, siehe http://www.mikrocontroller.net/articles/AVR_FAT32 |
3 | * Neuste Version: http://www.mikrocontroller.net/svnbrowser/avr-fat32/ |
4 | * Autor: Daniel R. |
5 | */
|
6 | |
7 | |
8 | #ifndef _UART_H
|
9 | |
10 | #define _UART_H
|
11 | #define BAUD 9600l
|
12 | #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
|
13 | |
14 | |
15 | #if defined (__AVR_ATmega168__)
|
16 | #define UDR UDR0
|
17 | #define UCSRA UCSR0A
|
18 | #define UDRE UDRE0
|
19 | #define UCSRB UCSR0B
|
20 | #define RXC RXC0
|
21 | #define UCSRC UCSR0C
|
22 | #define UCSZ0 UCSZ00
|
23 | #define RXEN RXEN0
|
24 | #define TXEN TXEN0
|
25 | #define UBRRH UBRR0H
|
26 | #define UBRRL UBRR0L
|
27 | #endif
|
28 | |
29 | //#######################################################################################################################
|
30 | // funktionen
|
31 | |
32 | extern void uinit(void); //Initialisiert uart |
33 | extern void uputc(uint8_t c); |
34 | extern void uputs (uint8_t *s); |
35 | extern void ugets( int8_t*,uint8_t); |
36 | extern uint8_t ugetc(void); |
37 | |
38 | #endif
|
39 | |
40 | |
41 | /*
|
42 | Terminal VT100 zeichen
|
43 | |
44 | uputc(0x1B); //steuer zeichen ESC (hex 0x1B, dez 27) Achtung, wird erst gesendet wenn danach ein string gesendet wird !! siehe uputs uputc
|
45 | |
46 | uputs("[1K"); //links vom cursor zeile löschen
|
47 | uputs("[K"); //rechts vom cursor zeile löschen
|
48 | uputs("[2J"); //vom cursor abwärts schirm löschen
|
49 | uputs("[J"); //vom cursor aufwärts schirm löschen
|
50 | |
51 | uputs("[01;01H"); //position cursor zeile 1, spalte 1
|
52 | |
53 | * die Zeilennummer 1-24
|
54 | * die Spalternummer 1-80 oder 1-132
|
55 | |
56 | |
57 | <ESC>[paramm '-(das ist ein kleines "m" am Schluß)-'
|
58 | |
59 | Mögliche "param" sind:
|
60 | |
61 | * 0 = Normal
|
62 | * 1 = Heller (bold)
|
63 | * 4 = Unterstrichen
|
64 | * 5 = Blinkend
|
65 | * 7 = Reverse (dunkel auf hell bzw. umgekehrt)
|
66 | |
67 | Dabei können mehrere Attribute angegeben werden, dann aber mit Semikolon getrennt:
|
68 | |
69 | <ESC>[param1;param2;param3m
|
70 | */
|
und die uart.c
1 | /*
|
2 | * Doku, siehe http://www.mikrocontroller.net/articles/AVR_FAT32
|
3 | * Neuste Version: http://www.mikrocontroller.net/svnbrowser/avr-fat32/
|
4 | * Autor: Daniel R.
|
5 | */
|
6 | |
7 | #define F_CPU 8000000UL
|
8 | #include "mmc_config.h" |
9 | #include "uart.h" |
10 | |
11 | |
12 | |
13 | //***********************Funktionen**********************************
|
14 | void uputc(uint8_t c){ //zeichen senden |
15 | |
16 | loop_until_bit_is_set(UCSRA,UDRE); // warten bis puffer frei ist |
17 | UDR = c; // zeichen schreiben |
18 | }
|
19 | |
20 | //*******************************************************************
|
21 | void uputs (uint8_t *s){ //string senden |
22 | |
23 | while(*s) uputc(*s++); //sendet zeichenkette, bis ende.. '\0' |
24 | |
25 | }
|
26 | |
27 | #if (!1)
|
28 | |
29 | // *******************************************************************
|
30 | uint8_t ugetc(void){ //zeichen holen |
31 | |
32 | while (!(UCSRA & (1<<RXC))) {;} // warten bis Zeichen verfuegbar |
33 | |
34 | return UDR; // Zeichen aus UDR an Aufrufer zurueckgeben |
35 | }
|
36 | |
37 | |
38 | // *******************************************************************
|
39 | void ugets(int8_t* Buffer, uint8_t MaxLen){ // zeichenkette holen |
40 | uint8_t NextChar; |
41 | uint8_t StringLen = 0; |
42 | |
43 | NextChar = ugetc(); // Warte auf und empfange das nächste Zeichen |
44 | |
45 | while( NextChar != '\n' && StringLen < MaxLen - 1 ) { //string ende oder puffer voll |
46 | *Buffer++ = NextChar; |
47 | StringLen++; |
48 | NextChar = ugetc(); |
49 | }
|
50 | |
51 | *Buffer = '\0'; //string abschluss |
52 | }
|
53 | #endif
|
54 | |
55 | |
56 | //*******************************************************************
|
57 | void uinit (void){ //init usart Tx, 8n1 ,UDRE interupt enable |
58 | |
59 | UCSRC |= (3<<UCSZ0); // URSEL = 1 dann wird UCSRC benutzt sonst UBRRH ; UCSZ0=data register- 8bit; USBS stop bit 1 |
60 | //Baudrate (high und low byte)
|
61 | UBRRH = (uint8_t)(UBRR_VAL>>8); |
62 | UBRRL = (uint8_t)UBRR_VAL; |
63 | UCSRB |= (1<<TXEN)|(1<<RXEN); // UART TX,RX einschalten, data register empty interrupt enable, |
64 | }
|