Forum: Mikrocontroller und Digitale Elektronik Deklarieren von Konstanten


von steffen (Gast)


Lesenswert?

guten morgen,
bin grad dabei Konstante zu deklarieren. Wie funktioniert das denn mit 
den externen? Benutze einen uC und einen Baustein, die über einen SMBus 
kommunitieren. Was wird denn alles als extern definiert?
Danke schonmal

von Gast (Gast)


Lesenswert?

Du mußt Deine Frage konkreter formulieren.
SMBus hat erst einmal nichts mit Konstanten zu tun.

von steffen (Gast)


Lesenswert?

hab als Auftrag bekommen, alles zu deklarieren was mit der kommunikation 
zwischen dem uC und dem Baustein zu tun hat. Hab aber keine Ahnung wie 
das funktioniert. Von dem Datenblatt des bausteins ist ein verweis auf 
SBD(Smart Battery Data), dort stehen die ganzen Commandos. Weiß aber 
nicht wie ich die im Programm in die Include files schreib und welche 
davon dann extern sind und welche nicht.Was wird denn als Extern 
überhaut bezeichnet?

von Karl H. (kbuchegg)


Lesenswert?

steffen wrote:
> hab als Auftrag bekommen, alles zu deklarieren was mit der kommunikation
> zwischen dem uC und dem Baustein zu tun hat. Hab aber keine Ahnung wie
> das funktioniert. Von dem Datenblatt des bausteins ist ein verweis auf
> SBD(Smart Battery Data), dort stehen die ganzen Commandos. Weiß aber
> nicht wie ich die im Programm in die Include files schreib und welche
> davon dann extern sind und welche nicht.Was wird denn als Extern
> überhaut bezeichnet?

(ICh geh mal davon aus, dass du in C schreiben musst)

Lies dir erst mal das hier durch

http://www.mikrocontroller.net/articles/FAQ#Globale_Variablen_.C3.BCber_mehrere_Dateien##

und dann gehts weiter:

In C gibt es 2 Möglichkeiten, wie man sowas realisieren kann. Wundert 
mich, dass dein C-Lehrbuch darüber kein Wort verliert.

Möglichkeit 1: Einsatz des Präprozessors

  Hier hat man streng genommen eigentlich gar keine Konstanten, sondern
  man benutzt den Präprozessor um Textersetzungen vorzunehmen
1
#define CMD_ADD   1
2
#define CMD_DEL   2

  Die teilt dem Präprozessor mit, dass in weiterer Folge überall
  im Quelltext der Text "CMD_ADD" durch den Text "1", bzw "CMD_DEL"
  durch "2" zu ersetzen ist. Es findet also lediglich eine
  Textersetzung statt noch bevor der eigentliche C-Compiler das
  Programm zu Gesicht kriegt
1
#define CMD_ADD   1
2
#define CMD_DEL   2
3
4
int main()
5
{
6
  printf( "%d", CMD_ADD );
7
}

  Der Präprozessor tauscht hier den Text "CMD_ADD" durch den Text "1"
  aus. Der eigentliche C-Compiler kriegt dann folgendes Programm zu
  Gesicht
1
int main()
2
{
3
  printf( "%d", 1 );
4
}

Möglichkeit 2: ganz normale globale Variablen, denen ein const
vorangestellt wird, und die daher als konstante Variablen oder
einfach nur Konstante bezeichnet werden
1
const int CmdAdd = 1;
2
const int CmdDel = 2;
3
4
int main()
5
{
6
  printf( "%d", CmdAdd );
7
}

  Es handelt sich hier bei CmdAdd und CmdDel um ganz normale globale
  Variablen. Der einzige Unterschied besteht darin, dass sie eben
  als const markiert sind. Der Compiler wird daher jeden Versuch
  einer Änderung dieser Variablen im Programmtext als illegal
  beanstanden. Auf der anderen Seite kann der Compiler aus der
  Kentniss der Konstanz und dem tatsächlichen Wert bei der
  Programmoptimierung oft Vorteile ziehen.


Und besorg dir bessere C-Unterlagen.
Ein Buch, welches über Präprozessor, Konstanten und wie man sie auf
Header Files verteilt kein Wort verliert, ist das Papier nicht wert
auf dem es gedruckt ist.

von Gast (Gast)


Lesenswert?

>(ICh geh mal davon aus, dass du in C schreiben musst)

Ich tippe auf SOPRANCOM :-)

von steffen (Gast)


Lesenswert?

ja genau, schreib in c.
hab mir das ganze mal durchgelesen. Danke für den Tipp. Da ich aber ganz 
Neu auf diesem Gebiet stellen sich für mich noch ganz grundlegende 
Fragen.
Was wird denn eigentlich alles definiert? Das mit dem Extern hab ich 
trotzdem nicht so genau verstanden, wann man das verwendet.

von Gast (Gast)


Lesenswert?

Wenn Du ganz neu mit C zu tun hast, würde ich empfehlen, zunächst 
praktische Versuche zu machen. Da bekommst Du gleich die Quittung, ob 
etwas geht oder nicht. Gerade einem Anfänger leuchtet es wenig ein, 
zunächst alles zu deklarieren, was später benötigt wird.

Weiterhin schreibe Dir erst einmal auf, welche Werte konstant sein 
werden: Registernamen, verwendete Bits, Befehle, ...

von steffen (Gast)


Lesenswert?

Hab mal hier paar Beispiele der Commandos für den slave 
zusammengeschrieben:

ManufacturerAccess       0x00 r/w word
RemainingCapacityAlarm*  0x01 r/w mAh or 10mWh
RemainingTimeAlarm*      0x02 r/w minutes
BatteryMode              0x03 r/w bit flags
AtRate                   0x04 r/w mA or 10mW
AtRateTimeToFull         0x05 r minutes
AtRateTimeToEmpty*       0x06 r minutes
AtRateOK*                0x07 r Boolean
Temperature              0x08 r 0.1°K
Voltage                  0x09 r mV
Current                  0x0a r mA
AverageCurrent           0x0b r mA
MaxError                 0x0c r percent
BatteryStatus*           0x16 r bit flags
CycleCount               0x17

Für den 0x16 gibt es dann noch folgende conditions.

SMBus Protocol: Read Word
Output: unsigned int - Status Register with alarm conditions bit mapped 
as follows:
  *   * Alarm Bits   *  
0x8000 OVER_CHARGED_ALARM
0x4000 TERMINATE_CHARGE_ALARM
0x2000 Reserved
0x1000 OVER_TEMP_ALARM
0x0800 TERMINATE_DISCHARGE_ALARM
0x0400 Reserved
0x0200 REMAINING_CAPACITY_ALARM

Könnt ihr damit irgendwas anfangen?

von Gast (Gast)


Lesenswert?

>Könnt ihr damit irgendwas anfangen?

Ja, etwas. Dein 1.Block enthält Variablen und der 2. Konstanten.
Die Variablen muß man mit der geforderten Größe deklarieren (char, int, 
long) und die Konstanten mit #define.
Jetzt kannst Du ja weitermachen.

von Karl H. (kbuchegg)


Lesenswert?

steffen wrote:

> Könnt ihr damit irgendwas anfangen?

Sicher.

Ich würde da gar nicht lange mit echten Konstanten rumfackeln
sondern mir ein File SMBus.h machen

SMBus.h:
********
1
/*
2
 * Commands
3
 */
4
#define SM_MANUFACTURER_ACCESS        0x00   /* r/w word          */
5
#define SM_REMAINING_CAPACITY_ALARM   0x01   /* r/w mAh or 10mWh  */
6
#define SM_REMAINING_TIME_ALARM       0x02   /* r/w minutes       */
7
#define SM_BATTERY_MODE               0x03   /* r/w bit flags     */
8
#define SM_AT_RATE                    0x04   /* r/w mA or 10mW    */
9
10
...
11
12
/*
13
 * Alarm condition Bits
14
 * as used by Command: SM_BATTERY_STATUS (0x16)
15
 */
16
#define SM_OVER_CHARGED_ALARM         0x8000
17
#define SM_TERMINATE_CHARGE_ALARM     0x4000
18
19
...

von Karl H. (kbuchegg)


Lesenswert?

Gast wrote:
>>Könnt ihr damit irgendwas anfangen?
>
> Ja, etwas. Dein 1.Block enthält Variablen

denk nicht das das Variablen sind.
Das werden irgendwelche Kommando-Bytes sein, die man an das Gerät
sendet und die irgendwas bewirken

von steffen (Gast)


Lesenswert?

danke, das hilft mir sehr weiter.
Ein Problem hab ich trotzdem noch.
unter 0x03 steht dann noch folgendes.
Die Tabelle ist nicht vollständig, die ghet bis 15 Bits.
Wohin muss man denn diese Werte schreiben?



Field           Bits Used   Format              Allowable Values

INTERNAL_CHARGE_  0       read only        0 - Function Not Supported
CONTROLLER                                1- Internal charge controller 
sup

von Gast (Gast)


Lesenswert?

>denk nicht das das Variablen sind.

Das werden Adressen von Registern im IO-Baustein sein.

@steffen
Sieh Dir doch einmal die #include-Dateien anderer Programme an; 
beispielsweise hier aus der Codesammlung oder von dem Compiler-Paket, 
das Du verwendest.

von steffen (Gast)


Lesenswert?

also ich definier jetzt alles so wie der Herr Buchegger vorgeschlagen 
hat.
Weiß zwar wie ein Datentransfer ausschaut beim SM-Bus, aber nicht was 
die eigentlichen Daten sind.

S| Slave Address| Wr| A| Command Code |A |Data Byte Low |A| Data Byte 
High |A

bei den ganzen Beispielen von oben, was wären denn da die eigentlichen 
Daten(high und low)?

Slave Adresse ist ja:  SM_MANUFACTURER_ACCESS        0x00  oder?
commando wäre ja  z.B.:  0x16

oder hab ich da was ganz falsch verstanden?

von steffen (Gast)


Lesenswert?

geh da jetzt wiefolgt vor...
extern unsigned int BatteryStatus(unsigned int 
SM_OVER_CHARGED_ALARM,unsigned int SM_TERMINATE_CHARGE_ALARM,
                                  unsigned int SM_OVER_TEMP_ALARM, .....

Weiß wirklich nicht wie ich das irgendwie einbinde. Kann mir jemand 
sagen ob es evtl. so geht?

von Karl H. (kbuchegg)


Lesenswert?

steffen wrote:
> geh da jetzt wiefolgt vor...

Ganz ehrlich:

Du musst jetzt erst mal C und Programmieren lernen.
So hat das wirklich wenig Sinn. Da fehlts hinten und vorne
an Basiswissen und am Verständnis für Zusammenhänge.

SM_OVER_CHARGED_ALARM, SM_TERMINATE_CHARGE_ALARM, SM_OVER_TEMP_ALARM,
oder Kombinationen davon sind mögliche Werte, die eine Funktion 
BatteryStatus liefern kann!

Du fragst das Gerät: In welchem Zustand bist du?
Und das Gerät antwortet mit SM_OVER_CHARGED_ALARM oder 
SM_TERMINATE_CHARGE_ALARM oder SM_OVER_TEMP_ALARM oder einer Kombination 
davon oder einfach nur mit 0, wenn nichts davon vorliegt.

SMBus.h:
********
1
/*
2
 * Commands
3
 */
4
#define SM_MANUFACTURER_ACCESS        0x00   /* r/w word          */
5
#define SM_REMAINING_CAPACITY_ALARM   0x01   /* r/w mAh or 10mWh  */
6
#define SM_REMAINING_TIME_ALARM       0x02   /* r/w minutes       */
7
#define SM_BATTERY_MODE               0x03   /* r/w bit flags     */
8
#define SM_AT_RATE                    0x04   /* r/w mA or 10mW    */
9
10
...
11
12
/*
13
 * Alarm condition Bits
14
 * as used by Command: SM_BATTERY_STATUS (0x16)
15
 */
16
#define SM_OVER_CHARGED_ALARM         0x8000
17
#define SM_TERMINATE_CHARGE_ALARM     0x4000
18
19
...
20
21
unsigned int BatteryStatus();

von steffen (Gast)


Lesenswert?

ja das weiß ich, das es vorne und hinten fehlt, aber muss es irgendwie 
hinbekommen.
was meinst du mit unsigned int BatteryStatus();   ?

Das normale C programmieren kann ich einigermaßen, aber nicht mit einem 
uC.
Was übergebe ich dann mit dem extern .... Befehl oder was schreib ich in 
den Prototyp?

von Karl H. (kbuchegg)


Lesenswert?

> S| Slave Address| Wr| A| Command Code |A |Data Byte Low |A|
> Data Byte High |A
>
> bei den ganzen Beispielen von oben, was wären denn da die
> eigentlichen Daten(high und low)?
>
> Slave Adresse ist ja:  SM_MANUFACTURER_ACCESS        0x00  oder?
> commando wäre ja  z.B.:  0x16

Kann ich mir ehrlich gesagt nicht vorstellen.
Slave Adresse wird irgendeine Zahl sein, mit der sich das Gerät am Bus 
identifiziert. commando wird SM_MANUFACTURER_ACCESS sein, also die 
Spezifizierung was das Gerät machen soll. So wie in: "Bitte liebes 
Gerät, gib mir mal deinen Hersteller" oder "Liebes Gerät, ich möchte 
einen neuen Hersteller programmieren" oder aber auch "Hey Gerät, Gib mir 
mal deinen Batterie Status". Nur halt nicht als Langtext, sondern als 
Zahlencode, wobei du mit den #define für jeden Zahlencode einen 
menschenlesbaren Alias geschaffen hast. Eben SM_MANUFACTURER_ACCESS oder 
auch SM_BATTERY_STATUS



1
    SendCommand( DeviceId, SM_MANUFACTURER_ACCESS, .... );
2
    SendCommand( DeviceId, SM_BATTERY_STATUS );
liest sich nun mal besser und vermittelt dem Leser mehr Information als
1
    SendCommand( DeviceId, 0x01, .... );
2
    SendCommand( DeviceId, 0x16 );

obwohls in beiden Fällen zu völlig identischem Code führt und eigentlich 
dasselbe bedeutet:
  Schicke an das Gerät mit der Identifikation (Slave Address) in
  DeviceId das Kommando 0x16, auf das es mir seinen Batterie Status
  liefert.

Nur im 2.ten Fall musst du auswendig wissen, dass der Commandocode 0x16 
für das Kommando "Batterie Status liefern" steht, während es im ersten 
Fall mehr oder weniger im Programmtext so dortsteht.

von P. S. (Gast)


Lesenswert?

Jeden Tag steht ein Dummer auf, der einen noch Duemmeren findet, der ihm 
die Arbeit macht... ich will gar nicht wissen, wie viele Firmen sich so 
durchschnorren.

von Karl H. (kbuchegg)


Lesenswert?

steffen wrote:
> ja das weiß ich, das es vorne und hinten fehlt, aber muss es irgendwie
> hinbekommen.
> was meinst du mit unsigned int BatteryStatus();   ?
>
> Das normale C programmieren kann ich einigermaßen, aber nicht mit einem
> uC.

Sorry. Aber das hat nichts mit einem µC zu tun. Das ist ganz normaler 
Programmaufbau und wie man sich als Programmierer ein Programm so 
gestaltet das es wartbar ist. Wenn du damit derartige Schwierigkeiten 
hast, wie du sie hier an den Tag legst, dann bezweifle ich ganz stark, 
dass deine C Kentnisse über mehr als ein Hallo World hinausgehen.

Ich klink mich jetzt aus. Denn sonst mach ich dir deine Arbeit und das 
ist nicht Sinn der Sache.

von steffen (Gast)


Lesenswert?

Deine ausführlichen Erklärungen sind echt super nett.
Woher bekommt man dann die Slave Adresse?

Wenn ich die defines angelegt hab, dann benötigt man trotzdem noch die 
Prototypen, oder?
Auf dem datenblatt steht ja unter Slave Funktionen z.B. : 
MaunfacturerAccess,
RemainingCapacityAlarm. Sind das nur Definitionen für die jeweilige 
Adresse, wie z.B. : 0x16 oder heißen so dann später die Funktionen?

von steffen (Gast)


Lesenswert?

hab schon wasmit  C zu tun gehabt, aber nicht das ich unterschiedliche 
headers verwende.Mit der ganzen Problematik von grad hab ich halt noch 
nie zu tun gehabt.In C++ bisschen Oberflächen und in C auch nur einfache 
und grundlegende Dinge.

von steffen (Gast)


Lesenswert?

An peter Stegemann:
bin von keiner firma. Mit meinem Wissen was uC angeht sicherlich nicht. 
Bin komplett neu auf diesem Gebiet und mach das für die Technikerarbeit. 
Glaub nicht das ein solches Wissen jemand angeboren ist.

von spitzfindiger (Gast)


Lesenswert?

@steffen

Also du kannst die grundlegenden Dinge in C.
Ok. Also hier ein paar ganz grundlegende Fragen zu deinem C Wissen.

1.) Was ist der Unterschied zwischen definieren und deklarieren einer 
Variablen?

2.) Wo werden Präprozessor Direktiven wie #define #ifdef usw. im 
Programmspeicher abgelegt?

3.) Für was braucht man Header-Dateien? Oder anders warum schreibt man 
nicht den ganzen Code in eine große C-Datei?

4.) Warum gibt es Funktionen, die einen Wert zurückliefern? Würden 
Prozeduren ohne Rückgabe Wert nicht reichen?

5.) Warum benutzt man überhaupt Konstanten? Man kann doch eigentlich 
jeden Wert auch als Zahl angeben.

6.) Was ist eigentlich volatile? Und warum muss ihm bei uC soviel 
Beachtung schenken?

7.) Warum muss man eigentlich Header-Dateien einbinden um Funktion wie 
printf() usw. zu verwenden?

8.) Werden Konstanten und Variablen im gleichen Speicherbereich im uC 
abgelegt?

9.) Kann jeder uC float rechnen? Und wenn ja, warum sollte man davon bei 
kleinen Controllern eher weniger Gebrauch machen?

10.) Was ist eigentlich ein Zeiger?

11.) Welchen Vorteil haben Zeiger?

12.) Welche Gefahr besteht durch Zeiger?

13.) Warum kann man bei einem Feld das man mit feld[13] definiert hat 
nicht auch mit feld[13] auf das Feld zugreifen?

14.) Was haben (*feld) und feld[0] gemeinsam?

15.) Warum funktionieren meine C++ Kommandos nicht in C?

16.) Welchen Vorteil bietet ein enum gegenüber normalen Konstanten oder 
Präprozessor defines?

17.) Was ist eigentlich ein struct? Welchen Sinn hat ein struct?

18.) Wann sollte man das Schlüsselwort extern verwenden?

19.) Was passiert wenn ich eine Variable in 2 C Dateien definiere?

20.) Was passiert, wenn ich eine Header Datei in 2 C-Datein einbinde 
ohne die Header vor Mehrfach Inkludierung zu schützen?

21.) Wie realsiert man die Mehrfach Inkludierung von Header-Dateien?

Wenn dir das alles klar ist, kannst du dich in die Untiefen der uC 
Programmierung stürzen.

;-)

viel spaß beim Lernen!

von steffen (Gast)


Lesenswert?

Danke, hat aber genau mit dem was ich eigentlich wissen wollte nicht 
viel zu tun. Weiß ja das es bestimmt nicht leicht ist und ich schlechte 
Grundvoraussetzungen hab einen uC zu programmieren.
trotz allem muss ich es irgendwie hinbekommen
Wie oben schonmal angesprochen. Das Problem grad ist ja nur das ich 
nicht weiß welche Daten oder Adressen ich wo genau einsetze und das ich 
noch nie mit mehreren Headers gearbeitet hab.
Da du es sicher weisst, kannst es mir ja sagen

von WhatsTheProblem? (Gast)


Lesenswert?

1
// Header1.h
2
3
#ifndef HEADER_1
4
#define HEADER_1
5
6
extern const int DEINE_KONSTANTE; // DEFINITION
7
8
#endif
9
10
// Source1.c
11
12
#include "Header1.h"
13
14
const int DEINE_KONSTANTE = 15; // DEKLARATION (UND DEFINITION)
15
16
// Source2.c
17
18
#include "Header1.h"
19
20
if (a == DEINE_KONSTANTE){
21
22
// tu was
23
24
}

von WhatsTheProblem? (Gast)


Lesenswert?

steffen, vielleicht wärs echt nicht schlecht du machst dir erstmal ein 
paar Gedanken. Das soll keine Kritik sein, aber wenn du dir Gedanken 
machst können dir die Leute hier auch konkreter und besser helfen.. 
ansonsten erntest du hier nur Hohn und Spott.

duck und weg ;-)

von WhatsTheProblem? (Gast)


Lesenswert?

extern sagt dem Compiler nur, dass es IRGENDWO Speicher für die Variable 
reserviert wurde und dass du sie BENUTZEN darfst...

Findet der Linker dann aber keine passende DEFINITION, dann gibts einen 
Linker Fehler!

von Karl H. (kbuchegg)


Lesenswert?

steffen wrote:
> Danke, hat aber genau mit dem was ich eigentlich wissen wollte nicht
> viel zu tun.

Das Problem ist, gelinde gesagt, dass deine Fragen nicht viel Sinn 
machen. Deine Fragen lassen darauf schliessen, dass du selber nicht 
weist, was du eigentlich tun sollst, bzw. wie dieser ominöse SMBus 
eigentlich prinzipiell funktioniert.

> Wie oben schonmal angesprochen. Das Problem grad ist ja nur das ich
> nicht weiß welche Daten oder Adressen ich wo genau einsetze

Moment.
Was genau ist denn nun eigentlich deine Aufgabenstellung?

Programmierst du die Kommunikationsfunktionalität oder arbeitest du 
einem anderen Programmierer zu, der sich um die Kommunikation am Bus 
kümmert?
Sprich: Du bereitest ihm die Header Files vor und er übernimmt das dann.

Oder noch einfacher ausgedrückt:
Besteht deine Aufgabe darin das Header File vorzubereiten oder musst du 
auch das zugehörige C-File schreiben?

von WhatsTheProblem? (Gast)


Lesenswert?

@Karl heinz Buchegger

>Deine Fragen lassen darauf schliessen, dass du selber nicht
>weist, was du eigentlich tun sollst, bzw. wie dieser ominöse SMBus
>eigentlich prinzipiell funktioniert.

Genau das scheint das Problem zu sein. Ich glaube der Herr ist zu faul 
mal das Datenblatt anzuschauen. Das die C Kenntnisse ein bisschen 
löchrig sind ist ja nicht mal schlimm, aber wenn man nicht genau weiß 
was man will... das ist das eigentliche Problem!! Werd mal konkret, 
Mensch! ;-)

von Karl H. (kbuchegg)


Lesenswert?

WhatsTheProblem? wrote:
> @Karl heinz Buchegger
>
>>Deine Fragen lassen darauf schliessen, dass du selber nicht
>>weist, was du eigentlich tun sollst, bzw. wie dieser ominöse SMBus
>>eigentlich prinzipiell funktioniert.
>
> Genau das scheint das Problem zu sein. Ich glaube der Herr ist zu faul

Zu faul will ich ihm gar nicht unterstellen.
Aber bei einigen Fragen greifst du dir an den Kopf und fragst dich, ober 
er sich schon mal überlegt hat, was ein Bussystem überhaupt ist und was 
man aus diesen Erkentnissen alles folgern kann.

Alleine aus dem Wort 'Bus' folgt schon, dass da mehrere 
Kommunikationspartner an einem Kommunikationspfad lauschen. Sonst würde 
es nämlich ganz einfach Kabel heissen (so wie bei: Sender und Empfänger 
sind über ein RS232 Kabel verbunden).
Wenn aber mehrere Zuhörer an einem Medium lauschen, muss der Sender eine 
Möglichkeit haben, umgangssprachlich gesehen, zu sagen: Diese nachricht 
ist für einen bestimmten Zuhörer gedacht, alle anderen ignorieren sie.

Mit diesem Basiswissen:
Was wird dann wohl die Bedeutung von Slave Adress in

> S| Slave Address| Wr| A| Command Code |A |Data Byte Low |A|
> Data Byte High |A

sein?
Doch sicher nicht eine der Konstanten, die in einem der ersten Postings 
selbst als 'Kommandos' bezeichnet wurden. Statt dessen wird wohl jeder 
Empfänger (also jeder Slave) in irgendeiner Form eine Identifizierung 
haben. Die kann hardwaremaessig vorgegeben sein, die kann dynamisch 
zugewiesen wurden sein, die kann ... spielt keine Rolle, er wird sie 
sicherlich haben. Und was wird man da nehmen. Na im einfachsten Fall 
kriegt einfach jeder Empfänger eine Nummer. Und genau diese Nummer wird 
man bei so einer Nachricht angeben, damit in der Nachricht drinnen 
steht: diese Nachricht ist für den Empfänger (den Slave) mit der Nummer 
25 (ist jetzt eine Hausnummer) gedacht.

Kommandos hingegen passen in diesem Protokoll wiederrum wunderbar auf 
den Eintrag 'Command Code'.

Und was wird wohl Data Byte Low und Data Byte High sein?
Einige Kommandos werden Argument brauchen, bzw. Werte liefern. Die 
müssen natürlich auch auf dem Bus übertragen werden.
Welche werden das sein? Da geh ich mal zurück auf die Kommando Tabelle 
von ganz am Anfang

> ManufacturerAccess       0x00 r/w word
> RemainingCapacityAlarm*  0x01 r/w mAh or 10mWh
> RemainingTimeAlarm*      0x02 r/w minutes
> BatteryMode              0x03 r/w bit flags
> AtRate                   0x04 r/w mA or 10mW
> AtRateTimeToFull         0x05 r minutes
> AtRateTimeToEmpty*       0x06 r minutes
> AtRateOK*                0x07 r Boolean
> Temperature              0x08 r 0.1°K
> Voltage                  0x09 r mV
> Current                  0x0a r mA
> AverageCurrent           0x0b r mA
> MaxError                 0x0c r percent
> BatteryStatus*           0x16 r bit flags
> CycleCount               0x17

was wird wohl das 'r' bzw 'r/w' heissen, bzw. der Text der danach kommt. 
Man muss wirklich kein Hellseher sein, um bei 'r' read und bei 'r/w' 
read/write zu vermuten. Und das ein Kommando 'Temperature' ja wohl 
irgendwas mit Temperaturen zu tun haben wird und daher ein Zahlenwert 
für die Temperatur über die Leitung geht, sollte eigentlich auch 
intuitiv klar sein. Mit diesem 'Vermutungen', was wird wohl die 
komplette Bedeutung der Zeile

> Temperature              0x08 r 0.1°K

aus der Doku sein?

Das alles hat rein gar nichts mit C oder µC oder sonstigen 
programmiertechnischen Details zu tun, sondern eher damit ob ich mir ein 
paar grundlegende Gedanken mache.

von Gast (Gast)


Lesenswert?

>trotz allem muss ich es irgendwie hinbekommen

@Steffen
"Irgendwie" funktioniert nicht. Mach praktische Übungen und stelle fest, 
daß der C-Compiler Unzulänglickeiten gnadenlos zurückweist.

@!steffen

Ich bewundere Eure Geduld.

von steffen (Gast)


Lesenswert?

Karl heinz Buchegger:
> Besteht deine Aufgabe darin das Header File vorzubereiten oder musst du
> auch das zugehörige C-File schreiben?
Das ganze mach ich für meine Technikerarbeit. Hätte nicht gedacht das da 
soviel auf mich zukommt. Muss sozusagen alles machen, nur wie ist die 
andere Frage

> Deine Fragen lassen darauf schliessen, dass du selber nicht
> weist, was du eigentlich tun sollst, bzw. wie dieser ominöse SMBus     > 
funktioniert
Für mich ist das ganze alles mehr als Neuland. Versuch die Vorgaben die 
mir gestellt werden irgendwie zu lösen.

WhatstheProblem:
>  Ich glaube der Herr ist zu faul mal das Datenblatt anzuschauen
Les das datenblatt rauf und runter, weiß aber nicht wie ich mit den 
ganzen Daten genau umzugehn muss.


Danke euch allen für die sehr hilfreichen Tipps. Werd dann malan diesem 
Problem weitermachen.
Nochmal zur Wiederhulung ob ich es richtig verstanden hab.
Also kann ich somit schreiben:
z.B.: extern unsigned int SM_commandsend(slaveadresse,command 
code,daten);
Müsste man theoretisch für jedes Kommando dann eine Funktion schreiben?

von Stefan (Gast)


Lesenswert?

>Müsste man theoretisch für jedes Kommando dann eine Funktion schreiben?
Nein, das Commando übergibst du ja per Parameter.
Tut mir leid, aber Du wirst Dich, um diese Aufgabenstellung zu meistern, 
erst deutlich intensiver mit einer Programmiersprache auseinandersetzen 
müssen. So Sachen wie SMBus ansprechen sind mit Deinem derzeitigen Stand 
leider nicht durchführbar. Versuch Dich am besten erst mal an einem 
Hallo Welt Klassiker, was in der µC Welt sowas bedeutet wie LED blinken 
lassen...

von Karl H. (kbuchegg)


Lesenswert?

steffen wrote:

> Also kann ich somit schreiben:
> z.B.: extern unsigned int SM_commandsend(slaveadresse,command
> code,daten);

ja, so ungefähr.

> Müsste man theoretisch für jedes Kommando dann eine Funktion schreiben?

Muss man nicht, kann man aber.
Dann braucht sich derjenige, der sich auf deine Basisfunktionalität 
stützt nicht so viel zu merken.

zb. könnte man dann eine Funktion für RamainingTimeAlarm schreiben ...
1
void SetRemainingTimeAlarm( int SlaveAdress, int Minutes )
2
{
3
  SM_CommandSend( SlaveAddress, SM_REMAINING_TIME_ALARM, Minutes );
4
}

... die die Details versteckt, was alles notwendig ist um das Kommando 
zum Gerät zu schicken.

Und noch ein Tip:

Du hast ein paar gestalterische Möglichkeiten. Nutze sie!

Es ist unklug sich Namensmonster wie 'SM_commandsend' zu machen, bei 
denen man als allererstes den Namen 5 mal lesen muss um rauszufinden, 
dass da 2 Worte zusammengefasst wurden. Dein Auge und dein Gehirn sind 
auf Mustererkennung trainiert! Also gib ihnen auch ein Muster! Du hast 
Grossbuchstaben, nutze sie. SM_CommandSend ist für die meisten schon 
viel leichter zu lesen, weil das Gehirn beim grossen S automatisch auf 
'Aha, neues Wort' umschaltet.

Erzeug keine Buchstabenwürste, wie in:
1
SM_commandsend(slaveadresse,commandcode,daten)
Diese Zeile besteht aus kleineren Einheiten, die etwas bedeuten!
Auch hier wieder: Nutze den Erfahrungsschatz, den sich dein Gehirn in 
langen Jahren erworben hat. Seit deiner Kindheit hat es gelernt: 
Zwischen Worte kommt ein Leerraum. So wie du das zur Zeit schreibst, 
musst du deine Augen erst mal über den Text streichen lassen um die 
einzelnen Worte zu finden. Schreibst du das als
1
SM_commandsend( slaveadresse, commandcode, daten )
dann findet dein Gehirn die Worte mit Leichtigkeit. Es ist seit 
frühester Jugend darauf trainiert worden, sowas zu erkennen.

Und ja: Eine vernünftige optische Form kann sehr wohl einen Unterschied 
in der Codequalität ausmachen! Ich habs oft genug erlebt, dass Leute den 
Überblick über ihren Code verloren und um Hilfe gerufen haben. Dann 
gehst du hin, stellst erst mal alle Einrückungen richtig, machst den 
Code mit vernünftigen Variablennamen und strategischen Leerzeichen 
lesbar und siehe da: plötzlich finden die Leute ihre Fehler selber. (Nur 
um dann in den nächsten 10min denselben Saustall im Code erneut zu 
verursachen und dann geht das Spielchen wieder von vorne los)

von Karl H. (kbuchegg)


Lesenswert?

> Tut mir leid, aber Du wirst Dich, um diese Aufgabenstellung zu
> meistern, erst deutlich intensiver mit einer Programmiersprache
> auseinandersetzen müssen.

Seh ich auch so.
Eine Analogie: Du willst zu deiner Gesellenprüfung als KFZ-Mechaniker 
einen Sternmotor bauen. Du hast zwar schon mal eine Feile und eine Säge 
gesehen und in der Hand gehabt, aber feilen und sägen musst du erst 
lernen. Mit einem Schraubenzieher kannst du jedoch umgehen. 
Schlitzschrauben, keine Kreuzschrauben.

(Wobei feilen zu erlernen vergleichsweise einfach ist, gegenüber dem was 
einen in der Programmierung erwartet)

Alles in allem: Du hast dich da in ein Abenteuer eingelassen, von dem 
noch in den Sternen steht, ob das zu meistern ist.

von steffen (Gast)


Lesenswert?

Doch, das wird zu schaffen sein(muss). Jeder hat doch mal klein 
angefangen.
Muss mich da jetzt Schritt für Schritt ranarbeiten.

Karl heinz Buchegger schrieb:
>zb. könnte man dann eine Funktion für RamainingTimeAlarm schreiben ...
>void SetRemainingTimeAlarm( int SlaveAdress, int Minutes )
>{
>  SM_CommandSend( SlaveAddress, SM_REMAINING_TIME_ALARM, Minutes );
>}

Wo bringe ich dann das mit dem extern ein und den Rückgabewert oder ist 
das die funktion schon selber im .c und man müsste dazu noch in den 
headerfiles das mit dem extern schreiben?

Echt super Tipp wegen der Schreibweise, werd ich beachten.

von Karl H. (kbuchegg)


Lesenswert?

steffen wrote:
> Doch, das wird zu schaffen sein(muss). Jeder hat doch mal klein
> angefangen.
> Muss mich da jetzt Schritt für Schritt ranarbeiten.

Du versuchst zur Zeit den Wiener City-Marathon zumindest in den Top-10 
zu beenden, bist aber noch dabei deine Lauftechnik zu entwickeln.
Da kannst du noch so fest mit dem Fuss aufstampfen und 'Ich will' rufen.

>
> Wo bringe ich dann das mit dem extern ein und den Rückgabewert oder ist
> das die funktion schon selber im .c und man müsste dazu noch in den
> headerfiles das mit dem extern schreiben?

Siehst du, genau das meine ich.
Das ist alles Grundlagenwissen!
Sowas müsste eigentlich in deinem Lehrbuch stehen.

http://www.mikrocontroller.net/articles/Funktionen_auslagern_%28C%29
http://www.mikrocontroller.net/articles/FAQ#Globale_Variablen_.C3.BCber_mehrere_Dateien

von er (Gast)


Lesenswert?

> Doch, das wird zu schaffen sein(muss). Jeder hat doch mal klein
> angefangen.
> Muss mich da jetzt Schritt für Schritt ranarbeiten.
Ja, richtig, jeder muss mal klein anfangen und sich Schritt für
Schritt ranarbeiten. Also C-Tutorial schnappen und von 'Hello World!'
bis Ende durcharbeiten, am besten nimmst du eins mit vielen Übungen,
Google ist da Freund.
Danach schnapp dir ein Eval-Board und lass die LEDs blinken, dann lass
die LEDs in Abhängigkeit der gedrückten Taster blinken, dann die LEDs
mit Timern blinkern lassen usw. usf..

von steffen (Gast)


Lesenswert?

>zb. könnte man dann eine Funktion für RamainingTimeAlarm schreiben ...
>void SetRemainingTimeAlarm( int SlaveAdress, int Minutes )
>{
>  SM_CommandSend( SlaveAddress, SM_REMAINING_TIME_ALARM, Minutes );
>}

Wie würde es denn an dem beispiel von dir im .c und .h file 
aussehen?weil ich nicht genau weiß wieso du das so schreibst?!
Wenn ich das weiß, dann könnte ich ja die anderen Funktionsprototypen 
und funkionsaufrufe wenigstens alle mal schreiben, da die ja alle fast 
gleich aussehen.
Hab halt keine andere Möglichkeit, als es irgendwie hinzubekommen.

von Karl H. (kbuchegg)


Lesenswert?

OK, einmal helf ich noch.
Auch wenn es mitlerweile gegen meine Überzeugung geht, dass das sinnvoll 
ist. Du kriegst einen Abschluss für ein Teilgebiet von dem du keine 
Ahnung hast und noch nicht mal die einfachsten Grundlagen beherrscht.


SM.h
1
....
2
...
3
4
5
void SetRemainingTimeAlarm( int SlaveAdress, int Minutes );
6
...


SM.c
1
...
2
3
void SetRemainingTimeAlarm( int SlaveAdress, int Minutes )
4
{
5
  SM_CommandSend( SlaveAddress, SM_REMAINING_TIME_ALARM, Minutes );
6
}
7
8
...


Und nein. Wenn du denkst das das kompliziert ist, dann hast du noch nie 
richtige Programmierprobleme gesehen.

von steffen (Gast)


Lesenswert?

Ja schon, aber dann ist wenigstens mal ein Anfang gemacht.
Das ist sicher ja auch nicht schwer wenn man das schonmal gemacht hat 
und alle Zusammenhänge kennt.Aber ich "lern" es hoffentlich auch.

Das SM_REMAINING_TIME_ALARM hab ich ja im .h file stehn(#define 
SM_REMAINING_TIME_ALARM 0x..). Kann ich deshalb auch gleich in den 
Funktionsaufruf von SM_CommandSend(..., SM_REAMINING_TIME_ALARM 
schreiben?)

SM.c
...
void SetRemainingTimeAlarm( int SlaveAdress, int Minutes )
{
  SM_CommandSend( SlaveAddress, SM_REMAINING_TIME_ALARM, Minutes );
}
...

von steffen (Gast)


Lesenswert?

wenn ich die Funktion 
SM_CommandSend( SlaveAddress,SM_REMAINING_TIME_ALARM, Minutes );
hab, wie nennt man denn dann alle anderen "Sende"Funktionen am besten?

Das SM_REMAINING_TIME_ALARM hab ich ja im .h file mit #define 
SM_REMAINING_TIME_ALARM 0x.. geschrieben, aber wie übergeb ich denn dann 
den wert in die .c? versteh das nicht so ganz wie du das in dem obigen 
Beispiel genau meinst
Wär echt nett wenn du mir da nochmal helfen könntest

gruß

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.