Hi ich brauche dringend Hilfe, möchte einen MLX90614 Sensor ansteuern
mit meinem Mikrocontroller T89C51CC01 der Familie 8051. habe ein c-code
geschrieben aber der LCD-Display zeigt mir leider nix an und ich weiß
nicht ob er mir die Daten schickt bin seit Tagen dran -.- kann mir vlt
einer bitte den Fehler sagen oder helfen.
mfg Martin
C-Code:
#include "t89c51cc01.h"
#include "fvs_bib_lcd.h"
#include "stdio.h"
#include "math.h"
#include "intrins.h"
#include "string.h"
// ------------------------------------------------
--------------------------------------------------
-------------------------------------- //
// I / O-Ports
// ------------------------------------------------
--------------------------------------------------
-------------------------------------- //
sbit MLX = P0 ^1;
// Verwenden Sie MCU externe Interruptquelle um PWM Puls auf SDA Pin von
MLX90614 zu messen
// ------------------------------------------------
--------------------------------------------------
-------------------------------------- //
// ------------------------------------------------
--------------------------------------------------
-------------------------------------- //
// Funktion: Berechnet die Temperatur nach PWM-Pulsbreite und
Periodenbetrag
// ------------------------------------------------
--------------------------------------------------
-------------------------------------- //
int Berechnen (unsigned int t1pwm, unsigned int T1pwm)
{
int DC;
long int T;
int T1;
int K;
int T1max = 120; // Die maximale Objekttemperatur, die im EEPROM 00h
gespeichert ist
int T1min = -20; // Die minimale Objekttemperatur, gespeichert im EEPROM
01h
K = 2 * (T1max-T1min);
DC = t1pwm * 100000 / T1pwm;
// Berechnen Sie den Duty-Zyklus, mal 100.000 verschiebt den Fixpunkt 5
Position nach rechts
T = (DC-0,125 * 100000) * K + T1min * 100000;
// Objekttemperatur berechnen, DC ist Tastverhältnis
T1 = T / 1000;
// Um ??die Auflösung auf 0.01 abzuschneiden, erfolgt eine Division von
1000 auf den Ergebnissen
return T1;
}
void main (void)
{
char txt[10];
unsigned int A;
unsigned int B;
unsigned int C;
unsigned int D;
unsigned int Data1;
unsigned int Data2;
int Daten;
TMOD = 0x19; // Set Timer und Timer GATE = Arbeit im Modus 1
TH0 = 0x00; // Löschen TH0, TL0
TL0 = 0x00;
ET0 = 1; // Open Timer 0 Interrupt-Freigabe
ET1 = 1; // Open Timer 1 Interrupt-Freigabe
EA = 1; // Gesamt-Interrupt-Freigabe öffnen
TL1 = 0x00; // Löschen TH1, TL1
TH1 = 0x00;
EX1 = 0; // INT1-Interrupt ausschalten
while (MLX == 1) // Warten INT1 niedrigen Puls
{;}
while (MLX == 0) // Warten INT1 Hochimpuls
{;}
TR0 = 1; // Timer öffnen 0
TR1 = 1; // Timer öffnen 1
while (MLX == 1) // Warten INT1 niedrigen Puls
{;}
TR0 = 0; // Timer löschen 0
C = TL0; // T0 Niedriges Byte sendet an C
D = TH0; // T0 High-Byte sendet an D
while(MLX == 0) // Warten INT1 Hochimpuls
{;}
TR1 = 0; // Timer löschen 1
A = TL1; // T1 Niedriges Byte sendet an A
B = TH1; // T1 High-Byte sendet an B
Data2 = (D << 8) + C;
Data1 = (B << 8) + A;
Daten = Berechnen (Data2, Data1); // Temperatur auf der Grundlage des
Zählerwertes berechnen
pos(40);
sprintf(txt,"T=%i",(int)Daten);
lcdsend(txt); // Temperatur anzeigen
}
"factory default is SMBus)"
Das Ding spricht also erstmal nur SMBus (I2C). Für PWM mußt Du den
EEPROM umprogrammieren.
Einfacher sollte allerdings sein, gleich I2C zu benutzen.
Kannst Du denn schon Zahlen auf dem LCD ausgeben?
Danke für die Antwort, aber hab schon alles mögliche versucht liegt
leider nicht an der position. weis zwar nicht warum ich nix angezeugt
bekomm der stoppt irgendwo und ab da geht gar nix mehr -.-....
Martin H. schrieb:> while (MLX == 1) // Warten INT1 niedrigen Puls> {;}> while (MLX == 0) // Warten INT1 Hochimpuls> {;}
Naja, klar, wenn wie Peter sagte das Teil keine PWM ausgibt, hängts bei
einem dieser whiles...
Peter D. schrieb:> "factory default is SMBus)">> Das Ding spricht also erstmal nur SMBus (I2C). Für PWM mußt Du den> EEPROM umprogrammieren.> Einfacher sollte allerdings sein, gleich I2C zu benutzen.>> Kannst Du denn schon Zahlen auf dem LCD ausgeben?
also am Lcd bekomm ich nix raus keine zahlen nicht mal ein buchstaben,
was es normal ausgeben muss/sollte. :/ ja genau einfacher schon aber
will es so programmieren wird schlieslich meine Techniker arbeit später
^^ find denn fehler leider nicht hab schon jegliche sachen getestet aber
ohne erfolg :/ wie meinst du das mit dem EEPROM verstehe ich grad net
sry ^^
Joe F. schrieb:> Martin H. schrieb:>> while (MLX == 1) // Warten INT1 niedrigen Puls>> {;}>> while (MLX == 0) // Warten INT1 Hochimpuls>> {;}>> Naja, klar, wenn wie Peter sagte das Teil keine PWM ausgibt, hängts bei> einem dieser whiles...
ok und wie soll ich es dann umschreiben hab da jetzt keine ahnung wie
ich das machen soll ^^ ?
Fang doch mal Schritt für Schritt an.
Schreibe einen einfachen String auf das Display, und schmeisse sonst
alles raus, was mit dem Sensor zu tun hat.
Dann weisst du, dass du zumindest mal auf das Display zugreifen kannst.
Als nächstes solltest du dich mit I2C auf deinem uC beschäftigen
(Library suchen, API verstehen, I2C Protokoll verstehen, Protokoll des
Sensors verstehen -> Datenblatt, Protokoll in deiner Firmware
implementieren).
Wenn du schon nicht verstehst, warum die while()-Schleifen hängen
bleiben, frage ich mich wie du diesen Code "geschrieben" haben möchtest.
Copy&Paste kommt da wohl näher an die Wahrheit heran.
Text bekomm ich raus aber keine Zahlen Leider weis nicht wie ich das
noch versuchen soll bekomm das nicht zum laufen -.- ist ein projekt den
ich fertig bekommen muss hab da echt keine Ahnung mir gehen langsam die
ideen aus :/
Hi
Kann es sein, daß Du, wenn Du die Zahl 34 senden willst, ein "
Anführungszeichen bekommst?
Ja -> 34 ist der ASCII Code für ein "
Ja² -> Du musst Deine Zahlen in Einzelzeichen umrechnen
Wenn Nein ... was kommt, wenn Du welche Zahl auszugeben versuchst?
MfG
Patrick J. schrieb:> Wenn Nein ... was kommt, wenn Du welche Zahl auszugeben versuchst?
Das Problem liegt eher nicht am sprintf... %i ist schon okay.
a)
Das Programm kann aber überhaupt nicht compilieren.
1
voidmian(void)
ist nicht main().
1
t1=Data();
Die Funktion Data() gib es gar nicht.
b)
Selbst wenn es bauen würde, I2C hat ein Timing.
Einfach die Ports mit Maximalgeschwindigkeit toggeln funktioniert
bestimmt nicht.
c)
1
I2CRead();
2
I2CSend();
3
t1=Data();
Da fehlt jegliches Verständnis, wie per I2C mit dem Sensor kommuniziert
wird.
Es muss eine I2C Adresse gesendet werden, es muss mind. 1 Register
ausgelesen werden.
Start-Stop Konditionen müssen beim reingepasteten Code an der richtigen
Stelle gemacht werden.
Martin H. schrieb:> zeigt mir> auch kein fehler an
das kann schlichtweg nicht sein.
Hi
Martin H. schrieb:> code:> sbit SDA=P0^0;> sbit SCL=P0^1;
Was mir gerade noch auffällt - gehören die 'Dach-Pfeile' nicht nach
links verdreht und verdoppelt?
1
sbit SDA=P0<<0;
2
sbit SCL=P0<<1;
Als Schiebe-Operation.
P0 wird wohl den Wert 0 zurück geben (Bit 0 im Port)
P0^0 -> 1 (jede Zahl hoch Null ist Ein)
P0^1 -> 0 (jede Zahl hoch Eins ist die Zahl selber)
Sicher, daß SDA und SCL überhaupt da sind, wo Sie vermutet werden?
(sofern sich der Code compilieren lässt, klar)
MfG
Patrick J. schrieb:>> sbit SDA=P0^0;>> sbit SCL=P0^1;>> Was mir gerade noch auffällt - gehören die 'Dach-Pfeile' nicht nach> links verdreht und verdoppelt?
Nein, das ist schon richtig so. Damit definiert man im Keil C51
Bitvariablen.
Aber der Rest enthält so viele Fehler, daß er unmöglich compiliert.
Man sieht ja am Display, daß es nichtmal initialisiert (obere Reihe
Kästchen).
Ja leider, bekomm das nicht hin beim dht11 Sensor hat es wunderbar
geklappt ohne Probleme. Beim mlx will das irgendwie nicht klappen, mir
gehen die Ideen aus, wenn ich es ein speise bekomm ich nur 255 raus und
ne 1 was mir aber überhaupt nicht weiter hilft und es lässt sich auch
ohne Fehler kompilieren mäckern tut er nicht würd er mir Fehler anzeigen
wäre ich froh würde vlt dann auf denn Fehler kommen aber tut es leider
nicht :/ aber zeigen tut er schon mal etwas an. Hat jemand vlt einen
Test Code oder so etwas weil im Internet findet man kaum was nur von
arduino.. hier ist das Datenblatt
https://www.melexis.com/-/media/files/documents/datasheets/mlx90614-datasheet-melexis.pdf
brauch ein Taktsignal für scl damit ich Daten heraus lesen kann von sda
das will nicht funktionieren ? Danke für die Hilfe euch allen hoffe wir
finden da eine Lösung.. wäre euch sehr dankbar ist meine Abschluss
Prüfung und sry für die schreib Fehler..
Martin H. schrieb:> beim dht11 Sensor hat es wunderbar> geklappt ohne Probleme.
Ganz ehrlich, ich glaube dir kein Wort!
Du hast keinesfalls ein funktionsfähiges one-wire Protokoll für den
DHT11 implementiert.
Martin H. schrieb:> und es lässt sich auch> ohne Fehler kompilieren mäckern tut er nicht würd er mir Fehler anzeigen> wäre ich froh
Das, kann, überhaupt, nicht, sein!
Ich weiss nicht was du machst, aber diese Programm compiliert so nicht.
Wo soll denn die Funktion Data() sein?
Wie soll I2CSend() ohne Argument aufgerufen werden können?
Entweder nimmst du uns hier alle auf den Arm, oder irgendwas stimmt mit
deinen Beschreibungen nicht, was du genau machst und wie das Programm
aussieht.
du musst zu allererst den Baustein Konfigurieren und ihm eine gültige
I2C-Bus Adresse verpassen. Dies geschieht am Anfang über die
General-Call Adresse 0x00 (Schreibadresse). Die benötigten Register sind
PWMCTRL zum deaktivieren des PWM-Modus, dann ConfigRegister1, dann SMbus
Address.
um mit deinen Funktionen einen ersten Kontakt mit dem Baustein zu
bekommen sollte das genügen:
1
#define GenCall_Write 0x00
2
// beliebige Schreib- (gerade Zahl) und Leseadresse
3
// (Schreibadresse+1 einsetzbar
4
#define MeineMLX_Adresse_Write 0x10
5
#define MeineMLX_Adresse_Read 0x11
6
7
voidmain(void)
8
{
9
// initialisierung
10
I2CInit();
11
I2CStart();
12
I2CSend(GenCall_Write);// Baustein zum schreiben adressieren
13
I2CSend(0x02);// Adresse des PWMCTRL-Registers
14
I2CSend(Low_Byte_der_Konfiguration);
15
I2CSend(High_Byte_der_Konfiguration);
16
I2CSend(Pruefsumme);// CRC-Prüfsumme des 16-Bit Wertes
17
I2CStop();
18
19
I2CInit();
20
I2CStart();
21
I2CSend(GenCall_Write);// Baustein zum schreiben adressieren
22
I2CSend(0x05);// Adresse des Config-Registers
23
I2CSend(Low_Byte_der_Konfiguration);
24
I2CSend(High_Byte_der_Konfiguration);
25
I2CSend(Pruefsumme);// CRC-Prüfsumme des 16-Bit Wertes
26
I2CStop();
27
28
I2CInit();
29
I2CStart();
30
I2CSend(GenCall_Write);// Baustein zum schreiben adressieren
31
I2CSend(0x0E);// Adresse des I2C-Adress-Registers
32
I2CSend(MeineMLX_Adresse_Write);// neue Adresse setzen