Forum: Compiler & IDEs Pin entsprechend eines Bits aus char setzen


von Dirk S. (fusebit)


Lesenswert?

Moin Leute,

ich stehe hier auf dem Schlauch. Ich habe ein Konfigurations char der 
innerhalb einer for-Schleife an einen ADC übergeben werden soll.

Ich habe also z.B.: 01100110

Dann möchte ich im ersten Durchlauf den entsprechenden Portpin auf Null 
setzten, im zweiten und dritten auf eins usw...

Nur wie picke ich mir die Werte raus?

Den umgekehrten Fall, einen Wert von einem Pin in einen char schieben 
habe ich kapiert, nur andersherum verstehe ich es nicht :-(


Vielen Dank schonmal

Dirk

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Vielleicht willst du ja Hardware-SPI nehmen?

In Software ungefähr so:
1
uint8_t
2
talk(uint8_t what)
3
{
4
   uint8_t i, res;
5
6
   for (i = res = 0; i < 8; i++) {
7
      res >>= 1;
8
      if (what & 0x80)
9
         PORTA |= 1;
10
      else
11
         PORTA &= ~1;
12
      /* clock pulse */
13
      PORTA |= 2;
14
      PORTA &= ~2;
15
      asm("nop");
16
      if (PINA & 4)
17
         res |= 0x80;
18
      what <<= 1;
19
   }
20
21
   return res;

von Jörg X. (Gast)


Lesenswert?

Hast du dir mal SPI angeschaut?
1
int8_t i;
2
for( i = 0; i<8; i++){
3
    if (data & 0x01) /* 0x80, wenn das Höchste Bit (MSB) zuerst gesendet werden soll */
4
        SETPIN;
5
    else
6
        CLEARPIN;
7
    /* hier muss bestimmt ein Taktsignal erzeugt werden, also ein Art 
8
 _delay() */
9
    
10
   data >>= data; // "<<=" wenn das MSB zuerst gesendet wird
11
   //wieder Taktsignal
12
}
13
//SETPIN, CLEARPIN sehen ungefähr so aus
14
#define SETPIN PORTN |= (1<<PN)
mach dir noch Gedanken:
 - welchen Pegel haben die Leitungen, wenn nicht gesendet wird
 - wann kommt das Taktsignal, d.h. die Flanken (kein Taktsignal haben im 
µC-Bereich eigentlich nur 1Wire oder UART-Signal)
 - muss die Datenleitung zwischen In/Output umgeschaltet werden (falls 
es nur eine gibt)
 - in welcher Reihenfolge werden mehrere Bytes gesendet
 - Kannst du nicht vielleicht eingebaute Hardware (SPI, TWI, USART) oder 
fertigen Code benutzen (Hier im Codesammlung -Forum)

hth. Jörg

von Dirk S. (fusebit)


Lesenswert?

Klar könnte man Hardware SPI nehmen, aber dann kapiere ich das ja nie. 
Ich möchte das einmal zu Fuß machen, danach kann ich ja das Auto 
nehmen...

Vielen Dank für die Tipps, werde sie mal versuche zu verstehen. Habe 
aber auch schon selber weiter geschaut. Könnte das funktioneren?
1
  for(int i=0;i<8;i++)
2
  {
3
    SETBIT(PORTB,3);            //SLK auf 1
4
    
5
    if((flag & (1<<i) !=0)) SETBIT(PORTB,2);
6
    else CLRBIT(PORTB,2);
7
    
8
    asm volatile ("nop");
9
//    wert=(wert<<1);
10
//    asm volatile ("nop");
11
//    if (bit_is_set(PIND,6)) wert|=1;    //DATA abfragen
12
    CLRBIT(PORTB,3);            //SCK auf 0
13
  }

von Johannes M. (johnny-m)


Lesenswert?

Wenn in "flag" das auszugebende Byte steht, dann dürfte das klappen.

von Jörg X. (Gast)


Lesenswert?

> 1<<i
ist auf dem AVR evtl. nicht so günstig, der kann nur 1 oder 4 Bits auf 
einmal schieben, also auf jeden Fall das List-File anschauen

> if(flag & (1<<i) !=0)
finde ich sehr hässlich -- if(flag &...) tut exakt das gleiche (aber 
meine persönliche Meinung)

und am Ende musst du nach dem
> CLRBIT(PORTB,3);            //SCK auf 0

wahrscheinlich noch mal warten (Nop/delay..)

hth. Jörg

von Frank J. (frajo)


Lesenswert?

Ich schreibe ein Byte seriell über einen Portpin auf eine 3 Leitungs 
Chipkarte SLE4442 so:
1
void writedata(uint8_t wert) {
2
  uint8_t i;
3
  for(i=0; i<8; i++) {
4
    if (wert & 0x01) io1; else io0;
5
    puls();
6
    wert = (wert>>1);
7
  }
8
}

  

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.