www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATtiny45 - Zustand an Pin zu bestimmtem Zeitpunkt speichern


Autor: Yorgi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen!

Folgendes zu meinem Aufbau:
Ich benutze einen ATtiny45, der mir Signale über MISO, MOSI und SCK 
ausgibt. Die programmierte Ausgabe ist fest und kann nicht verändert 
werden. Ablauf wie folgt:

1) MOSI setzen
2) SCK auf "1"
3) SCK auf "0"
Das Ganze geschieht neun mal, danach triggert die MISO-Leitung einmal 
auf "1" und wieder zurück auf "0".
Soviel zu den vorgegebenen Aufbau.

Was ich nun mit einem zweiten tiny45 machen möchte ist, den Zustand des 
MOSI-Pins jeweils zu dem Zeitpunkt speichern, wenn auch SCK auf High 
ist.
Also grob gesagt, die Ausgabe des ersten Controllers mit einem zweiten 
speichern. Danach das Ganze an einem anderen Pin nacheinander wieder 
ausgeben. Habe mir dazu folgendes überlegt:
//PB0 = MOSI
//PB1 = MISO
//PB2 = SCK

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#ifndef F_CPU
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert
   (z.B. durch Übergabe als Parameter zum Compiler innerhalb
   des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die
   "nachträgliche" Definition hinweist */
#warning "F_CPU war noch nicht definiert, wird nun mit 8000000 
definiert"
#define F_CPU 8000000UL     /* interner RC mit 8 Mhz */
#endif

void main (void){

  DDRB = 0b00011000;

  unsigned int input_buffer=0;
  unsigned char count_in;
  unsigned char count_out;
  unsigned int output_buffer=0;

 while(1){
  //Speichern der Messwerte
  while(!(PINB & (1<<PB1)));

   for(count_in=0;count_in<9;count_in++){
     loop_until_bit_is_set(PINB, PB2);
    if(PINB & (PINB<<PB0)){
     input_buffer++;
    }
     input_buffer = input_buffer<<1;
   }

  //Ausgabe des Bitstromes
  output_buffer = input_buffer;

  PORTB &= ~(1<<PB4);
  PORTB |= (1<<PB4);
  _delay_us(250);
  PORTB &= ~(1<<PB4);
  _delay_us(250);

   for(count_out=0; count_out<9; count_out++){
    if(output_buffer & (1<<count_out)){
      PORTB |= (1<<PB4);
     _delay_us(100);                  }
    else{                      PORTB &= ~(1<<PB4);
    _delay_us(100);
    }
     }
   input_buffer=0;
   output_buffer=0;
 }
}


Die Ausgabe funktioniert wunderbar, wenn ich dem output_buffer eine 
Bitfolge vorgebe, nur leider scheint es am Speichern zu hapern.
Ich bekomme immer die selbe Ausgabe: 1. Bit "0", danach nur noch "1".
Wäre nett, wenn mir jemand auf die Sprünge helfen könnte.

mfg Yorgi

PS: Die Eingangs- und Ausgangspins des zweiten µC kontrolliere ich mit 
einem Logic Analyzer, die Zeiten dabei passen, nur die Werte nicht.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Yorgi wrote:

> Was ich nun mit einem zweiten tiny45 machen möchte ist, den Zustand des
> MOSI-Pins jeweils zu dem Zeitpunkt speichern, wenn auch SCK auf High
> ist.

Ich wette du möchtest den Wert nicht übernehmen wenn SCK auf High
ist, sondern immer dann wenn SCK von Low auf High wechselt.


>    for(count_in=0;count_in<9;count_in++){

       Hier also erst mal warten, bis PB2 auch auf Low liegt

       loop_until_bit_is_clear(PINB, PB2);

       und erst danach abwarten, bis der Pin auf High zieht.
       wartest du das Low nicht ab, dann ist PB2 beim nächsten
       Schleifendurchlauf immer noch High und du holst immer
       dasselbe Datenbit von PB0

>      loop_until_bit_is_set(PINB, PB2);
>     if(PINB & (PINB<<PB0)){
>      input_buffer++;
>     }
>      input_buffer = input_buffer<<1;
>    }

Autor: Yorgi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Antwort, das werde ich doch direkt mal testen :-)

mfg Yorgi

Autor: Yorgi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, habe das Ganze mal getestet, leider ohne sichtbaren Erfolg.
Ich habe in die Ausgabe mal einen Takt lang ein High bzw, Low angesetzt, 
um zu sehen, ob er überhaupt soweit im Programm läuft:

...
//Ausgabe des Bitstromes
  output_buffer = input_buffer;

  PORTB &= ~(1<<PB4);
  PORTB |= (1<<PB4);
  _delay_us(250);
  PORTB &= ~(1<<PB4);
  _delay_us(250);

   for(count_out=0; count_out<9; count_out++){
    if(output_buffer & (1<<count_out)){
      PORTB |= (1<<PB4);
     _delay_us(100);                //Warteschleife
    }
    else{                      PORTB |=(1<<PB4);
    PORTB &= ~(1<<PB4);
    _delay_us(100);
    }
     }
   input_buffer=0;
   output_buffer=0;
...

Soweit scheint es wohl zu stimmen, aber meine Ausgabe sieht immer wie 
folt aus

__ _ _ _ _ _               _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
   |         |_  _  _|_ _|

Hoffe, man kann es erkennen, ein _ soll dabei 50µs darstellen.
Nach diesem Signalverlauf kommen nochmal ca. 350µs High und danach geht 
es von vorne los.
Hat noch jemand einen Einfall?
Ich hab das Gefühl, ich seh den Wald vor lauter Bäumen nicht ^^

mfg Yorgi

Autor: Yorgi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Soviel dazu... verdammt :(

Autor: Jörg W. (yorgi)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So, hoffe nun kann man es erkennen. ;)

Autor: Jörg W. (yorgi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
/schieb

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal ne bescheidene Frage:
Geht sich das mit dem Timing überhaupt aus?
Wie schnell sendet denn der Sender, bzw. hast du
mal nachgerechnet, ob der Empfänger da überhaupt
mitkommen kann?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bist du sicher mit dieser Zeile:

if(PINB & (PINB<<PB0)){

Autor: Jörg W. (yorgi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nabend,

also das Timing sollte passen. Lasse den tiny im Moment mit 8 Mhz 
laufen. Werd aber morgen nochmal die Zeiten messen.

Ich habe erst mit
     if(PB0){      gearbeitet, es dann aber nachher in
     if((PINB & (PINB<<PB0)){     geändert.

Ich wüsste auf den ersten Blick nicht, warum es nicht funktionieren 
sollte!?
Kannst mir aber gern auf die Sprünge helfen ;-)


mfg Yorgi

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg W. wrote:
> Ich habe erst mit
>      if(PB0){      gearbeitet, es dann aber nachher in
>      if((PINB & (PINB<<PB0)){     geändert.
>
> Ich wüsste auf den ersten Blick nicht, warum es nicht funktionieren
> sollte!?
Das eine ist so falsch wie das andere. Überleg mal, was Du da 
schiebst...

Autor: Jörg W. (yorgi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, genauer hinschauen sollte ich O:-)

     if(PINB & (1<<PB0)){

so sollte es schon eher hinkommen, oder?

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg W. wrote:
> so sollte es schon eher hinkommen, oder?
Ja...

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.