ATtiny45 - Zustand an Pin zu bestimmtem Zeitpunkt speichern

Gast #850593
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.
#850615
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;
>    }
Gast #851201
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
#854695
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren