Hallo Kolleg:innen,
ich habe mit ein wenig Halbwissen, einigen Tutorials, Google-Suche und
meiner Bascom-Programmier-Erfahrung schon mal ein paar Grundbausteine
für mein nächstes (und erstes) C-Projekt zusammengebastelt.
Das Projekt soll Sensordaten via I2C einlesen, diese Daten manipulieren,
über serielle Verbindungen zum PC und einem Nextion-Display ausgeben,
Befehle und Werte über diese seriellen Verbindungen empfangen und auch
einige Parameter im EEPROM abspeichern, usw...
Mit Bascom habe ähnliche Projekte schon realisiert, aber C ist eine neue
Welt für mich. Zugegeben - da ist noch viel Unverständnis dabei, aber
meine Neugier war einfach zu groß und mein C-Kurs ist noch lange nicht
soweit und man lernt doch eh am besten bei der Arbeit am Projekt...
Langer Rede kurzer Sinn, das Wetter ist schlecht und vielleicht hat ja
jemand Lust sich diesen ersten Code mal anzuschauen und mir ein Feedback
zu geben, was gut ist und was ich anders/besser machen könnte.
Tausend Dank vorab!
1
/*
2
* Test für I2C, USART, EEPROM
3
*/
4
5
#define F_CPU 2E6
6
#include<avr/io.h>
7
#include<util/delay.h>
8
#include<stdio.h>
9
#include<avr/eeprom.h>
10
#include<avr/interrupt.h>
11
12
/*wird bei Code::Blocks benötigt, bei Geany nicht
13
* erzeugt dort einen [-Wimplicit-function-declaration] Fehler
14
void init_twi(void);
15
void init_serial_1(void);
16
void init_serial_2(void);
17
void sendChar_1(char c);
18
void sendChar_2(char c);
19
void sendString_1(char *text);
20
void sendString_2(char *text);
21
*/
22
23
/* Byte */
24
uint8_teeFooByteEEMEM=13;
25
/* Wort */
26
uint16_teeFooWordEEMEM=12345;
27
/* float */
28
floateeFooFloatEEMEM;
29
30
31
intmain(void)
32
{
33
// Initialisierungen
34
init_serial_1();
35
init_serial_2();
36
init_twi();
37
38
// Interrupt für Data-In
39
PMIC.CTRL=PMIC_LOLVLEN_bm;
40
sei();
41
volatilechardata_in;
42
43
// Testdaten ins EEPROM schreiben
44
eeprom_write_byte(&eeFooByte,123);
45
eeprom_write_float(&eeFooFloat,1.23456);
46
47
48
while(1)
49
{
50
_delay_ms(1000);
51
52
// Variablendeklaration für die I2C Kommunikation
53
uint8_tDataLow;
54
uint8_tDataHigh;
55
uint16_tDataResult;
56
charstr[32];
57
58
/* I2C-Schreiben (Adresse 1111000) wird noch nicht benötigt,
Marie L. schrieb:> und mir ein Feedback> zu geben, was gut ist und was ich anders/besser machen könnte.
Zu allererst lernst du bitte die Hinweise zum Posten zu lesen,
zu verinnerlichen und zu beachten.
Im Speziellen jetzt hier:
----------------------------------------------
Wichtige Regeln - erst lesen, dann posten!
............
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
----------------------------------------------
Will heissen dass eine Source die länger als etwa ein Bildschirm
ist in einen Anhang als *.c Datei gepostet gehört.
Nachdem du schon seit 28.04.2010 hier angemeldet bist, also mehr
als 10 Jahre, solltest du das eigentlich wissen. Ist sozusagen
Bestandteil der Netiquette.
Moin, -
besorge Dir ein kleines C-Buch zu den Grundlagen.
> #define F_CPU 2E6
ich weiss nicht, ob der Float so eine gute Idee ist und der Compiler das
richtig bekommt.
> /*wird bei Code::Blocks benötigt, bei Geany nicht> * erzeugt dort einen [-Wimplicit-function-declaration] Fehler> void init_twi(void);
Das sind keine Fehlermeldungen sondern Warnungen des Compilers. Es
kompiliert irgendwas (nicht unbedingt was Du Dir gedacht hast). Du hast
implizite Funktionen deklariert (--> C-Buch). Beim Compileraufruf sind
die Warnungen einstellbar, aber:
"Thou shalt run lint frequently and study its pronouncements with care,
for verily its perception and judgement oft exceed thine."
> eeprom_write_byte (&eeFooByte, 123);
eeprom_write_byte koennte auch scheitern. Sicherlich hat das einen
Return-Wert. Auswerten!
> float myFloat = eeprom_read_float(&eeFooFloat);> sprintf(str, "Float auslesen: %f", myFloat); //funktioniert nicht.> Kommt nur ein ?
Du hast nur eine eingeschraenkte fprintf-Library. Bei Mikrocontroller
versuche immer, float-Ausgabe zu vermeiden.
Gruesse
Th.
Thomas W. schrieb:> besorge Dir ein kleines C-Buch zu den Grundlagen.>> #define F_CPU 2E6> ich weiss nicht, ob der Float so eine gute Idee ist und der Compiler das> richtig bekommt.
Das ist schon in Ordnung
Thomas W. schrieb:> Du hast nur eine eingeschraenkte fprintf-Library. Bei Mikrocontroller> versuche immer, float-Ausgabe zu vermeiden.
Float Unterstützung bekommen man mit den folgenden Optionen:
> (so steht das in meinem Makefile)
Ja, hast Du Dir den Footprint fuer das bischen Float angeguckt? OK, bei
einem 32bitter mit richtig Speicher, aber bei einem acht-bitter muesste
ich schon in bitterer Not sein um die Library zu nutzen (or don't care).
Einfache Nachkomma-Formatierung (z.B. 123.45) geht auch viel einfacher.
(z.B.
https://github.com/eepj/SHT2x_for_STM32_HAL/blob/master/sht2x_for_stm32_hal.c
)
Gruesse
Th.
Edith zeigt auf github.com/eepj/sht2x_for_stm32_hal
Erst mal vielen Dank für die vielen Rückmeldungen!
da und dort schrieb:> Wichtige Regeln - erst lesen, dann posten!> ............> Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
Mea Culpa - hätte ich mir auch denken können...
Ich gelobe Besserung!
Stefan ⛄ F. schrieb:> Deine Strings "fressen" eine Menge RAM. Du kannst sie stattdessen> im> FLash Speicher lassen und von dort aus verwenden.
Hab ich mir angeschaut, aber leider nicht verstanden. Ich denke, dass
ich bei vielen Themen einfach noch nicht soweit bin. Das ist ein guter
Übergang zum nächsten Thema:
Thomas W. schrieb:> besorge Dir ein kleines C-Buch zu den Grundlagen.
Ich mache gerade einen Udemy-Kurs, bin aber noch relativ am Anfang. Ist
sehr trocken und am Projekt "rumspielen" macht einfach mehr Spass. Ich
weiss, dass das die falsche Vorgehensweise ist, aber manchmal kann man
halt nicht aus seiner Haut :-)
Thomas W. schrieb:>> eeprom_write_byte (&eeFooByte, 123);>> eeprom_write_byte koennte auch scheitern. Sicherlich hat das einen> Return-Wert. Auswerten!
Das ist natürlich die Folge der Übereifers. Ich habe nicht versanden wie
ich das auswerten kann. Vielleicht magst Du mir das ja noch erklären.
Stefan ⛄ F. schrieb:> Float Unterstützung bekommen man mit den folgenden Optionen:# Enable> floating-point support in printf> # LDFLAGS += -Wl,-u,vfprintf -lprintf_flt> # Enable floating-point support in scanf> # LDFLAGS += -Wl,-u,vscanf -lscanf_flt> (so steht das in meinem Makefile)
Super, vielen Dank!!! Du hast mir sehr geholfen. Jetzt funktionieren die
Floats!
Zur Erklärung, ich werde ca. 15 bis 30 Floats brauchen, weil ich da
Kalibrierwerte abspeichern muss.
Ich danke Euch allen für die Unterstützung!
Marie L. schrieb:> Zur Erklärung, ich werde ca. 15 bis 30 Floats brauchen, weil ich da> Kalibrierwerte abspeichern muss.
Vielleicht, vielleicht auch nicht. Man sollte auch mal eine Minute an
das Thema Festkommaarithmetik verschwenden. Die reicht in vielen
Fällen.
Marie L. schrieb:>> Deine Strings "fressen" eine Menge RAM. Du kannst sie stattdessen>> im FLash Speicher lassen und von dort aus verwenden.> Hab ich mir angeschaut, aber leider nicht verstanden. Ich denke, dass> ich bei vielen Themen einfach noch nicht soweit bin.
Kurz gesagt, änderst du
> puts("Es war einmal ein langer String...");
in
> puts_p(PSTR("Es war einmal ein langer String..."));
Dann wird der String beim Programmstart nicht ins RAM kopiert, sondern
direkt aus dem Flash verwendet. Der Zugriff darauf ist ein bisschen
langsamer.
Oder:
> char geschichte[] PROGMEM = "Es war einmal ein langer String...";> puts_p(geschichte);
Die ganzen xxx_p() Funktionen sind dafür vorbereitet, direkt aus dem
Flash zu lesen.
Moin, -
please disregard my comment: in <avr/eeprom.h> ist wie folgt definiert:
1
voideeprom_write_byte(
2
uint8_t*__p,
3
uint8_t__value
4
)
d.h. eine Fehlermeldung gibt es nicht. Wenn es einen Fehler gibt (d.h.
out of bound, Eeprom nicht bereit) bekommst Du das nicht mit (-> per
Hand programmieren: Schreiben, Lesen, vergleichen)
Gruesse
Th.
Moin, -
noch eine kleine Bemerkung: Flash kann man ca. 10000x beschreiben,
eeprom ca. 100000x. Hoert sich sehr viel an, wenn Du aber auf die Idee
kommst, jede Minute Messdaten in den Eeprom zu schreiben, hast Du die
theoretische Lebenserwartung nach 70 Tagen erreicht.
Gruesse
Th.
Falk B. schrieb:> Vielleicht, vielleicht auch nicht. Man sollte auch mal eine Minute an> das Thema Festkommaarithmetik verschwenden. Die reicht in vielen> Fällen.
Ja, das ist in der Tat sehr interessant, das werde ich mir mal genauer
anschauen. Danke!
Stefan ⛄ F. schrieb:> Dann wird der String beim Programmstart nicht ins RAM kopiert, sondern> direkt aus dem Flash verwendet. Der Zugriff darauf ist ein bisschen> langsamer.
Geschwindigkeit spielt bei den Messungen keine große Rolle, ich werde es
mal testen, ob ich damit zurecht komme. Danke!
Thomas W. schrieb:> d.h. eine Fehlermeldung gibt es nicht. Wenn es einen Fehler gibt (d.h.> out of bound, Eeprom nicht bereit) bekommst Du das nicht mit (-> per> Hand programmieren: Schreiben, Lesen, vergleichen)
Die Kalibrierwerte müssen nach der Kalibrierung wieder ausgegeben werden
(zur Kontrolle und Dokumentation). Also wird es sowieso eine Funktion
geben (müssen), die alle Kalibrierwerte ausliest. Mal schauen ob ich das
gleich kombinieren kann... Danke!
Thomas W. schrieb:> noch eine kleine Bemerkung: Flash kann man ca. 10000x beschreiben,> eeprom ca. 100000x. Hoert sich sehr viel an, wenn Du aber auf die Idee> kommst, jede Minute Messdaten in den Eeprom zu schreiben, hast Du die> theoretische Lebenserwartung nach 70 Tagen erreicht.
Ich kann dich beruhigen, es werden nur Kalibrierwerte und keine
Messwerte ins Eeprom geschrieben. Also maximal 30 Werte und das ca.
einmal im Jahr. Ansonsten kommen eventuell noch "Zustände" ins Eeprom,
z.B. der Messbereich, damit man beim Einschalten wieder die gleichen
Einstellungen hat.
Euch allen nochmal vielen Dank für die freundliche Unterstützung!
Ich werde bestimmt noch die ein oder andere doofe Frage stellen. Der
Umstieg von Bascom auf C ist nämlich nicht ohne.
Bis bald...