PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Port erweiterung -- Parallele Ausgabe--avr gcc



claudia1989
21.02.2011, 03:26
Port erweiterung -- Parallele Ausgabe--avr gcc


Hey Liebe Elek'er,

bin wieder da und ich versuche gerade ein absolut Drehgeber mit
meinem Atmega88 auszulesen. Habe ein c code beim googlen gefunden (http://www.posital.eu/en/products/POSITAL/AbsoluteEncoders_Context/AbsoluteEncoders_Context_Technology_SSI_AppNote.pd f) und kann schon die werte über Usart auf my pc anzeigen (mit der spi_read methode siehe source code.).

jetzt möchte ich aber die daten (uint16_t u16singleturn) paralllel
ausgeben am Pin (Port) die übrig sind (PC0...5 , PD3...7,usw...)oder am
zwei 74HC595 .

Meine Fragen:

1)( Methode Spi_read () siehe source code). wie kann ich zum Bspl.
eine uint8_t variable am PC0...5 und PD4,5 ausgeben. (mit MSB am PC0 und
LSB am PD5 oder umgekehr) ?
DDRC = (1 << DDC0) | (1 << DDC1) | (1 << DDC2) | (1 << DDC3) | (1
<<DDC4)| (1 <<DDC5); //oder DDRC=0x3F;
DDRD = (1<<DDD4) | (1<<DDD5) ;
und dann ?

2)(Methode pinToggleReadSSI( void )) .für die Ausgabe mit zwei 74*595.
ich nehme an RCK liegt am PB3, wie mache ich ein 010 am PB3 um die
daten am Latch ausgang zu haben. so?:
DDRB = ( 1 << DDB3);
PORTB=(1<<PB3);
PORTB=~(1<<PB3);
PORTB=(1<<PB3);
?
3)(und falls Ihr etwas zeit habt ,würde mich sehr freuen). Für die
Ansteuerung via Software
hier(http://www.rn-wissen.de/index.php/Portexpander_am_AVR#Ohne_SPI-Hardware)
,

wie würde dann serpa.c ausehen mit zwei 74*595 (also uint16_t u16data
ist auszugeben) und:
PC0->SCK
PC1->RCK
PC2->SER
?

Schaltung und Software zum Auslesen des Absolut drehgeber habe ich hier
gefunden (pdf):
http://www.posital.eu/en/products/POSITAL/AbsoluteEncoders_Context/AbsoluteEncoders_Context_Technology_SSI_AppNote.pd f
(bin etwa verwirrt mit dem avr gcc und Portexpander tuto )

danke im voraus

XBert
22.02.2011, 15:26
1)


DDRC = (1 << DDC0) | (1 << DDC1) | (1 << DDC2) | (1 << DDC3) | (1<<DDC4)| (1 <<DDC5); //oder DDRC=0x3F;
DDRD = (1<<DDD4) | (1<<DDD5) ;
PORTC = var&0b11111100; //bzw PORTC |= var&0b11111100 wenn die letzten 2 bit belassen werden sollen
PORTD = var&0b00000011;
Wenn nötig musst du halt dein uint8_t swappen.
2)


DDRB = ( 1 << DDB3);
PORTB &=~(1<<PB3); // oder das & weglassen wenn die anderen Pins auf high sein sollen
PORTB |=(1<<PB3);
PORTB &=~(1<<PB3);
vermutlich wirst du aber noch delays dazwischen machen müssen (je nachdem wie schnell/langsam deine clock ist; oder das ganze mit Interrupts machen)
3)
hab ich im Moment keine Zeit dafür ;)

LG

claudia1989
23.02.2011, 00:41
Hey Xbert, danke für deine Antwort,


PORTC = var&0b11111100; //bzw PORTC |= var&0b11111100 wenn die letzten 2 bit belassen werden sollen
PORTD = var&0b00000011;

0)
frage: sollte das nicht so etwa sein ?:
PORTC = (var & 0x3F);//bzw. var & 0x0b00111111
PORTD = ((var & 0xC0) >> 2);//bzw var&0b11000000
Gut. aber die anderen Pins werden überschrieben.

1)
Beispiel : am portc habe ich 0b00000000 und
portd 0b11110001

danke !
und var ist 0b00001110

Nach diesen Zuweisungen PORTC = var&0b11111100; und PORTD = var&0b00000011; habe ich Portc =00001100 und Portd= 00000010 mit LSB von Var am PD0 und MSB am pc6(reset).

2) falls ich die zuweisung so durchführe:
PORTC |= (variable & 0x3F);//bzw. variable & 0b00111111
PORTD |= ((variable & 0xC0) >> 2);//...
mit portc = 0b11111111 ,portd = 0b00001111 undvar =0b00000000 dann habe ich am Portc =0b11111111 und Portd=0b00001111;

in den beiden letzten Fälle, fals ich mich nicht irre bekomme ich nicht meine var am Pc0...5 und Pd4,5.

3)
kann man nicht auf einzelne Pin zugreifen zum beispiel PC0 = Var&0b00000001 ?
4)
wenn var eine uint16_t ist muss ich die zuweisung wie folgt durchführen ?:
PORTC = uint8_t (var & 0x3F);//bzw. var & 0x0b00111111
PORTD = uint8_t((var & 0xC0) >> 2);//bzw var&0b11000000

sternst
23.02.2011, 02:49
Wenn du mehrere Pins an einem Port auf einen bestimmten Wert setzen willst, ohne die anderen Pins zu beeinflussen, dann sieht das z.B. so aus
(Bit 0 und 1 von var an Pin 2 und 3 von PORTD ausgeben):

PORTD = (PORTD & 0b11110011) | ((var<<2) & 0b00001100);

Aber Achtung: wenn diese "anderen Pins" in einem Interrupt verändert werden, dann muss die Zeile natürlich atomar gekapselt werden.

claudia1989
23.02.2011, 03:41
Hey Sternts, danke und :


Wenn du mehrere Pins an einem Port auf einen bestimmten Wert setzen willst, ohne die anderen Pins zu beeinflussen, dann sieht das z.B. so aus
(Bit 0 und 1 von var an Pin 2 und 3 von PORTD ausgeben):

PORTD = (PORTD & 0b11110011) | ((var<<2) & 0b00001100);

Aber Achtung: wenn diese "anderen Pins" in einem Interrupt verändert werden, dann muss die Zeile natürlich atomar gekapselt werden.

wie sollte die zuweisung aussehen für uint16_t var?:
(Bit 0 und 1 von var an Pin 2 und 3 von PORTD ausgeben):

PORTD = (PORTD & 0b11110011) | (uint8_t ((var<<2) & 0b00001100));
PORTD = (PORTD & 0b11110011) | (uint8_t(var<<2) & 0b00001100);
PORTD = (PORTD & 0b11110011) | ((var<<2) & 0b0000000000001100);//oder &0x000C;


Danke ;)

sternst
23.02.2011, 11:30
wie sollte die zuweisung aussehen für uint16_t var?Genauso. Was in den oberen 8 Bits passiert wäre unerheblich, denn in der Zuweisung an PORTD steckt ein impliziter Cast nach uint8_t. Da fallen diese oberen 8 Bits dann eh einfach weg.


PORTD = (PORTD & 0b11110011) | (uint8_t ((var<<2) & 0b00001100));
PORTD = (PORTD & 0b11110011) | (uint8_t(var<<2) & 0b00001100);
PORTD = (PORTD & 0b11110011) | ((var<<2) & 0b0000000000001100);//oder &0x000C;
Würde aber auch alles funktionieren (von der falschen Schreibweise beim Typ-Cast mal abgesehen).