Forum: Mikrocontroller und Digitale Elektronik ATtiny13 C-Programm zu groß


von Markus P. (papi70)


Angehängte Dateien:

Lesenswert?

Salve zusammen,

so es darf gelacht werden. Ich habe keine Ahnung von C und keine vom µC 
und habe in den letzten Wochen eine Platine gebaut & ein C-Programm für 
einen ATtiny13 geschrieben.

Software: AVR Studio 4 Vers. 4.16 Build 628
Hardware: ATtiny13
Anschlüsse: PB4 ist ein Analogeingang
            PB0 ein PWM-Ausgang

Ziel der Schaltung: einen im PKW vorhandenen NTC in ein PWM mit 
unterschiedlichem Duty_Cycle zu wandeln um dann eine Anzeigegerät die 
Kühlwassertemperatur genauer anzuzeigen. Über die HW brauchen wir aber 
bitte nicht zu diskutieren

Problem. das erste .hex-file hatte 13kb und nun bin ich schon durch 
schmerzliches geizen auf 10kB runter, aber der ATTiny hat 1kB und ich 
komme nicht weiter...

Eigentlich wollte ich eine PWM mit 50kHz und veränderlichem Duty_cycle 
haben, aber das geht wohl nur über die CTC-Betriebsart und das wäre 
nicht so gut

Danke für Tipps und es wäre nett, wenn ich nicht gleich völlig zerlegt 
würde:
1
#include <avr/io.h>
2
3
// Variablen
4
  uint8_t I = 53; // Strom bei 47 Ohm in mA Wertebereich 1..75,5
5
  uint8_t Duty_Cycle = 50; // Duty_Cycle in Prozent Wertebereich 1..100
6
  uint16_t U; // aktuelle Spannung am NTC in mV  Wertebereich 1..5000
7
  uint8_t R;  // NTC_Widerstandswert Wertebereich 1..128
8
9
// AD-Wandler-Prozedur +++ AD-Wandler-Prozedur +++ AD-Wandler-Prozedur +++ AD-Wandler-Prozedur
10
11
uint16_t ReadChannel()  
12
{
13
  uint8_t i;       // Zähler Wertebereich 1..5
14
  uint16_t result; // Spannung am NTC  Wertebereich 1..1024
15
 
16
  ADMUX = 0b00000010; // externe Referenzspannung nutzen und Kanal PB4 auswählen
17
 
18
  ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler setzen auf 8 (1) und ADC aktivieren 
19
   
20
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
21
  
22
  ADCSRA |= (1<<ADSC);                      // eine ADC-Wandlung 
23
  while ( ADCSRA & (1<<ADSC) ) {
24
     ;                           // auf Abschluss der Konvertierung warten 
25
  }
26
  result = ADCW;                    // ADCW muss einmal gelesen werden,
27
                                    // sonst wird Ergebnis der nächsten Wandlung
28
                                    // nicht übernommen.
29
 
30
  /* Messung - Mittelwert aus 5 aufeinanderfolgenden Wandlungen */
31
  result = 0; 
32
  for( i=0; i<5; i++ )
33
  {
34
    ADCSRA |= (1<<ADSC);                    // eine Wandlung "single conversion"
35
    while ( ADCSRA & (1<<ADSC) ) {
36
      ;                         // auf Abschluss der Konvertierung warten
37
    }
38
    result += ADCW;                    // Wandlungsergebnisse aufaddieren
39
  }
40
  ADCSRA &= ~(1<<ADEN);                     // ADC deaktivieren
41
 
42
  result /= 5;                             // Summe durch 5 teilen = arithm. Mittelwert
43
44
  result = result * 5000/1024;            // Umwandeln in den Spannungswert
45
 
46
  return result;
47
}
48
49
  
50
// PWM-Prozedur +++ PWM-Prozedur +++ PWM-Prozedur +++ PWM-Prozedur +++ PWM-Prozedur +++
51
52
void PWM(uint8_t duty_cycle)
53
{
54
   OCR0A = (duty_cycle*255/100);
55
}
56
57
58
     
59
           
60
// Hauptprogramm +++ Hauptprogramm +++ Hauptprogramm +++ Hauptprogramm +++ Hauptprogramm +++ Hauptprogramm +++  
61
62
      int main (void)
63
  
64
      {
65
      //  Initial I/O
66
67
      ACSR  = 0b10000000;      // Analog-Komparator abschalten, spart Strom. ACD-Bit im ACSR auf 1. Außerdem müssen wir sicherstellen, dass die Intern Voltage Reference nicht auf den Analog Comparator geschaltet ist. Dazu muss ACBG in ACSR auf 0 gesetzt werden.
68
         DDRB  = 0b00000001;         // PB0 ist PWM-Ausgang; Rest Eingang
69
70
      PORTB = 0b00000001;         // interne Pull-Ups an Port-Pins 1 bis 7 deaktiviert
71
      
72
      TCCR0A = 0b11000011;      // COM0A1 - COM0A0 (Set OC0A on Compare Match, clear OC0A at TOP) WGM01 - WGM00 (set fast PWM)
73
        TCCR0B = 0b00000001;      // Prescaler = 1 => 37,647 kHz PWM-Frequenz
74
      OCR0A = 0;          // clear OC0A at TOP, initialize Output Compare Register A to 0
75
76
          while(1)             // Endlosschleife
77
78
      {                
79
        //  Analogwert U von PB4 (MUX10) einlesen mit ADC-Noise-Reduzierung wusste ich nicht wie
80
81
      U = ReadChannel();
82
            
83
      //  Spannungswert in NTC_Widerstandswert umwandeln  
84
85
      R = U/I;
86
87
      //  Duty_Cycle berechnen:
88
89
      Duty_Cycle = (2.8236*R - 84.199);
90
      
91
      
92
              PWM(Duty_Cycle);      //  PWM-Duty-Cycle an Ausgang PB0
93
      //    }  
94
 
95
          
96
  
97
              return 0;
98
    }

von Peter D. (peda)


Lesenswert?

Ja ne, float paßt nicht rein:
1
Duty_Cycle = (2.8236*R - 84.199);

Das mußte schon nen ATtiny25 nehmen.
Oder die Rechnung auf int/long umstellen.


Peter

von skorpionx (Gast)


Lesenswert?

IC MCU AVR 1K FLASH 20MHZ 20MLF - ATTINY13-20MU - Integrierte 
Schaltkreise (ICs)

Nur 1K FLASH!

von skorpionx (Gast)


Lesenswert?

1K FLASH oder 2K FLASH. Mit so wenig Speicher würde ich nicht in „C“ 
versuchen zu programmieren. Dann bin ich mit meinen kleinen (28 Pins) 
PIC18F258 mit 32K Flash wesentlich besser gestellt. Es gibt auch im 
gleichen Gehäuse nächste Stufe  mit doppelt so viele Flash. Das war für 
mich auch ein Argument für PIC.

von Markus P. (papi70)


Lesenswert?

SCHEISSE bin ich doof. Jo ich habe jetzt alles in mV und mOhm und mA 
gerechnet um die Kommas loszuwerden. Es passt. Geil - Danke - Super - 
gute Nacht - saugut - bin begeistert. Super.

DANKE!!!!!!!!!!!!!!!!!

von Gast (Gast)


Lesenswert?

Wie groß ist das kompilierte Programm denn jetzt? Nur so aus Interesse 
:)

von Peter D. (peda)


Lesenswert?

skorpionx schrieb:
> 1K FLASH oder 2K FLASH. Mit so wenig Speicher würde ich nicht in „C“
> versuchen zu programmieren.

Und warum nicht?
Mag ja aufm PIC anders sein, aber der AVR-GCC ist garnicht so schlecht.

Das Programm ist mit der float Multiplikation genau 1130Byte groß, paßt 
also bequem in 2kB.

Und wenns doch etwas mehr sein soll, die AVR 8-, 14- und 20-Pinner gehen 
bis 8kB, die 28-Pinner bis 32kB.


Peter

von Markus P. (papi70)


Lesenswert?

also laut Windoof hat es 1364Bytes aber der ATtiny frisst es. Ob es 
klappt sehe ich morgen am Auto, jetzt is zu dunkel. Hier auf dem Tisch 
(also ohne Kühlmitteltemperaturanzeige) zeigt das HP-DVM die errechnete 
PWM-Frequenz an und spuckt auch ne Spannung aus

von Markus P. (papi70)


Lesenswert?

jo ich wollte auch immer PIC machen, aber damit schafft in meiner 
Umgebung keiner. Zur Zeit sitze ich aber im Norden und es ist 
Urlaubszeit. Da kann ich kaum fragen. Ich bin ja mal froh überhaupt mal 
angefangen zu haben. Bisher habe ich alles analog aufgebaut. Und ich 
finde programmieren immer noch doof.

In jedem Fall hat das Forum und vor allem das AVR-GCC-Tutorial sehr 
geholfen und ich finde es bemerkenswert wie sich hier Leute in die Kurve 
legen um eine mangelhafte Dokumentation von Atmel auch unbedarften 
Erdbewohnern nahezubringen. Früher gab es noch gute Handbücher oder 
Fachbücher. Ich denke nur an die Top-Elektronik-Reihe zum Bsp für den 
NE555. Heute zahlt man nen Haufen Geld für ein Buch was dann doch nicht 
hilft.

So - nu is gut. Ich danke nochmals

von skorpionx (Gast)


Lesenswert?

Ich bin seit sehr vielen Jahren beruflich  bei der Programmierung tätig.
Angefangen habe ich mit dem Assembler. In der ganzen Welt existieren
tausende Anlage in deren meine Ideen sich verwirklichen.
Am Anfang für kleine Prozessoren war es nur Assembler. Dann kam
68000 von Motorola und habe ich in „C“ programmiert. Viele
Bibliotheken   wurden aber weiter (Gewohnheit…) in Assembler 
geschrieben.
Motorola hat die Entwicklung vernachlässig und kam Intel.
Unsere Assemblerbibliotheken waren plötzlich nichts Wert.
Jetzt appelliere ich an alle Anfänger. Vergisst den Assembler.
Nur eine Hochsprache garantiert Unabhängigkeit von Prozessorentypen.
Die gleiche (#define…) C-Code kann man für PIC oder AVR verwenden.
Vergessen sollte man nicht den Satz: „Reserve für zukünftige 
Entwicklung“.
Wenn ein Kunde sagt Z.B „2“, dann denkt „x“.  Das bezieht sich auch auf
Speichergröße.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Nur so als Tipp: eine Intel-hex ist immer etwa 2,5x so groß, wie das 
eigentliche Programm, da jedes Byte mit 2 ASCII-Zeichen kodiert wird und 
außerdem noch Adressen und Prüfsummen mitgeliefert werden. Daran kann 
man also keine Aussage treffen, ob das Programm in den Controller paßt.

von jimjack j. (jimjack)


Lesenswert?

@skorpionx

Ähm... Du weisst aber schon, dass C nicht wirklich portierbar ist? Vor 
allem wenn man mit den verschidensten Controllern zu tun hat? Die 
Compiler-Harsteller scheren sich meist nicht um Ansi-C und bauen munter 
drauflos ihre eigenen Erweiterungen ein.
Klar muss man die nicht nutzen, aber manchmal macht es das Leben um 
vieles einfacher.

Aber ich muss trotzdem zustimmen. Bei ordentlichem C-Code, der noch 
modular gehalten ist, ist der Umstieg auf eine andere Controller-Familie 
auf jeden Fall einfacher als in Assembler.

von Sumynona (Gast)


Lesenswert?

Allgemeine Abschätzung:

Firmware-größe <= (Dateigröße - (Zeilenanzahl * 12)) / 2

Bei Windows-Zeilenende ists dann eine 13 statt einer 12
Nicht berücksichtigt werden hierbei Adressierungszeilen, bei denen die 
Adresse im "payload"-Bereich steht
http://www.schulz-koengen.de/biblio/intelhex.htm

von P. S. (Gast)


Lesenswert?

Steffen Hildebrandt schrieb:

> Ähm... Du weisst aber schon, dass C nicht wirklich portierbar ist? Vor
> allem wenn man mit den verschidensten Controllern zu tun hat?

Wenn man spitzfindig genug ist, ist nichts portierbar. Da gucken vor 
Allem die Java-Juenger oft mal ganz dumm aus der Waesche...

> Aber ich muss trotzdem zustimmen. Bei ordentlichem C-Code, der noch
> modular gehalten ist, ist der Umstieg auf eine andere Controller-Familie
> auf jeden Fall einfacher als in Assembler.

Eben...

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.