Schieberegister mit PIN abfrage

Gast #2559791
Lesenswert?
• ▲
▼
hy zusammen,

will an meinem atmega8 den PIN lesen und weiter senden an den PC per 
USB,
beim PIN einlesen liegt das Problem.
Dachte an ein schieberegister nur umgekehrt, erliest nur den ersten 
zustand und hört auf zu Schieben.
1
  case USB_Trans:
2
    PORTB |= (1<<PB0);
3
  
4
    unsigned short Datain = 0; 
5
    for(uint16_t a = 0; a<16 ; a++)
6
    {
7
    PORTB |= (1<<PB5); //CLK High
8
  
9
    if(PINB &(1<<PINB4))
10
    {
11
      Datain = High;
12
    }
13
    else
14
    {
15
      Datain = Low;
16
    }
17
    Datain <<=1;
18
    PORTB &= ~(1<<PB5); //CLK Low
19
    }
20
    PORTB &= ~(1<<PB0);
21
    itoa(Datain,Dataout,10);
22
    usbMsgPtr = Dataout;
23
  return sizeof(Dataout);


wäre für Tipps dankbar
Mfg Rudi
#2559856
Lesenswert?
• ▲
▼
Rudi schrieb:
> Das habe ich mir gedacht,

Was hast du dir gedacht?

> Anders gefragt ist ein Schieberegister überhaupt sinnvoll für die
> Aufgabe oder doch lieber mit dem fifo befassen?

Schieberegister ist doch schon ok.

Klartext: Du hast einen Programmfehler! Korrigier ihn und alles ist gut.

wenn du

   i = 5;

ins Programm schreibst, erwartest du ja auch nicht, dass da irgendwelche 
Bits von vorher irgendwie magisch überleben!
Warum erwartest du das dann bei

      Datain = High;

Was immer vorher in Datain stand (zb die Bits aus den vorhergehenden 
Schleifendurchläufen), durch die Zuweisung werden sie sicher glöscht. 
Danach enthält Datain nur noch das durch 'High' definierte Bitmuster.
Gast #2560267
Lesenswert?
• ▲
▼
Also ich würde das so machen:
1
case USB_Trans:
2
    PORTB |= (1<<PB0);
3
  
4
    unsigned short Datain = 0; 
5
    for(uint16_t a = 0; a<16 ; a++)
6
    {
7
       Datain <<=1;
8
       PORTB |= (1<<PB5); //CLK High
9
       if (PINB & (1<<PINB4)) Datain |= High;
10
       PORTB &= ~(1<<PB5); //CLK Low
11
    }
12
    PORTB &= ~(1<<PB0);
13

14
    itoa(Datain, Dataout, 10);
15
    usbMsgPtr = Dataout;
16
    return sizeof(Dataout);

Das Shiften muss außerdem vor dem Ver-Odern geschehen.
Ob das 'sizeof(Dataout)' stimmt, ist auch fraglich...
Gast #2563104
Lesenswert?
• ▲
▼
Man war das peinlich von mir, erst denken dann schreiben.
Habe umgedacht weil es mit dem Timing nicht gepasst. es kommt zwar etwas 
an aber nicht das was ich verschicke.
Vom Slave kommt ein Dummy wert (0xaaaa) beim Master kommt immer 
unterschiedliche werte an, deshalb habe ich ein paar warte schleifen im 
master eingesetzt um das Timing zu verbessern.
Deshalb gibt der Slave den takt vor.

als Master mega8:
Sende Vorgang starten mit PB0
Wert lesen am PINB1
1
case USB_Trans:
2
    DDRB  |= (1<<PB0);//Ausgang für CS
3
    PORTB |= (1<<PB0);//High
4
    DDRB &= ~(1<<PB2)|(1<<PB1);//eingang
5
    PORTB |= (1<<PB2)|(1<<PB1);//Pull-up
6

7
    uint16_t Datain = 0; 
8
    for(uint16_t a = 0; a<16 ; a++)
9
    { 
10
      
11
    do{}
12
    while((PINB &(1<<PINB2)));
13

14
    if(PINB &(1<<PINB1))
15
    {
16
      Datain |= 1 ;
17
    }
18
    else
19
    {
20
      Datain &= ~1 ;
21
    
22
    }
23
    Datain <<=1;
24
    do{}
25
    while(!(PINB &(1<<PINB2)));
26
    }
27
    PORTB &=  ~(1<<PB0);    
28
    itoa(Datain, Dataout, 10);
29
    
30
    usbMsgPtr = Dataout;
31
  return sizeof(Dataout);

als Slave habe den tiny13
Takt Vorgabe
und wert raus shiften
1
uint16_t wechsel = 0xAAAA;
2

3
if((PINB & (1<<PINB0))) //Wenn CS High geht 
4
{  
5

6
MSB = 0x8000;
7
    for(int8_t a = 16 ; a>=0 ;a--)
8
  {  
9

10
  PORTB |=(1<<PB2);
11
  
12
  
13
  if(MSB & wechsel)
14
  {
15
           PORTB |= (1<<PB1);
16
  }
17
  else 
18
  {
19
           PORTB &= ~(1<<PB1);
20
  }
21
      
22
  MSB >>= 1;   //schiebt nach rechts
23
  PORTB &=~(1<<PB2);
24
  }
25
  
26
  do{}
27
  while(!(SPI_Init_PIN & (1<<SS_PIN0)));//warte bis CS wieder low ist 
28
}  
29
}

>Ob das 'sizeof(Dataout)' stimmt, ist auch fraglich...
Es funktioniert habe es noch in anderen Cases.

danke für die tipps
#2563145
Lesenswert?
• ▲
▼
Rudi schrieb:

> Deshalb gibt der Slave den takt vor.

Kann man machen.

Ein Tip:
Du musst dir darüber im klaren sein, was denn der Ruhezustand der 
Taktleitung sein soll. Also: welchen Zustand hat sie, wenn der Tiny noch 
nicht angefangen hat zu senden.

Da du im Tiny Code auf jeden Fall zum Schluss das hier machst

  PORTB &=~(1<<PB2);

ist der Ruhezustand offenbar 0.

Das bedeutet aber auch, dass dein Code im Mega:

> case USB_Trans:
>     DDRB  |= (1<<PB0);//Ausgang für CS
>     PORTB |= (1<<PB0);//High
>     DDRB &= ~(1<<PB2)|(1<<PB1);//eingang
>     PORTB |= (1<<PB2)|(1<<PB1);//Pull-up
>
>     uint16_t Datain = 0;
>     for(uint16_t a = 0; a<16 ; a++)
>     {
>
>     do{}
>     while((PINB &(1<<PINB2)));

hier erst mal einen Low-Pegel vorfinden wird, wenn der Tiny es nicht 
schafft die Taktleitung im Zeitraum vom Erkennen seines CS Signals bis 
zum Zeitpunkt an dem der Master das erste mal die Taktleitung abfrägt 
auf High zu ziehen. Mit dem Effekt, dass der Master über diese while 
Schleife drüberrauscht und ein falsches Bit einliest.
#2563155
Lesenswert?
• ▲
▼
> >Ob das 'sizeof(Dataout)' stimmt, ist auch fraglich...
> Es funktioniert habe es noch in anderen Cases.

Da hat er sich falsch ausgedrückt.
Das du den sizeof zurückgeben kannst steht natürlich ausser Frage. Die 
Frage ist nur: was bringt dem Aufrufer diese Information. Er kann damit 
nur sehr bedingt irgendetwas anfangen.

Wie gross das Array Dataout ist, kann er selbst auch feststellen. 
Interessant wäre für ihn höchstens, wie lang der String ist, den itoa 
dort abgelegt hat. Aber das ist nicht die Information, die man mittels 
sizeof ermitteln kann.
Gast #2564643
Lesenswert?
• ▲
▼
So ich bins mal wieder beim Slave-Timing bin ich verzweifelt. So kam ich 
auf HW-SPI-slave beim Atmega8. es wird zwar der richtige wert übertragen 
aber nur nach dem brennene.
Nach dem brennt kommt 170 (0xaa) was auch richtig. Wenn ich den 
Schaltung Deaktiviere Bzw. Master auf reset drücke bekomme ich andere 
werte sind zwar vom Bit muster ähnlich zu 0b10101010 aber halt nicht 
richtig. Habt Ihr vielleicht ne Idee
1
//master 
2
if((PINB & (1<<PINB1))) //Wenn CS High geht 
3
{  
4

5

6
    for(int8_t a = 0 ; a<8 ;a++)
7
  {  
8

9
  if(MSB & wechsel)
10
  {
11
           PORTB |= (1<<PB0); //MOSI
12
  }
13
  else 
14
  {
15
           PORTB &= ~(1<<PB0);//MOSI
16
  }
17
      
18
 
19
  PORTB |= (1<<PB2);//CLK HIGH
20
  PORTB &= ~(1<<PB2);//CLK LOW
21
   MSB >>= 1;   
22
  }
1
case USB_Trans://SPI-Slave
2
uint8_t Datain81 = 0;
3
uint8_t Datain82 = 0;
4
uint16_t Datain16 = 0;
5
volatile unsigned char status = 0;
6

7
SPCR = (1<<SPE);
8
status = SPSR;    
9

10
  PORTB |= (1<<PB1);
11

12
  
13
  Datain81 = SPDR;
14
  //Datain82 = SPDR;
15
  PORTB &= ~(1<<PB1);
16
  //Datain16 = (Datain81<<8)|Datain82;  
17
  itoa(Datain81, Dataout, 10);
18
    
19
    usbMsgPtr = Dataout;
20
  return sizeof(Dataout);

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.