www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik wie Daten an MSP430F1611 seriell einlesen?


Autor: Wolfgang-G (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Offensichtlich ist mein Problem so trivial, dass ich nichts darüber 
finde.
Der Temperaturfühler TSic 506 sendet in Abständen von ca. 3ms seine 2 
Bytes langen Daten seriell auf einer Datenleitung. (mit 8kHz).
Die Datenleitung soll bei mir an P2.5 des MSP430 angeschlossen sein. Und 
jetzt mein Problem:
Wie kriege ich die ankommenden Nullen und Einsen seriell in einen 
Puffer, um dann diese weiterverarbeiten zu können.
Als Ansatz hatte ich mir gedacht, ich definiere eine Variable, und 
schiebe den Inhalt der Variablen nach jedem Takt um eine Stelle nach 
links.
Aber wie kann ich P2.5 abfragen, ob dort eine Null oder  Eins steht und 
diesen Wert mit der Variablen so verknüpfen, dass die kompletten Daten 
nach Empfang von 2 Bytes in der Variablen stehen?
Oder wie macht man es richtig?  Programmierung  in C.
MfG
Wolfgang

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm...da haste dir ja einen Sensor ausgesucht. 11 Bit Single Wire Output 
für State of the Art µControllers. Ohje.
Eventuell lässt sich was über die UART machen, die irgendwie 
missbrauchen. Aber das wird alles schwierig. Du musst ja den Takt auch 
irgendwie rückgewinnen. Gibts da nen komplettes Datenblatt irgendwo? 
Kannst du mal verlinken?

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Möglichkeit ist die von dir beschriebene. Das heißt, einzeln im 
Takt von 8kHz den Pinzustand abfragen und immer ein weiter nach links 
schieben. Nach 16 Takten hast du dann dein fertigen Wert stehen.

Wenn du noch frei in der Pinanordnung bist, würde ich persönlich eine 
Hardware-SPI Schnittstelle verwenden. Dann übernimmt der MSP für dich 
das schieben und zusammensetzen.

Viele Grüße
Michael

Autor: Wolfgang-G (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier geht es  zum Datenblatt
http://www.zmd.biz/temp.php?group=temp&content=products

den TSic 506 habe ich mir als „Referenznormal“ beschafft. Die Fehler 
soll bei < 0,1° liegen.

Es muss P2.5 als Eingang für den seriellen Datenstrom verwendet werden, 
da meine Leiterplatte als Datenschreiber fertig ist und der 
Temperaturfühler nur angeschlossen werden soll. Da eine serieller 
Anschluss häufiger mal gebraucht wird (z.B. 1wire) , möchte ich 
gleichzeitig auch noch etwas dazulernen

Von ZMD gibt es ein Programmbeispiel in C für einen 8051, welches ich 
leider nicht richtig verstehe.
Deshalb würde ich noch mal meine Kernfrage in den Raum stellen: Wie 
fragt man den Eingang P2.5 ab, ob dort eine logische 1 oder Null steht 
und wie  verknüpft man das Ergebnis mit einem Puffer?
Oder wie kann man es unter den vorgegeben Bedingungen besser machen?
Mit freundlichen Grüßen
Wolfgang

Autor: Supa Micha (supa_micha)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Wesentlichen würde das so aussehen:

Messwert = Messwert << 1;
if (P2IN&0x20)
  Messwert |= 0x01;

Diesen Code müsstest du im 8 kHz Takt aufrufen.

Viele Grüße
Michael

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, das ist doch kein komplettes Datenblatt. Da steht nix zum Timing 
usw. drin. Schon ein seltsames Teil. Seh ich das richtig, dass er alle 
3ms einfach so seine 11 Bit rausfeuert? Ohne extra Takt, ohne Kodierung 
ohne alles? Was soll´n das für ein Unsinn sein. Du müsstest dich ja 
irgendwie exakt auf den Anfang eines Datenwortes synchronidieren, da man 
ja aber nie weiß, ob das jetzt 0 oder 1 ist, wird´s bissl schwierig. 
Wenn man das erste Bit hat, kann man mit einem Timer-Int abtasten, keine 
Frage. Die Synchronisierung ist halt tricky. Gibts da kein richtiges 
Datenblatt? In dem 6-Seiten-Wisch steht ja nix drinne....

Autor: szimmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmm, hab mal bei dem Link gesucht, unter
http://www.zmd.biz/pdf/IST_TSic_ZACwire_V2.3%20Dig...
steht die Beschreibung zum Protokoll. Ist schon etwas abartig, aber mit 
dem MSP wohl machbar.
Also, wie in der Beschreibung mal folgendes testen:
1. Einen Timer mit 125kHz takten
2. Das Ausgangssignal auf einen interruptfähigen Eingang führen und so 
konfigurieren, dass bei negativer Flanke die ISR ausgeführt wird.
3. Timerwert (T1) beim Einsprung merken
4. In der ISR solange den Eingang pollen, bis er auf high geht. 
Timerwert (T2) merken und Differenz zu T1 bilden. Dabei kommt dT heraus.
5. Damit hast Du die "Strobe" Time beim Startbit ermittelt
6. Beim nächsten Einsprung in die ISR Timerwert (T3) wieder merken, T4 = 
T3+dT berechnen. Warten, bis der Timer T4 erreicht hat
7. In diesem Moment auf den Eingang schauen (am besten dreimal mit 
Majoritaetsenscheidung). Ist er high, hat der Sensor eine 1 ausgegeben, 
ist er 0, dann hat er eine 0 ausgegeben.
8. Nacheinander in dieser Art und Weise die Bits aufsammeln. Nach 21 
Bits (inclusive Startbit) ist ein Telegramm komplett und Du fängst 
wieder bei 1. an
Was die ISR-Last betrifft, er ist bei einem Telegramm (2,65ms) die 
Hälfte dieser Zeit in der ISR (1,3ms) beschäftigt. Bei einem Zyklus von 
100ms ist das eine CPU-Belastung von ca. 1,3%. Geht also noch (ich hoffe 
mal ich hab mich nicht arg verrechnet). In der Beschreibung kommen die 
auf Doppelte. Weiss allerdings nicht, warum.
Probiere es halt mal aus. Schoene Aufgabe, würde ich auch gerne machen, 
sicherlich interessant.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian R. wrote:

> Ohne extra Takt, ohne Kodierung
> ohne alles? Was soll´n das für ein Unsinn sein.

Nix Unsinn, sondern schlicht PWM. Jedem, der schon man DCF77 dekodiert 
hat, sollte das verdammt bekannt vorkommen. Funktioniert exakt genauso, 
nur schneller, 8KHz statt 1Hz.

> Du müsstest dich ja
> irgendwie exakt auf den Anfang eines Datenwortes synchronidieren, da man
> ja aber nie weiß, ob das jetzt 0 oder 1 ist, wird´s bissl schwierig.

125µs lang high: Startbit folgt.
125µs lang low: Startbit isses.

Hat man einen capture-fähigen Timer, der auf beide Flanken reagieren 
kann, oder den man entsprechend umschaltet, ist das problemlos so 
nebenher zu erledigen. Aber bei dem dezenten Timing tut's ggf. auch ein 
externer Interrupt, wie oben beschrieben. Nur sollte die 
Interrupt-Latenzzeit dann unbedingt angenehm kurz bleiben.

Autor: Wolfgang-G (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zunächst einmal an alle vielen Dank.
Ich denke mal, dass ich jetzt ein Stück weiterkomme und werde zunächst 
mal mit Supa Michas  Programmschnipsel beginnen, falls dies der dafür 
gängige und einzige Weg ist, einen seriellen Datenstrom an einem Eingang 
zu erfassen.
@szimmi
Wenn ich es richtig verstanden habe, wird in dem von Dir zitierten 
Artikel eine weitere Möglichkeit beschrieben. Der Fühler wird über einen 
µC Ausgang zu- und abgeschaltet. Nach dem Zuschalten des Fühlers wartet 
man auf die fallende Flanke des Starbits auf der Datenleitung und hat 
somit den Anfang des Telegramms. Mal sehen, ob das so geht.
Mit freundlichen Grüßen
Wolfgang

Autor: szimmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein,da habe ich mich wohl missverständlich ausgedrückt. Der Sensor wird 
nur über eine Signalleitung mit einem Eingang des µC verbunden.
Der Sensor wird nicht zu- oder abgeschaltet.

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Kaiser wrote:
> Christian R. wrote:
>
>> Ohne extra Takt, ohne Kodierung
>> ohne alles? Was soll´n das für ein Unsinn sein.
>
> Nix Unsinn, sondern schlicht PWM. Jedem, der schon man DCF77 dekodiert
> hat, sollte das verdammt bekannt vorkommen. Funktioniert exakt genauso,
> nur schneller, 8KHz statt 1Hz.

Jo, is schon recht. Da kannte ich das vollständige Datenblatt noch 
nicht.

Autor: Wolfgang-G (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
@szimmi
Wahrscheinlich noch ein Missverständnis.
Ich meinte den angehängten Artikel. Lt. Abschnitt 1.4.2 erfolgt hier die 
Stromversorgung des Fühlers vom µC aus. Der Stromverbrauch ist so 
gering, dass er von einem Ausgang des µC versorgt werden kann. 65ms bis 
85ms nach dem Zuschalten des Fühlers beginnt der Fühler mit dem Senden 
des ersten Temperaturtelegramms. So habe ich es verstanden.
Mit freundlichen Grüßen
Wolfgang Gröbel

Autor: Jörg S. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Wo ist denn da jetzt eigentlich das Problem? Ein C-Code wird von ZMD ja 
schon zur verfügung gestellt. Einfach passend anwandeln und gut. Ein 
Source Code für den TSic für MSP430 hab ich mal in den Anhang gepackt.

Autor: Jörg S. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Und die h-Datei...

Autor: Jörg S. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Zur Sicherheit noch die Hardware Datei :)

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat jemand das schon einmal für den AVR umgesetzt ?

Autor: Rubert K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Here is a sample code, based on the C++ code from the datasheet 
mentioned above. Works well with atmega8 and avr-gcc compiler.

Autor: Rubert K. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
(uploading files doesn't work first time)

Autor: beobachter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du könntest über capture-and-compare so weine Art Software-UART 
implementieren.
Beispielcodes dafür gibts jede Menge.

Autor: Martin Kirchner (mkkirchner)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Habe mal versucht den Code für einen PIC 16F876A umzustricken.
Leider ist bei dem zweiten Byte der ParityCheck immer FAIL und die 
Temperatur wird um 10,00°C zu wenig angezeigt.
Allersings verstehe ich dieses Verhakten absolut nicht!!

Hat jemand eine Idee????

Bin am Verzweifeln

martin

Autor: Wolfgang-G (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
vielleicht hast Du 10° zweimal abgezogen
lt. Datenblatt: Temp.= DigitalSignal/2047*70 -10

Autor: Jörg S. (joerg-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welchen TSic hast du? Der 506er hat ein anderes Datenformat als die 
kleineren.

Autor: overseer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend.

Ich versuche z.Z einen TSIC 306 zum laufen zu bringen.

atm verwende ich dazu das von Robert K. gepostete programm (zwei drei 
posts über meinem)

folgendes verstehe ich aber nicht.
temperatur ist eine 16bit unsigned integer variable...was bedeutet das 
float davor?
in diese variable wird der tempsensor output geladen bei 25°C sind das 
0x2FF
der sensor sendet immer 11bit pakete
Temp_celsius = ((float)temperatur / 2047 * 200) - 50;

temper

hier das ganze im kontext.
int main (void) {

  uint16_t temperatur;  // 11-bit temperature value
  uint8_t returnvalue;  // return value of getTSicTemp(*temp);
  uint8_t Temp_celsius; // converted temperature in °C

  TSIC_INIT();          // set data direction of IO-Pins


  while(1){

    returnvalue = getTSicTemp(&temperatur);  // pull the TSIC-Sensor

    // conversion equation from TSic's data sheet
    Temp_celsius = ((float)temperatur / 2047 * 200) - 50;


Autor: Jörg S. (joerg-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>temperatur ist eine 16bit unsigned integer variable...was bedeutet das
>float davor?
Das von unsigned int auf float "gecastet" (gewandelt) wird.

Autor: overseer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gut, die rechnung läuft dann mit nachkommastellen ab...

aaaber: was passiert dann? dann wird eine kommazahl auf ein uint8_t 
variable geschrieben?
oder wirkt sich der cast auch irgendwie auf die Temp_celsius aus?

Autor: Jörg S. (joerg-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> dann wird eine kommazahl auf ein uint8_t variable geschrieben?
Ja

>oder wirkt sich der cast auch irgendwie auf die Temp_celsius aus?
Nein

Autor: overseer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und wie sieht das im klartext aus, wenn eine kommazahl auf einen integer 
geschrieben wird?
wird die kommazahl einfach abgerundet?

mich wundert das es überhaupt möglich ist und der compiler keinen terror 
schiebt :/

Autor: overseer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke jörg

habs jetzt am laufen :)

die angezeigte temp. macht mich zwar etwas stutzig (ich glaube 1 bis 2°C 
zuviel) aber das sollte nur ein kleines problem sein

Autor: Toni (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend,

wenn ich hier einfach mal Anknüpfen darf.
Bin nun schon seit einiger Zeit am probieren, den TSIC 306 zum laufen zu 
bringen, allerdings zeigt dieser mir nur Scheiße auf dem LCD an :(
Erstmal die Codeschnipsel:

Hauptprogramm:
// Definitionen
// lcd-anschlussbelegung
#define LCD_PORT  PORTC
#define LCD_DDR    DDRC

#define LCD_DB    PC0
#define LCD_E    PC4
#define LCD_RS    PC5

// INCLUDE
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdint.h>
#include "lcd_steuerung.h"
#include "tempsensor_ansteuerung.h"

// MAIN
void main (void)

  {
      lcd_init();

    // Temperturmessung mit TSIC ausführen und Daten auf dem LCD ausgeben
      while(1)
      {
      unsigned char parity = 0; // referenz für 2. übergabewert
      uint16_t wert = 0;
      lcd_string("WERT:;");
      wert = temp_messung(&parity);  //temp_byte = übergabe
      lcd_zahl_16(wert);
      lcd_cursor(0,2);
      lcd_string("parity:;");
      lcd_zahl_8(parity);
      _delay_ms(500);
      lcd_befehl(1);

      //ende while
      //33246 bei 20°C      
      }
            
    
    
    while(1){};
      

  }

LCD-Ansteuerung:
// LCD_FUNKTIONEN
/* ansteuerung eines LC-Displays im 4bit modus.
   Wartezeiten nach Datenblatt, Pinbelegung einsellbar. 


// Definitionen
// lcd-anschlussbelegung
#define LCD_PORT  PORTC
#define LCD_DDR    DDRC

#define LCD_DB    PC0
#define LCD_E    PC4
#define LCD_RS    PC5
*/

// lcd-Befehle

// clear display----------------0b00000001
#define lcd_display_löschen    0x01

// cursor bewegen
#define LCD_CURSOR_HOME      0x02

// DDRAM - Adresse festelgen
#define LCD_DDRAM        0x80

/* lcd-adressen für die Zeilen
   angaben sind für ein 4x20 Zeichen lcd.
   bei anderen auflösungen müssen die werte angepasst werden.
*/
#define lcd_cursor_1zeile    0x00
#define lcd_cursor_2zeile    0x40
#define lcd_cursor_3zeile    0x14
#define lcd_cursor_4zeile    0x54

///////////////////////////////////////////
// LCD-INITIALISIEREN
void lcd_init(void)

  {
    unsigned char zaehler = 1;
    LCD_DDR = 0xff;        // PORTC = ausgang
    _delay_ms(15);         // 15 ms warten
    LCD_PORT = 0x3;        // PORTC = 0x03
    while(zaehler <= 3)      // 3-mal enable
      {
        lcd_enable();    //enable 
        zaehler++;      //Zähl-Variable +1
      }
    // 4-bit modus
    LCD_PORT = 0x2;
    lcd_enable();
    
    // 4-bit, 2-Zeilig, 5x8 matrix 
    lcd_befehl(0x28);
    
    // display ein, cursor aus, blinken aus
    lcd_befehl(0x0f);
    
    //cursor inkrement, kein scrollen
    lcd_befehl(0x06);

    //lcd löschen
    lcd_befehl(0x01);

  }

///////////////////////////////////////////
// LCD_ENABLE
void lcd_enable(void)

  {
      LCD_PORT |= ( 1 << LCD_E );    //E-Setzen
      _delay_us(50);          //50µS warten
      LCD_PORT &= ~( 1 << LCD_E );  //E-rücksetzen
      _delay_ms(5);          //5ms warten
  }  

///////////////////////////////////////////
// LCD DATEN senden
void lcd_daten(uint8_t data)
  
  {
      LCD_PORT |= (1 << LCD_RS);      //RS setzen
      uint8_t u_nibble = data & 0x0f;    //unteres nibble
      data &= 0xf0;            //nur die obersten 4 bit maskieren
      LCD_PORT &= ~(0xf0 >> (4-LCD_DB));  //untere 4 bits löschen
      LCD_PORT |= (data >> (4-LCD_DB));  //obere 4 bits ausgeben
      lcd_enable();            //enable
      LCD_PORT &= ~(0xf0 >> (4-LCD_DB));  //untere 4 bits löschen
      LCD_PORT |= u_nibble;        //untere 4 bit ausgeben
      lcd_enable();            //enable
  }

///////////////////////////////////////////
// LCD BEFEHL senden
void lcd_befehl(uint8_t data)

  {
    
      LCD_PORT &= ~( 1 << LCD_RS);    //RS löschen
      uint8_t u_nibble = data & 0x0f;    //unteres nibble
      data &= 0xf0;            //nur die obersten 4 bit maskieren
      LCD_PORT &= ~(0xf0 >> (4-LCD_DB));  //untere 4 bits löschen
      LCD_PORT |= (data >> (4-LCD_DB));  //obere 4 bits ausgeben
      lcd_enable();            //enable
      LCD_PORT &= ~(0xf0 >> (4-LCD_DB));  //untere 4 bits löschen
      LCD_PORT |= u_nibble;        //untere 4 bit ausgeben
      lcd_enable();

  }

///////////////////////////////////////////
// LCD_STRING ausgeben
void lcd_string(const char *data)

  {
      while( *data != ';' )
         lcd_daten( *data++ );  
  }

///////////////////////////////////////////
// lcd-cursor postition; x = zeile/horizont, y = spalte/vertikal
void lcd_cursor(uint8_t x, uint8_t y)

  {
      uint8_t zeile;
      switch(y)
        {
          case 1:    // 1 Zeile
            lcd_befehl(LCD_CURSOR_HOME);
            zeile = LCD_DDRAM + lcd_cursor_1zeile + x;
            lcd_befehl(zeile);
            break;

          case 2:    // 2 Zeile
            lcd_befehl(LCD_CURSOR_HOME);
            zeile = LCD_DDRAM + lcd_cursor_2zeile + x;
            lcd_befehl(zeile);
            break;

          case 3:   // 3 Zeile
            lcd_befehl(LCD_CURSOR_HOME);
            zeile = LCD_DDRAM + lcd_cursor_3zeile + x;
            lcd_befehl(zeile);
            break;

          case 4:    // 4 Zeile
            lcd_befehl(LCD_CURSOR_HOME);
            zeile = LCD_DDRAM + lcd_cursor_4zeile + x;
            lcd_befehl(zeile);
            break;
          
          default:  // eine falsche angabe.
            return;
        }
  }

///////////////////////////////////////////
// 8-bit Zahl in ASCII umwandel und gleich auf dem LCD ausgeben
void lcd_zahl_8(uint8_t zahl)
  {
  if(zahl < 0)
  {
  uint8_t zaehler;
  //100er
  while( zahl > -99)
    { 
      zahl += 100;
      zaehler++;
    }
      if(zaehler != 0)
      {  
        zaehler += 0x30;
        lcd_daten(zaehler);
      }
      zaehler = 0;

    //10er
    while( zahl > -9)
      { 
        zahl += 10;
        zaehler++;
      }
        if(zaehler != 0)
        {
          zaehler += 0x30;
          lcd_daten(zaehler);
        }

      //einer
      zahl += 0x30;
      lcd_daten(zahl);
  }
  uint8_t zaehler;
  //100er
  while( zahl > 99)
    { 
    zahl -= 100;
    zaehler++;
    }
    if(zaehler != 0)
    {  
      zaehler += 0x30;
      lcd_daten(zaehler);
    }
    zaehler = 0;

    //10er
    while( zahl > 9)
      { 
      zahl -= 10;
      zaehler++;
      }
      if(zaehler != 0)
      {
        zaehler += 0x30;
        lcd_daten(zaehler);
      }

      //einer
      zahl += 0x30;
      lcd_daten(zahl);
  }

///////////////////////////////////////////
// 16-bit Zahl in ASCII umwandel und gleich auf dem LCD ausgeben
void lcd_zahl_16(uint16_t zahl)
  {
  uint8_t zaehler;
  //10000er
  while( zahl > 9999)
    { 
    zahl -= 10000;
    zaehler++;
    }
    if(zaehler != 0)
    {
      zaehler += 0x30;
      lcd_daten(zaehler);
    }
    zaehler = 0;

    //1000er
    while( zahl > 999)
      { 
      zahl -= 1000;
      zaehler++;
      }
      if(zaehler != 0)
      {
        zaehler += 0x30;
        lcd_daten(zaehler);
      }
      zaehler = 0;

      //100er
      while( zahl > 99)
        { 
        zahl -= 100;
        zaehler++;
        }
        if(zaehler != 0)
        {  
          zaehler += 0x30;
          lcd_daten(zaehler);
        }
        zaehler = 0;

        //10er
        while( zahl > 9)
          { 
          zahl -= 10;
          zaehler++;
          }
          if(zaehler != 0)
          {
            zaehler += 0x30;
            lcd_daten(zaehler);
          }

          //einer
          zahl += 0x30;
          lcd_daten(zahl);
  }

und die wohl wichtigste Datei, Sensoransteuerung:
// TSIC 306
#define steigende_flanke  (PINB & (1 << PB2))    // steigende Flanke bzw. high
#define fallende_flanke    !(PINB & (1 << PB2))  // fallende Flanke bzw. low
#define tsic_on        PORTB |= (1 << PB1)    // Sensor einschalten
#define tsic_off      PORTB &= ~(1 << PB1)  // Sensor ausschalten
#define tsic_delay_us    1            // Flankenzeit des TSIC

unsigned int temp_messung(unsigned char *parity_byte)
{
      
      uint16_t temp_byte = 0;
      //tempsensor ansteuerung
      //Sensor starten und auf fallende flanke warten
      DDRB = ((1 << PB1) | (1 << PB0));    // PB0, PB1 = eingang
      
      tsic_on;
      _delay_ms(40);              // Sensor einschalten
      
      while (fallende_flanke);        // warte auf fallende Flanke
      
      while (steigende_flanke);        // auf steigende Flanke warten
              
      for (uint8_t i = 0; i < 8; i++)      // hier nun Bits auswerten
        {
          while (fallende_flanke);    // warten bis zum ersten bit.
          _delay_us(tsic_delay_us);    // 60µSekunden warten
          if (steigende_flanke)      // wenn eingang 1, 
            temp_byte |= 1 << (15-i);  // dann bit schreiben
            else               // wenn nicht,
              while (steigende_flanke);  // dann warten bis flanke wieder steigt, bzw. immernoch eingang = 1.
        }

      // parity auswerten bzw. erstmal abwarten
      while (fallende_flanke);        // Parity_bit
      _delay_us(tsic_delay_us);        // 60µs warten
      if (steigende_flanke)
        *parity_byte |= 1 << 1;        // wenn parity = 1, dann eine 1. eine stelle nach links schieben
        else while (steigende_flanke);    // wenn parity_byte = 0, dann warten bis flanke wieder steigt
      
      // stoppbit absitzen
      while (fallende_flanke);        // stop bit
      
      // startbit absitzen
      while (steigende_flanke);        // start bit
      
      // 2 byte LSB
      for (uint8_t i = 0; i < 8; i++)      // hier nun Bits auswerten
        {
          while (fallende_flanke);    // warten bis zum ersten bit.
          _delay_us(tsic_delay_us);    // 60µSekunden warten
          if (steigende_flanke)      // wenn eingang 0, 
            temp_byte |= 1 << (7-i);  // dann bit schreiben
            else               // wenn nicht,
              while (steigende_flanke);  // dann warten bis flanke wieder steigt, bzw. immernoch eingang = 1.
        }
      // parity auswerten bzw. erstmal abwarten
      while (fallende_flanke);        // Parity_bit
      _delay_us(tsic_delay_us);        // 60µs warten
      if (steigende_flanke)
        *parity_byte |= 1 << 0;        // wenn parity = 1, dann eine 1. 0 stellen nach links schieben
      
      tsic_off;                // Sensor ausschalten
      
      return temp_byte;            // gemessenen Wert zurückgeben          
}


Ich verwende aktuell im "main"-Abschnitt die direkte Wert-Ausgabe, d.h. 
er zeigt mir den eingelesenen Wert direkt an.
Da kommt aber absoluter Mist raus. Verändere ich die T-strobe Zeit auf 1 
µS, so zeigt er mir 65471 an, wobei nach meinem Verständnis hier 0 
angezeigt werden sollte. Allgemein kommt mit jeder anderen Wartezeit ein 
anderer Wert raus und ich kapier einfach nicht warum. Der Code ist stark 
an den im Datenblatt angegebenen angelehnt. Vielleicht kann ja mal 
jemand schnell drüber schauen ob er einen Fehler findet. Oder besser 
jemand hat mal ein Digitaloszi an den Sensor gehangen und kann mir 
beschreiben, wie der genaue Ablauf zwischen dem 1. und 2. Byte mit 
Stop/Start-Bit vonstatten geht. Die LCD-Funktionen funktionieren 
einwandfrei, der Fehler muss in der letzten Datei liegen, irgendwo bei 
der einleserei. Ich find einfach keinen Fehler.
Ich Danke Euch schonmal für die Hilfe.

Autor: Dude (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Es gibt in Beitrag "AVR TSIC Auswertung => riesen Programm" eine 
verbesserte Fassung des Codes aus Beitrag 
Beitrag "Re: wie Daten an MSP430F1611 seriell einlesen?" für AVR (allerdings 
mit ein paar Fehlern).

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.