Forum: PC-Programmierung Wert eines mehrdimensionalen Arrays in ein Array übernehmen


von Le H. (beks)


Lesenswert?

Hallo,

ich habe ein Array und ein mehrdimensionales Array. Ich möchte jetzt dem 
Array z.B. den dritten Wert aus dem mehrdimensionalen zuweisen. Wie mach 
ich das.
1
char array[8] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2
3
char font8x8_basic[128][8] = {
4
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0000 (nul)
5
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0001
6
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0002
7
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   
8
    ....
9
10
array[0] = font8x8_basic[2][0];
11
array[1] = font8x8_basic[2][1];
12
array[2] = font8x8_basic[2][2];
13
array[3] = font8x8_basic[2][3];
14
array[4] = font8x8_basic[2][4];
15
array[5] = font8x8_basic[2][5];
16
array[6] = font8x8_basic[2][6];
17
array[7] = font8x8_basic[2][7];

In dem mehrdimensionalen Array ist wie man schon vermuten kann, eine 
Schriftart für eine 8x8 Matrix enthalten.

Einzelne Zeichen darauf möchte ich temporär in ein Array ablegen, was 
direkt auf die Matrix gemultiplexed wird.

Ich wäre über Hilfe dankbar.

von Dirk B. (dirkb2)


Lesenswert?

Für so etwas ist memcpy gedacht:
1
memcpy(array, font8x8_basic[2], 8);

Aber wenn du nicht unbedingt eine Kopie der Daten brauchst, dann geh 
tauch ein Pointer:
1
char* pointer;
2
3
pointer = font8x8_basic[2];

von Klaus (Gast)


Lesenswert?

Hm. Was ist denn das Problem? Ich meine das so: Dein Codeschnipsel sieht 
so aus als sollte er genau das machen, was Du willst. Man würde, wenn 
man das dann partout so machen wollte/sollte/müsste, memcpy nehmen. Das 
wäre alles.

Allerdings würde man in der Regel gar nichts umkopieren. Nur einen 
Zeiger für die Multiplex-Routine setzen. Umkopieren kostet nämlich 
unnötig Zeit.

von Le H. (beks)


Lesenswert?

Klaus schrieb:
> Allerdings würde man in der Regel gar nichts umkopieren. Nur einen
> Zeiger für die Multiplex-Routine setzen. Umkopieren kostet nämlich
> unnötig Zeit.

Danke für den Tipp. Das mit dem Zeiger werde ich mal probieren und 
andernfalls greif ich auf die Funktion zurück. Danke. Leider hat sich 
grad ein anderes Problem aufgetan.

Seitdem ich das include für die font.h eingebunden habe, bleibt die 
Matrix dunkel. Der Compiler bringt allerdings keine Fehlermeldung. Nehme 
ich Zeile wieder raus, funktioniert alles. Die font.h liegt im selben 
Ordner wie die main.c.
1
#define F_CPU 1000000UL
2
#define PORT_Column PORTB
3
#define DATA 0
4
#define SHIFT 1
5
#define LATCH 2
6
7
#define PORT_Row PORTC
8
#define DATA 0
9
#define SHIFT 1
10
#define LATCH 2
11
12
#include <avr/io.h>
13
#include <stdlib.h>
14
#include <stdio.h>
15
#include <util/delay.h>
16
#include <avr/interrupt.h>
17
#include "font.h"
18
19
//globale Variable für Zeilendurchlauf (veränderbar in der ISR (volatile))
20
volatile uint8_t isrZeile = 0;
21
volatile uint8_t isrRow = 0b10000000;
22
23
char leds[8] = {0b11111000,\
24
             0b10000000,\
25
             0b10000000,\
26
             0b10000000,\
27
             0b11100000,\
28
             0b10000000,\
29
             0b10000000,\
30
             0b11111000};
31
32
33
34
//Prototypen
35
void Set_Column(unsigned char BitMuster);
36
void Set_Row(unsigned char BitMuster);
37
38
ISR(TIMER0_OVF_vect)       // Overflow Interrupt Vector
39
{
40
  //Spalten kurz abschalten um Glimmen von Nachbar_LEDs zu vermeiden
41
  Set_Column(0b00000000);
42
  //Zeilen iterieren
43
  Set_Row(isrRow);
44
45
  //Spalten festlegen
46
  Set_Column(leds[isrZeile]);
47
48
  //Inkrementieren der Zeilen
49
    isrZeile++;
50
51
    //Nach der 8.Zeile wieder auf 0 zurücksetzen
52
    if (isrZeile > 7) isrZeile =0;
53
54
    //Zeilenlaufzähler iterieren 0b10000000 bis 0b00000001 und von vorne
55
  isrRow = (isrRow >> 1);
56
    if(isrRow==0b00000000)isrRow=0b10000000;
57
}
58
59
int main (void) {
60
61
  DDRB  = 0b00000111;
62
  DDRC  = 0b00000111;
63
64
  //Timer konfigurieren
65
  TIMSK |= (1<<TOIE0);  // den Overflow Interrupt des Timers freigeben
66
  TCCR0 = (1<<CS01);    // Vorteiler 8, jetzt zählt der Timer bereits
67
68
  //Interrupts aktivieren
69
  sei();
70
71
  while(1)
72
  {
73
74
75
  }
76
}
77
78
void Set_Column(unsigned char BitMuster)
79
{
80
   unsigned char mask = 0x80;  //0b1000 0000
81
82
   while(mask)
83
   {  //bitMuster = 0b0000 0001
84
      if(BitMuster & mask)  //Ist in BitMuster das Bit mask gesetzt (mask)?
85
        PORT_Column |= (1 << DATA); // das mask Bit in Bitmuster ist gesetzt, dann DATA = true
86
      else
87
        PORT_Column &= ~(1 << DATA);//das mask Bit in Bitmuster ist nicht gesetzt, dann DATA = false
88
89
          PORT_Column ^= (1 << SHIFT); //SHIFT invertieren; Flanke erzeugen um DATA Bit ins Schieberegister zu schieben
90
          PORT_Column ^= (1 << SHIFT); //SHIFT invertieren
91
      mask >>= 1; //mask Bit rechtsschieben
92
   }
93
94
   PORT_Column ^= (1 << LATCH); //LATCH invertieren; Flanke erzeugen um Schieberegister an Ausgänge zu geben
95
   PORT_Column ^= (1 << LATCH); //LATCH invertieren
96
}
97
98
void Set_Row(unsigned char BitMuster)
99
{
100
   unsigned char mask = 0x80;  //0b1000 0000
101
   BitMuster = ~BitMuster;
102
   while(mask)
103
   {  //bitMuster = 0b0000 0001
104
      if(BitMuster & mask)  //Ist in BitMuster das Bit mask gesetzt (mask)?
105
        PORT_Row |= (1 << DATA); // das mask Bit in Bitmuster ist gesetzt, dann DATA = true
106
      else
107
        PORT_Row &= ~(1 << DATA);//das mask Bit in Bitmuster ist nicht gesetzt, dann DATA = false
108
109
          PORT_Row ^= (1 << SHIFT); //SHIFT invertieren; Flanke erzeugen um DATA Bit ins Schieberegister zu schieben
110
          PORT_Row ^= (1 << SHIFT); //SHIFT invertieren
111
      mask >>= 1; //mask Bit rechtsschieben
112
   }
113
114
   PORT_Row ^= (1 << LATCH); //LATCH invertieren; Flanke erzeugen um Schieberegister an Ausgänge zu geben
115
   PORT_Row ^= (1 << LATCH); //LATCH invertieren
116
}

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Le Ha schrieb:

> Seitdem ich das include für die font.h eingebunden habe, bleibt die
> Matrix dunkel.

welcher AVR?

Ein
1
char font8x8_basic[128][8]
schlägt mit immerhin 1K Speicherverbrauch zu Buche. Je nach AVR ist das 
schon eine Menge Holz.
Derartig konstante Daten verbannt man ins Flash.

D.h. dort sind die Daten sowieso. Aber es gibt keinen Grund, warum für 
diese Daten im SRAM Speicher reserviert werden soll und der Programmcode 
erst mal in der Initialisierungsphase die ganzen Daten aus dem Flash ins 
SRAM kopieren soll.

: Bearbeitet durch User
von Le H. (beks)


Lesenswert?

Karl Heinz schrieb:
> welcher AVR?

Hallo Karl Heinz,

ein ATMEGA 8. Daran liegt es dann wohl. Der hat nur 1kB SRAM.

: Bearbeitet durch User
von Klaus (Gast)


Lesenswert?

1. Zunächst mal ist das ein ganz anderes Problem, als das ursprüngliche 
und steht in keinem direkten Zusammenhang. Es ist gute Sitte in Foren, 
dafür einen neuen Thread aufzumachen.

2. Das einzige, was nun wirklich interessant wäre, wäre gerade die 
font.h-Datei und die Auskunft, was denn der Compiler/Linker meldet wenn 
Du die nicht includest. Es sollte dann logischerweise Fehlermeldungen 
geben, da die in der H-Datei enthaltene Variable nicht deklariert bzw. 
definiert ist.
Dein Text allerdings suggeriert, das Du in keinem Fall eine 
Fehlermeldung erhälst. Das ist schlechterdings unmöglich. Da fehlt eine 
Information von Dir.

3. Wie in dem Hinweis-Text vor jedem neuen Beitrag zu lesen ist, ist es 
gute Foren-Sitte, lange Quelltexte nicht in den Beitrag einzufügen, 
sondern als Anhang zu posten.

von Le H. (beks)


Lesenswert?

Klaus schrieb:
> . Das einzige, was nun wirklich interessant wäre, wäre gerade die
> font.h-Datei und die Auskunft, was denn der Compiler/Linker meldet wenn
> Du die nicht includest. Es sollte dann logischerweise Fehlermeldungen
> geben, da die in der H-Datei enthaltene Variable nicht deklariert bzw.
> definiert ist.
> Dein Text allerdings suggeriert, das Du in keinem Fall eine
> Fehlermeldung erhälst. Das ist schlechterdings unmöglich. Da fehlt eine
> Information von Dir.

Ich verwende noch keine Variable aus der Header Datei. Karl Heinz hat 
mit seinen Hinweis auf das 1kB große mehrdimensionale Array recht. In 
der Header ist lediglich ein Array mit 1kB Größe enthalten auf welches 
ich im Programm noch nicht zugreife. Deswegen sicher auch kein 
Fehlermeldung.

Kopiere ich das Array allerdings direkt in die main.c zeigt die Matrix 
das gewünschte Bild. So ganz kann ich es mir nicht erklären.

Mit Punkt 1 und 3 gebe ich dir Recht und gelobe Besserung.

von Le H. (beks)


Lesenswert?

Jetzt noch einmal zum Verständnis bitte. Wird die Header Datei in den 
RAM geladen?

Dann wäre es nur logisch, dass wenn ich den Inhalt von font.h in die 
main.c kopiere alles funktioniert. Denn der ATMEGA8 hat einen 8kB Flash.

von Karl H. (kbuchegg)


Lesenswert?

Le Ha schrieb:

> Kopiere ich das Array allerdings direkt in die main.c zeigt die Matrix
> das gewünschte Bild. So ganz kann ich es mir nicht erklären.

Zufall.

Das Problem ist, dass dein Array 1KB Speicher verbraucht, also alles was 
der Mega8 hat.
Jetzt ist es aber so, dass dieses Array ja initialisiert werden muss. 
Das macht Code, der noch vor deinem main() zur Ausführung kommt. Und 
wenn dieser Code die 1K Daten vom Flash ins SRAM kopiert, dann bügelt er 
sich so ganz nebenbei den Systemstack zu diesem Zeitpunkt nieder.

Hilft nichts. Da brauchst du nicht lange rumzufackeln. Die Font-Daten 
bleiben im Flash und es werden immer nur die Teile bei der Ausgabe 
geholt, die du für die Ausgabe des Zeichens gerade brauchst.

von Le H. (beks)


Lesenswert?

Karl Heinz danke für deine Bemühungen. So ganz ist es bei mir aber noch 
nicht angekommen.

Der ATMEGA8 hat 8kB Flash für den Programmspeicher. Wenn ich jetzt die 
1kB Font in das c-file einbinde, dann müsste das doch funktionieren oder 
nicht?

Ich versteh noch nicht wie ich aus der Misere rauskomme. Die einfachste 
Option wäre sicher ein anderer Controller.

Ich habe jetzt die Font eingekürzt. Da ich leider keinen anderen 
Controller zur Zeit habe.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Le Ha schrieb:
> Karl Heinz danke für deine Bemühungen. So ganz ist es bei mir aber noch
> nicht angekommen.
>
> Der ATMEGA8 hat 8kB Flash für den Programmspeicher. Wenn ich jetzt die
> 1kB Font in das c-file einbinde, dann müsste das doch funktionieren oder
> nicht?

Aber nicht so
1
char font8x8_basic[128][8]

So liegt das Array im SRAM und verbraucht dir das eine KB, das du dort 
hast.

> Ich versteh noch nicht wie ich aus der Misere rauskomme. Die einfachste
> Option wäre sicher ein anderer Controller.


Das einfachste wäre, seine Möglichkeiten kennen zu lernen :-)
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Speicherzugriffe

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:

> Das einfachste wäre, seine Möglichkeiten kennen zu lernen :-)
> https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Speicherzugriffe

Und in diesem Kapitel dann wieder ganz speziell der UNterpunkt
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Flash_mit_flash_und_Embedded-C

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
Noch kein Account? Hier anmelden.