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
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; |
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
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 | }
|
Wenn in "flag" das auszugebende Byte steht, dann dürfte das klappen.
> 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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.