Forum: Mikrocontroller und Digitale Elektronik Vergesslicher, ungeduldiger atmega bei UART


von Martin W. (schnuffituffi)


Lesenswert?

Moin,
ich will die Werte von 3 Hall Sensoren gerne über UART ausgeben. 
Allerdings nur dann, wenn sie sich auch ändern. Das mit dem Ausgeben 
funktioniert soweit. Das mit dem ändern allerdings nicht. Dafür hatte 
ich eine Variable   sensorold angelegt, die dann mit den aktuellen 
Sensorwerten verglichen wird. Leider wird sie immer wieder 0. In jedem 
Schleifendurchlauf! Ich versteh leider nicht warum. Auch das 
_delay_ms(500) wird scheinbar komplett ignoriert.
1
#include <avr/io.h>
2
#define F_CPU 20000000UL
3
#include <util/delay.h>
4
#define BAUD 9600L
5
#include <stdlib.h> 
6
#include <string.h>
7
8
9
10
int uart_putc(unsigned char character)
11
{  
12
  while (!(UCSR0A & (1<<UDRE0))){}    //warten bis Senden möglich
13
  UDR0 = character;
14
  return 0;
15
}
16
int main(void){
17
  
18
  //Initialisieren
19
  DDRD |=  0b11111100; //Phasen Ausgänge
20
21
  //Ausgangsverknüpfung (clear on compare match)
22
  TCCR1A |= (1<<COM1A1);
23
  
24
  //kein Vorteiler
25
  TCCR1B |= (1<<CS10);
26
  
27
  //Fast PWM, 10-bit
28
  TCCR1A |= (1<<WGM11) | (1<<WGM10);
29
  TCCR1B |= (1<<WGM12);
30
  
31
  //OCR1A = 500; //PWM Wert (MAX 1024)
32
  OCR1A = 300;
33
34
  DDRB |=  0b00000010; //PWM Ausgang
35
36
  //UART
37
  UCSR0B |= (1<<TXEN0);  // UART TX einschalten
38
  // Asynchron 8N1 ist bei mega 168 default
39
  UBRR0 = 129;
40
41
  // Pullups für Hall Sensoren
42
  PORTC|=  0b00111000;
43
  
44
  char sensor[200];
45
  uint8_t sensorold = 0;
46
  uint8_t sensorbin = 0;
47
  
48
  
49
  while (1){
50
      
51
    sensorbin = 0;
52
    
53
    if ( PINC & (1<<PINC5) ) {
54
      sensorbin += 1;
55
    }
56
57
    if ( PINC & (1<<PINC4) ) {
58
      sensorbin += 2;
59
    }
60
61
    if ( PINC & (1<<PINC3) ) {
62
      sensorbin += 4;
63
    }
64
    
65
    if(sensorbin != sensorold){
66
      if (sensorbin & 1){
67
        strcat( sensor, "A1\r\n" );
68
      }
69
      else{
70
        strcat( sensor, "A0\r\n" );  
71
      }
72
      
73
      if (sensorbin & 2){
74
        strcat( sensor, "B1\r\n" );
75
      }
76
      else{
77
        strcat( sensor, "B0\r\n" );
78
      }    
79
    
80
      if (sensorbin & 4){
81
        strcat( sensor, "C1\r\n" );
82
      }
83
      else{
84
        strcat( sensor, "C0\r\n" );
85
      }    
86
      
87
      uint8_t i = 0;
88
      uint8_t l = strlen (sensor);
89
    
90
      while (i <= l){
91
        uart_putc(sensor[i]);
92
        i++;
93
      };
94
        
95
      strcpy(sensor, "");// String leeren  
96
      _delay_ms(500);
97
      sensorold = sensorbin;
98
    }    
99
  }
100
}

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Martin W. schrieb:
> Auch das _delay_ms(500) wird scheinbar komplett ignoriert.
Worauf begründest du den Schein? Schließ doch mal ein LED an einen Pin 
an, der mit jedem Zyklus getoggelt wird...

BTW: der Watchdog ist ausgeschaltet?

von fake (Gast)


Lesenswert?

>sensorbin = 0;
>sensorold = sensorbin;

Damit setzt Du doch bei jedem Schleifendurchlauf sensorold auf 0.

von Bastian W. (jackfrost)


Lesenswert?

Hi,

geht es mit
1
If(PINC != sensorold)
2
{
3
    utoa(sensor,PINC,10);
4
    sensorold = PINC;
5
     while (i <= l){
6
        uart_putc(sensor[i]);
7
        i++;
8
    };
9
}

Gruß JackFrost

von Frickelfritze (Gast)


Lesenswert?

fake schrieb:
> Damit setzt Du doch bei jedem Schleifendurchlauf sensorold auf 0.

Nö.

von Martin W. (schnuffituffi)


Lesenswert?

Lothar M. schrieb:
> Martin W. schrieb:
>> Auch das _delay_ms(500) wird scheinbar komplett ignoriert.
> Worauf begründest du den Schein? Schließ doch mal ein LED an einen Pin
> an, der mit jedem Zyklus getoggelt wird...

Das leite ich daraus ab, das mir die Konsole innerhalb einer Sekunde 
bereits völlig zugeballert wird. Daher weiß ich ja auch, das der Rest 
funktioniert. Die ausgegebenen Sensorwerte sind richtig. Daher weiß ich 
auch, dass sensorold am ende der Schleife auf keinen Fall mit 0 
überschrieben wird. Trotzdem ist es beim Sprung in den Anfang der 
Schleife wieder 0.(hab ich mir über uart ausgeben lassen)

>
> BTW: der Watchdog ist ausgeschaltet?

Das klingt sehr spannend, aber wie finde ich das heraus? Die Fuse für 
Watchdog ist nicht gesetzt. Und von Hand hab ich da auch nix 
angeschaltet.

von jb (Gast)


Lesenswert?

>>fake schrieb:
>> Damit setzt Du doch bei jedem Schleifendurchlauf sensorold auf 0.

>Nö.

Wohle. Ganz sicher.

Gruß J

von Joachim B. (jar)


Lesenswert?

kommst du denn überhaupt in diesen Programmteil?

du nutzt strcat! ohne erstmalig sensor[] überhaupt zu initialisieren.

vermutlich sollte es mal NULL sein aber wer weiss?

Martin W. schrieb:
> char sensor[200];

sollte besser char sensor[200]={0}; sein bevor es mit strcat weitergeht!

: Bearbeitet durch User
von Rainer B. (katastrophenheinz)


Lesenswert?

Martin W. schrieb:
> völlig zugeballert wird

Was wird denn ausgegeben?
Beim ersten Scheifendurchlauf ist das char-Array "sensor" 
uninitialisert, es sei denn, der Compiler initialisiert es automatisch 
mit 0en.

von Rainer B. (katastrophenheinz)


Lesenswert?

... guter zweiter Platz ;-)

von Martin W. (schnuffituffi)


Lesenswert?

jb schrieb:
>>>fake schrieb:
>>> Damit setzt Du doch bei jedem Schleifendurchlauf sensorold auf 0.
>
>>Nö.
>
> Wohle. Ganz sicher.
>
> Gruß J

Warum sollte das so sein ?

Zu beginn der Schleife wird meine Sensorspeicher (sensorbin) gelöscht. 
Dann werden die Sensoren in den Speicher geschrieben. Dass das 
funktioniert hat, weiß ich anhand der UART-Ausgabe. sensorbin ist also 
nun nicht mehr 0. Anschließend wird doch erst sensorold = sensorbin; 
ausgeführt.

von jb (Gast)


Lesenswert?

>>sensorbin = 0;
>>sensorold = sensorbin;

Für die beiden isolierten Zeilen schon, den restlichen Code habe ich 
nicht betrachtet.

Gruß J

von Martin W. (schnuffituffi)


Lesenswert?

Joachim B. schrieb:
> kommst du denn überhaupt in diesen Programmteil?
>
> du nutzt strcat! ohne erstmalig sensor[] überhaupt zu initialisieren.
>
> vermutlich sollte es mal NULL sein aber wer weiss?
>
> Martin W. schrieb:
>> char sensor[200];
>
> sollte besser char sensor[200]={0}; sein bevor es mit strcat weitergeht!

Hab ich geändert. Hilft nur leider nicht. Die Ausgabe bleibt die selbe, 
also z.B.:
A1
B0
C1

Aushabe erfolgt geschätzt 10 mal pro Sekunde, oder öfter.

von Peter II (Gast)


Lesenswert?

Martin W. schrieb:
> Aushabe erfolgt geschätzt 10 mal pro Sekunde, oder öfter.

dann hast du ein viel größere Problem:

> _delay_ms(500);

dann sollte maximal 2mal in der sekunde etwas gesendet werden.

von BlaBla (Gast)


Lesenswert?

1
char sensor[200];
2
  uint8_t sensorold = 0;
3
  uint8_t sensorbin = 0;

muss aus der main() heraus.

von Martin W. (schnuffituffi)


Lesenswert?

BlaBla schrieb:
>
1
char sensor[200];
2
>   uint8_t sensorold = 0;
3
>   uint8_t sensorbin = 0;
>
> muss aus der main() heraus.

Warum ?

Peter II schrieb:
> Martin W. schrieb:
>> Aushabe erfolgt geschätzt 10 mal pro Sekunde, oder öfter.
>
> dann hast du ein viel größere Problem:
>
>> _delay_ms(500);
>
> dann sollte maximal 2mal in der sekunde etwas gesendet werden.

Ja davon sprach ich ja auch schon. Deswegen klang das mit dem Watchdog 
ja auch so gut. Aber wenn der nicht per default an ist, kanns das nicht 
sein.

von Bastian W. (jackfrost)


Lesenswert?

Hast du das Programm mal simuliert ? Da darf ja nichts gesendet werden. 
Auch kannst du die Verzögerung messen

Gruß JackFrost

: Bearbeitet durch User
von Frickelfritze (Gast)


Lesenswert?

Wie war das doch nochmal?

Lokale Variablen werden nicht automatisch initialisiert,
globale dagegen schon.

betrifft:
1
char sensor[200];

Eigentlich sollte der Compiler eine Warnung ausgeben ....

von Martin W. (schnuffituffi)


Lesenswert?

Frickelfritze schrieb:
> Wie war das doch nochmal?
>
> Lokale Variablen werden nicht automatisch initialisiert,
> globale dagegen schon.
>
> betrifft:
>
1
char sensor[200];
>
> Eigentlich sollte der Compiler eine Warnung ausgeben ....

Es ist egal ob Global oder nicht initialisiert oder nicht. Fehler 
bleiben leider immer die selben.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Joachim B. schrieb:
> Martin W. schrieb:
>> char sensor[200];
>
> sollte besser char sensor[200]={0}; sein bevor es mit strcat weitergeht!

Das ist suboptimal. Damit werden sämtliche 200 Speicherstellen von 
sensor in einer Schleife genullt, obwohl das gar nicht notwendig ist.

Die erste Stelle reicht nämlich (wg. strcat):
1
char sensor[200];
2
sensor[0] = '\0';

von BlaBla (Gast)


Lesenswert?

BlaBla schrieb:
>
char sensor[200];
>   uint8_t sensorold = 0;
>   uint8_t sensorbin = 0;
>
> muss aus der main() heraus.

Warum ?

Das ist so! Bei jedem Durchlauf der while-Schleife werden die Variablen 
auf Null gesetzt. Mach daraus globale Variablen, dann werden die Inhalte 
beibehalten.

von Joachim B. (jar)


Lesenswert?

Frank M. schrieb:
> Das ist suboptimal. Damit werden sämtliche 200 Speicherstellen von
> sensor in einer Schleife genullt,

stimmt, wer packt das auch in eine Schleife im Code, das gehört sich 
anders!

Frank M. schrieb:
> Die erste Stelle reicht nämlich (wg. strcat):char sensor[200];
> sensor[0] = '\0';

auch das stimmt und ist effektiver wenn der sensor[] unbedingt im Code 
in der while stehen bleiben soll!

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

BlaBla schrieb:
> Das ist so! Bei jedem Durchlauf der while-Schleife werden die Variablen
> auf Null gesetzt. Mach daraus globale Variablen, dann werden die Inhalte
> beibehalten.

Das ist blanker Unsinn. Die Variablen werden ausserhalb der 
while-Schleife definiert und auf Null gesetzt. Da main() auch nie 
verlassen wird, bleiben sie auch als lokale Variablen die ganze Laufzeit 
am Leben.

Sorry, aber Du scheinst wenig bis gar keine Ahnung von C zu haben. Ich 
wäre vorsichtig mit solchen Vorschlägen.

von Peter II (Gast)


Lesenswert?

BlaBla schrieb:
> Das ist so! Bei jedem Durchlauf der while-Schleife werden die Variablen
> auf Null gesetzt.

welche schleife meinst du? Die NACH der Initialisierung?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Joachim B. schrieb:
> auch das stimmt und ist effektiver wenn der sensor[] unbedingt im Code
> in der while stehen bleiben soll!

Die Definition von sensor[] steht gar nicht in der while-Schleife, 
sondern darüber ;-)

Ausserdem ist eine lokale Variable hier sogar ressourcensparender:

Wenn Du sensor[200] nämlich global definierst, werden trotzdem wieder 
200 Speicherstellen gelöscht, obwohl die erste komplett reicht.

Martin W. schrieb:
> strcpy(sensor, "");// String leeren
1
sensor[0] = '\0'

ist hier etwas eleganter. Man muss nicht unbedingt immer mit Funktionen 
auf Variablen schießen - auch wenn sie in moderneren 
C-Compiler-Umgebungen intern abgebildet werden.

: Bearbeitet durch Moderator
von BlaBla (Gast)


Lesenswert?

Meine Antwort hat sich erledigt. Habe heute einen Knick in der Optik. 
Die Variablen stehen an der richtigen Stelle. Auf die Polemik von Frank 
M. werde ich nicht weiter eingehen.

von Joachim B. (jar)


Lesenswert?

Frank M. schrieb:
> Die Definition von sensor[] steht gar nicht in der while-Schleife,
> sondern darüber ;-)

ach was solls der ganze Code ist undurchsichtig!

von Werner P. (Gast)


Lesenswert?

Martin W. schrieb:
> Ich versteh leider nicht warum. Auch das
> _delay_ms(500) wird scheinbar komplett ignoriert.

wenn dem so ist dann resetet der Controller.

mach doch einfach vor der while in der main eine uart Ausgabe. Sagen wir 
Ausgabe von "start".

Dann siehst Du auf jeden Fall ob ein Reset während des Programmablaufs 
stattfindet.

von Rainer B. (katastrophenheinz)


Lesenswert?

Zurück zum Problem des TO:
 - Sind Compiler-Warnings mit -Wall eingeschaltet?
 - Ändert sich etwas, wenn du den delay-wert auf 5000 erhöhst?
 - Poste mal den Build-Output und das .lss-File

von BlaBla (Gast)


Lesenswert?

Noch eine Idee: liegt die richtige Spannung für 20 MHz an.

von Martin W. (schnuffituffi)


Lesenswert?

BlaBla schrieb:
> Noch eine Idee: liegt die richtige Spannung für 20 MHz an.

Spannung sind 4,91V

Werner P. schrieb:
> Martin W. schrieb:
>> Ich versteh leider nicht warum. Auch das
>> _delay_ms(500) wird scheinbar komplett ignoriert.
>
> wenn dem so ist dann resetet der Controller.
>
> mach doch einfach vor der while in der main eine uart Ausgabe. Sagen wir
> Ausgabe von "start".
>
> Dann siehst Du auf jeden Fall ob ein Reset während des Programmablaufs
> stattfindet.

War ne gute Idee. Der Atmel scheint sich neu zu starten. Zumindest wird 
das Start ständig geschrieben. Der neustart erfolgt alle 16 UART Zeichen 
wenn ich mich nicht verzählt hab.
Aber woran kann das liegen ?

von Werner P. (Gast)


Lesenswert?

Martin W. schrieb:
> Aber woran kann das liegen ?

Wenn der Code in deinem Eingangspost alles ist dann kann es eigentlich 
nur noch ein Hardwarefehler sein.

Schaltplan?

Edit: Was passiert wenn Du in der while mal alles ausdokumentierst?

von BlaBla (Gast)


Lesenswert?

Noch eine Idee: AtmelStudio 7 zeigt mir die Variable "sensorbin" nicht 
im Debugger mit der Compiler-Option -Os an. Die wird scheinbar hinfort 
optimiert. Mit der folgenden Änderung wird sie wieder sichtbar.
1
volatile uint8_t sensorold = 0;
2
volatile uint8_t sensorbin = 0;

von CRätsel (Gast)


Lesenswert?

Frank M. schrieb:
>> sollte besser char sensor[200]={0}; sein bevor es mit strcat weitergeht!
>
> Damit werden sämtliche 200 Speicherstellen von
> sensor in einer Schleife genullt, obwohl das gar nicht notwendig ist.

Komisch, mein Compiler initialisiert mit dieser Art
1
char sensor[200]={0};

genau ein Element von sensor[], und zwar das erste. So war
ich es bisher auch gewohnt.

Frank M. scheint einen neuartigen Compiler zu haben oder einen
der einen anderen Standard verfolgt ..... vielleicht M$?

von Joachim B. (jar)


Lesenswert?

CRätsel schrieb:
> Frank M. scheint einen neuartigen Compiler zu haben

kann nicht sein, der Frank weiss es immer besser als ich.....

Ich glaube fast ich muss das wirklich auf meinem Compiler untersuchen 
was da genau passiert obwohl es mir total schnurz ist ob

Joachim B. schrieb:
> char sensor[200]={0};

200 Byte auf 0 setzt oder nur das erste Byte

aber da Frank mir wieder mal widersprach:

Frank M. schrieb:
> Das ist suboptimal. Damit werden sämtliche 200 Speicherstellen von
> sensor in einer Schleife genullt

interessiert es mich schon ob mit Recht oder nur weil er ein 
Widerspruchsgeist ist.

CRätsel schrieb:
> Komisch, mein Compiler initialisiert mit dieser Art
> char sensor[200]={0};
> genau ein Element von sensor[], und zwar das erste. So war
> ich es bisher auch gewohnt.

dafür spricht:

http://www.tutorials.at/c/09-arrays-strings.html
Ein wichtiger Punkt bei lokal deklarierten Arrays ist deren 
Initialisierung. Ein Beispiel:

int daten[3] = { 0, 0, 0 };

Hier wird das Array daten mit 3 Elementen vom Typ int deklariert und 
zugleich definiert. Alle drei Elemente werden auf 0 gesetzt 
(initialisiert). Die einzelnen Werte werden dabei der Reihe nach 
zwischen geschwungenen Klammern { } angegeben.

int daten[] = { 4, 10, -20 };

Hier wurde die Anzahl der Elemente in eckigen Klammern weggelassen. Das 
ist immer dann möglich, wenn ein Array gleich initialisiert wird. Denn 
es geht für den Compiler aus der Initialisierungsliste ohnehin hervor, 
wieviel Speicher und Elemente reserviert werden müssen.

Das erste Element (daten[0]) wird mit 4 initialisiert, das zweite 
(daten[1]) mit 10 und das dritte (daten[2]) und zugleich letzte mit -20.

: Bearbeitet durch User
von Martin W. (schnuffituffi)


Angehängte Dateien:

Lesenswert?

Werner P. schrieb:
> Martin W. schrieb:
>> Aber woran kann das liegen ?
>
> Wenn der Code in deinem Eingangspost alles ist dann kann es eigentlich
> nur noch ein Hardwarefehler sein.
>
> Schaltplan?
>
> Edit: Was passiert wenn Du in der while mal alles ausdokumentierst?

Also ich hab alles im While auskommentiert. Ergebnis: Der Kontroller 
startet permanent neu, statt in der while schleife zu verharren. :'( 
Lass ich ihn etwas Ausgeben, schafft er vor dem Absturz etwa 16 Zeichen. 
Am Reset Pin hab ich mal mit dem Oszi gemessen und konnte nix sehen was 
einen Restart rechtfertigen würde.

Schaltplan hab ich mal angehängt. Ich denke aber mal nicht, dass ich da 
etwas total verkackt habe.

von Frickelfritze (Gast)


Lesenswert?

Martin W. schrieb:
> dass ich da etwas total verkackt habe.

Naja, total nicht aber bisschen schon.

Die Abblock-Cs an Vcc und Avcc fehlen. Was das in deinem Fall
ausmacht wage ich nicht zu beurteilen, aber gut ist das nicht.

Abblock-Cs müssen übrigens direkt am Controller sein.

von Frickelfritze (Gast)


Lesenswert?

Frickelfritze schrieb:
> Abblock-Cs müssen übrigens direkt am Controller sein.

... und dürfen nicht weggelassen werden bloss weil am
Spannungsregler schon welche sitzen .....

von Martin W. (schnuffituffi)


Lesenswert?

Hab nochmal den UART ausgemacht. Leider stürzt er immer noch ab. Hab den 
PWM Ausgang gemessen. Absturz ist zuverlässig nach exact 17,3ms .

von Frickelfritze (Gast)


Lesenswert?

Martin W. schrieb:
> Leider stürzt er immer noch ab.

Aufbau zeigen ....

Die 27pF am Quarz kommen mir etwas hoch vor, könnte die
Betriebssicherheit beeinträchtigen. 18pF müssten reichen.

Ein 78L05 als Spannungsregler ..... ob der Strom ausreicht
um alles zu speisen .... ich weiss nicht was die IRS2184
an Strom ziehen ....

... und wieviel Oberspannung hast du auf der Primärseite
des Reglers?

von Martin W. (schnuffituffi)


Lesenswert?

Frickelfritze schrieb:
> Martin W. schrieb:
>> Leider stürzt er immer noch ab.
>
> Aufbau zeigen ....
>
> Die 27pF am Quarz kommen mir etwas hoch vor, könnte die
> Betriebssicherheit beeinträchtigen. 18pF müssten reichen.
>
> Ein 78L05 als Spannungsregler ..... ob der Strom ausreicht
> um alles zu speisen .... ich weiss nicht was die IRS2184
> an Strom ziehen ....

Der 78L05 versorgt ausschließelich die MCU.

> ... und wieviel Oberspannung hast du auf der Primärseite
> des Reglers?

12V. Die Frage hat das Problem gelöst. Von sowas hab ich noch nie 
gehört, und es ist mir echt peinlich, das die Quasi 1.Frage jeder 
Telefonhotline mein Problem löst. Auf die Frage hin, hab ich das 
Netzteil einmal aus der Steckdose gezogen um nochmal auf die 
Beschriftung zu gucken. 12V DC 800mA. Also eigentlich ok. Nach dem 
wieder reinstecken ging alles.

Ist irgendwem sowas schon mal passiert ? Ich finde das sehr Skuril. Ich 
dachte spätestens nach dem Programmieren und dem damit verbundenen Reset 
müsste ein Absturz des Prozis behoben sein... aber offensichtlich war 
das hier nicht der Fall.

Vielen Dank an alle die geholfen haben und die vielen Tipps nebenbei. 
Der Thread ist damit gelöst.

von Frickelfritze (Gast)


Lesenswert?

Martin W. schrieb:
> Der Thread ist damit gelöst.

Danke für die Rückmeldung!

Aber die Abblock-Cs baust du noch dazu! Sonst gibt's ein
schlechtes Gewissen und ......

von Frickelfritze (Gast)


Lesenswert?

Martin W. schrieb:
> Also eigentlich ok. Nach dem wieder reinstecken ging alles.

Vielleicht wird es dem 78L05 doch etwas ungemütlich wenn er
7 Volt verarbeiten und xx mA liefern muss.

von Martin W. (schnuffituffi)


Lesenswert?

Frickelfritze schrieb:
> Martin W. schrieb:
>> Also eigentlich ok. Nach dem wieder reinstecken ging alles.
>
> Vielleicht wird es dem 78L05 doch etwas ungemütlich wenn er
> 7 Volt verarbeiten und xx mA liefern muss.

Jup. Also gut anfassen kann man ihn nicht. Ich denke ich werde ihn 
tatsächlich tauschen, zumal in der Endfassung 16,88V anliegen können 
sollen.

Das sind dann 11,88V drop. Bei den erlaubten 100mA wären das dann schon 
Rund 1,2 Watt. Andererseits darf das Ding laut Datenblatt 70°C heiß 
werden.

von Frickelfritze (Gast)


Lesenswert?

Martin W. schrieb:
> Andererseits darf das Ding laut Datenblatt 70°C heiß
> werden.

Mit nicht vorhandenen Reserven sollte man nicht spekulieren.

Das nennt man Leben auf Pump.

von guest (Gast)


Lesenswert?

Frickelfritze schrieb:
>> dass ich da etwas total verkackt habe.
>
> Naja, total nicht aber bisschen schon.

L1 an AREF ist auch eher daneben, die würde eher an AVCC Sinn ergeben. 
Wenn man die Versorgungsspannung als Referenz will setzt man einfach die 
REFSn Bits in ADMUX passend.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

CRätsel schrieb:
> Komisch, mein Compiler initialisiert mit dieser Art
> char sensor[200]={0};
> genau ein Element von sensor[], und zwar das erste. So war
> ich es bisher auch gewohnt.
>
> Frank M. scheint einen neuartigen Compiler zu haben oder einen
> der einen anderen Standard verfolgt ..... vielleicht M$?

Der "neuartige" Compiler ist ein stinknormaler avr-gcc.
Testcode:
1
#include <string.h>
2
3
int
4
main ()
5
{
6
    char sensor[200] = { 0 };
7
    strcat (sensor, "Hello World");
8
}

lss-Output:
1
00000096 <main>:
2
  96:  cf 93         push  r28
3
  98:  df 93         push  r29
4
  9a:  cd b7         in  r28, 0x3d  ; 61
5
  9c:  de b7         in  r29, 0x3e  ; 62
6
  9e:  c8 5c         subi  r28, 0xC8  ; 200
7
  a0:  d1 09         sbc  r29, r1
8
  a2:  0f b6         in  r0, 0x3f  ; 63
9
  a4:  f8 94         cli
10
  a6:  de bf         out  0x3e, r29  ; 62
11
  a8:  0f be         out  0x3f, r0  ; 63
12
  aa:  cd bf         out  0x3d, r28  ; 61
13
  ac:  ce 01         movw  r24, r28
14
  ae:  01 96         adiw  r24, 0x01  ; 1
15
  b0:  28 ec         ldi  r18, 0xC8  ; 200
16
  b2:  fc 01         movw  r30, r24
17
  b4:  11 92         st  Z+, r1
18
  b6:  2a 95         dec  r18
19
  b8:  e9 f7         brne  .-6        ; 0xb4 <main+0x1e>
20
  ba:  60 e0         ldi  r22, 0x00  ; 0
21
  bc:  71 e0         ldi  r23, 0x01  ; 1
22
  be:  0e 94 6d 00   call  0xda  ; 0xda <strcat>

Die Initialisierungsroutine geht von 0xac bis 0xb8. Hier werden 200 
Bytes in einer Schleife genullt.

Und jetzt noch die Literatur dazu, dass der avr-gcc das richtig macht, 
während Du entweder irgendetwas dahingeschwätzt oder einen defekten 
Compiler hast:

  http://www.c-howto.de/tutorial-arrays-felder-initialisierung.html

Zitat:
-----------------------------
Ist die Anzahl der Werte bei der Initialisierung kleiner als die 
Feldgröße, werden die restlichen Werte auf Null gesetzt. [...]
Dadurch lässt sich ein Feld auch einfach komplett mit Null-Werten 
initialisieren:

int punkte[5] = { 0 };
-----------------------------

Weitere Links dazu:

  http://stackoverflow.com/questions/2589749/how-to-initialize-array-to-0-in-c
  http://stackoverflow.com/questions/201101/how-to-initialize-all-members-of-an-array-to-the-same-value

Es gibt noch tausende andere Links zu diesem Thema, meinst Du, die lügen 
alle?

: Bearbeitet durch Moderator
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Joachim B. schrieb:
> dafür spricht:
>
> http://www.tutorials.at/c/09-arrays-strings.html
> Ein wichtiger Punkt bei lokal deklarierten Arrays ist deren
> Initialisierung. Ein Beispiel:
>
> int daten[3] = { 0, 0, 0 };
>
> Hier wird das Array daten mit 3 Elementen vom Typ int deklariert und
> zugleich definiert.

Ich muss Dir leider widersprechen: Das spricht überhaupt nicht dafür. 
Das ist der normale Ansatz eines Tutorial-Schreibers, wenn er dem Leser 
die Initialisierung beibringen will.

Der Autor dieses Tutorials kennt lediglich die folgende Regel nicht:

"Wenn eine Initialisierung angegeben wird und diese unvollständig(!) 
ist, wird der Rest automatisch mit Nullen gefüllt".

Die wenigsten kennen diese, obwohl sie steinalt, also keine irgendwelche 
komische "Neuerung" irgendeines Standards ist. Im Gegenteil: Das war 
schon immer so.

von Joachim B. (jar)


Lesenswert?

Frank M. schrieb:
> Ich muss Dir leider widersprechen:

machst du ja gerne, aber ich räume ein eine Fundstelle ist naturgemäß 
wenig aussagekräftig.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Joachim B. schrieb:
> machst du ja gerne,

:-)

> aber ich räume ein eine Fundstelle ist naturgemäß wenig aussagekräftig.

Was Du da zitiert hast, ist ja nicht falsch - höchstens unvollständig. 
Der Autor hätte auf die zusätzliche Möglichkeit der 
Komplettinitialisierung eines Array ruhig hinweisen können.

Bei
1
int daten[2048] = { 0 };

hätte er nämlich sonst eine ziemliche Schreibarbeit :-)

von Georg G. (df2au)


Lesenswert?

Joachim B. schrieb:
> eine Fundstelle ist naturgemäß
> wenig aussagekräftig.

Genügt dir K&R, The C Programming Language, Prentice Hall, Kapitel 4.9, 
auf Seite 84?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Oder auch die Second Edition vom K&R-Klassiker, hier Seite 86:

"If there are fewer initializers for an array than the number specified, 
the missing elements will be zero for external, static, and automatic 
variables."

Also ist kein "neuartiger" Compiler dafür notwendig. Das war schon seit 
Anbeginn von C so.

: Bearbeitet durch Moderator
von Martin W. (schnuffituffi)


Lesenswert?

guest schrieb:
> Frickelfritze schrieb:
>>> dass ich da etwas total verkackt habe.
>>
>> Naja, total nicht aber bisschen schon.
>
> L1 an AREF ist auch eher daneben, die würde eher an AVCC Sinn ergeben.
> Wenn man die Versorgungsspannung als Referenz will setzt man einfach die
> REFSn Bits in ADMUX passend.

Du hast vollkommen recht, da hab ich kacke gebaut! Wird natürlich 
korrigiert.

von Joachim B. (jar)


Angehängte Dateien:

Lesenswert?

Georg G. schrieb:
> Genügt dir K&R, The C Programming Language, Prentice Hall, Kapitel 4.9,
> auf Seite 84?

habe ich nicht, aber das hier ist auch interessant!

QC hält sich nicht an die automatische Arraygröße wenn Werte vorgegeben 
sind

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Joachim B. schrieb:
> QC hält sich nicht an die automatische Arraygröße wenn Werte vorgegeben
> sind

Die früheren C-Compiler für Windows aus den 80ern haben jede Menge 
falsch bzw. "anders" gemacht als das UNIX-Original. Wirf das QuickC-Buch 
am besten wech oder verfeuere es im Kamin, aber verschenke es 
keinesfalls. Der andere könnte darin lesen und einiges lernen, was 
schlicht und einfach falsch ist. ;-)

: Bearbeitet durch Moderator
von Joachim B. (jar)


Lesenswert?

Frank M. schrieb:
> Die früheren C-Compiler für Windows

sorry das war DOS! (alles weisst du auch nicht gelle :)

und das M$ immer alles anders macht weiss man ja, wieso wurde 
dennFAT16(!?) auf int 32k Cluster reglementiert? wenn es auch locker 
uint 64k Cluster sein könnten? denn negative Cluster will ja keiner.

Ich muss noch mal nach meinem Sybex Buch suchen, nur das hier fiel mir 
gerade beim Werkstattumzug in die Hände.

: Bearbeitet durch User
von Georg G. (df2au)


Lesenswert?

Joachim B. schrieb:
> sorry das war DOS!

Möchtest du eine Windows Version von QC haben? Mit LCC32 erzeugt.

von Joachim B. (jar)


Lesenswert?

Georg G. schrieb:
> Möchtest du eine Windows Version von QC haben? Mit LCC32 erzeugt.

habe sogar das Original, als QC für win und als VC für win aber leider 
ziemlich unbrauchbar, die hatten sogar mit Kompatiblität geworben, war 
aber nur geschönt, meinte Quellcode kompatibel, was für ein Witz, die HP 
IEEE Libs konnte man nicht nutzen.

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.