Forum: Mikrocontroller und Digitale Elektronik Pin einlesen


von Bj (Gast)


Lesenswert?

Hallo zusammen

ist das der richtige befehl um einen pin der extern belegt wird bei 
einem ATmega64 einzulesen?

sensorwert = (PORTB  & PB3);

für ne Soft-Spi

gruß Bj

von Niels H. (monarch35)


Lesenswert?

PIN ist Eingang...PORT is Ausgang.

Richtig wäre so:
sensorwert=(PINB & _BV(B3));

Aber vorher bitte das entsprechende DDRB-Bit löschen:
DDRB&=~(_BV(B3));

von Bj (Gast)


Lesenswert?

Danke für deine Hilfe. aber warum muß ich das bit löschen. der pin wird 
doch von außen gefüttert.

von Niels H. (monarch35)


Lesenswert?

Vielecht schaust du mal besser in der Dokumentation nach, was das 
DDRB-Register überhaupt macht.

von Bj (Gast)


Lesenswert?

verstehe was du meinst. ich mach das immer mit imagecraft und kann mit 
nem application builder die ports/pins bestimmen.

von Niels H. (monarch35)


Lesenswert?

"Application Builder"?! Ahhh..ja...

Welcome to the real world :)

von B. K. (bekoeppel) Benutzerseite


Lesenswert?

Hi Bj,

guck dir mal das AVR-GCC-Tutorial an, da ist es beschrieben wie das es 
richtig geht: 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Zugriff_auf_Ports

Gruss
B. Köppel

von Bj (Gast)


Lesenswert?

wollte mir das ganze als anfänger was leichter machen. ist das erste mal 
das ich mit den dingern arbeite. besser wäre sicher ausführlich aber der 
innere schweinehund wollte nicht.

von Bj (Gast)


Lesenswert?

habe das jetzt so gemacht

SPI sendet ein Byte und empfängt 11 bit (msb first)

void soft_spi_Mastersend (char command2)
{
char n, i;
i = 0;

PORTB = (0 << PB0);                         //ss auf low
for (n = 7; n > 0; n--)
  {
  PORTB = (1 << PB1);               //CLK high
  command2 = command2 >> n;
  PORTB = (command2 <<PB2);
  timer0_init();                    //Timer 0 = 3,3mysec (f=150kHz)
  while (!(TIFR & (1<<TOV0)));           //Timerzeit
  TIFR = (1<<TOV0);
  PORTB = (0 << PB1);               //CLK low
  timer0_init();                    //Timer 0 = 3,3mysec (f=150kHz)
  while (!(TIFR & (1<<TOV0)));           //Timerzeit
  TIFR = (1<<TOV0);
  }
}


int soft_spi_Slavesend (void)

{
for(n = 11 ;n > 0 ;n--)
  {
  PORTB = (1 << PB1);               //CLK high
  timer0_init();                    //Timer 0 = 3,3mysec (f=150kHz)
  while (!(TIFR & (1<<TOV0)));           //Timerzeit
  TIFR = (1<<TOV0);
  PORTD = (0 << PD0);                  //Clk low
  timer0_init();                     //Timer 0 = 3,3mysec (f=150kHz)
  while (!(TIFR & (1<<TOV0)));           //Timerzeit
  TIFR = (1<<TOV0);                //Timerreset
  sensorwert = (PINB & _BV(B3));          //Einlesen der Werte MSB first
  xGes = xGes <<1;
  xGes += sensorwert;
  }
  PORTB = (1 << PB0);                         //ss auf high
  return xGes;
}

von Niels H. (monarch35)


Lesenswert?

PORTB = (1 << PB1);               //CLK high
PORTD = (0 << PD0);                  //Clk low

Zweite Zeile sieht etwas unsinnig aus...ausserdem stehen beide CLK-Ports 
in keinem Bezug. Ich vermute mal, das ist so nicht gedacht... ich 
vermute, das sollte PORTD&=~_BV(PD0) heissen...(wenn nicht sogar portb)

Ich nehme an, die DDRB's werden verher schon irgendwo gesetzt?

von Niels H. (monarch35)


Lesenswert?

ich vergas: _BV(Bitnummer) ist eine abkürzung für (1<<Bitnummer)

von Bj (Gast)


Lesenswert?

ich habe das von einer anderen soft spi, die ich an d habe teilweise 
kopiert. Danke fürs aufmerksamme lesen. welche zeile is denn die die 
deiner ansicht nach unsinnig ist?

von Niels H. (monarch35)


Lesenswert?

Sagte ich das nicht bereits?

PORTD = (0 << PD0);                  //Clk low

von Bj (Gast)


Lesenswert?

Ja das habe ich schon geändert. dachte du meinst aus dem code zeile 
2.klingt der rest für dich schlüssig?

von Niels H. (monarch35)


Lesenswert?

Bisauf die fehlenden DDRBs ....
Ich kenn mich allerdings auch nicht so mit SPI aus.

von Bj (Gast)


Lesenswert?

werde das mal testen. danke für die hilfe

von Niels H. (monarch35)


Lesenswert?

Hat denn der Code irgendwann irgendwo schonmal gefunzt?

Auf dem zweiten Blick muss ich sagen, das mir
command2 = command2 >> n;
PORTB = (command2 <<PB2);
etwas spanisch vorkommt...

von Bj (Gast)


Lesenswert?

wollte das gleich mal testen. ich will damit bitweise ein datenwort 
übermitteln.

von Niels H. (monarch35)


Lesenswert?

also command2 soll bit für bit auf PortB2 geführt werden?

So bestimmt nicht!

von Bj (Gast)


Lesenswert?

da muß ich dir recht geben. das ist schwachsinn. weiß aber auch leider 
net wie es geht

von Niels H. (monarch35)


Lesenswert?

senden auch msb first?

uint8_t bitval;

bitval=(command2 & 128);  // msb ausmaskieren
command2 = command2 << 1;
bitval=(bitval >> 5);     // aus Position von PB2 verschieben
if (bitval != 0)
    PORTB|=bitval;
else
    PORTB&=~bitval;



Verstanden?

von Bj (Gast)


Lesenswert?

ja senden auch msb first
die if/else glaube ich zu vertehen. das ist ja wie

if (data & 1){
  PIN_SPI_DATA = 1;
else{
  PIN_SPI_DATA = 0;
}
data = data >> 1;

aber das mit dem ausmaskieren verstehe ich nicht.

von Bj (Gast)


Lesenswert?

und warum >>5?

von Bj (Gast)


Lesenswert?

habe das jetzt mal so gemacht:


PORTB = (0 << PB0);                         //ss auf low
for (n = 7; n > 0; n--)
  {
  PORTB = (1 << PB1);               //CLK high
  if (command2 & 0x8000)                // Wenn MSB-Bit gesetzt
     {
       PINB = (1<<PINB2);                 // Data-Pin auf 1 schalten,
     }
    else
     {
       PINB = (0<<PINB2)                 // ansonsten auf 0
     }
    command2 = command2 << 1;

von Niels H. (monarch35)


Lesenswert?

Ich sehe, da fehlen ein klein wenig die logischen Grundlagen.

Ein Byte besteht aus 8 Bit. (Das war jetzt hoffendlich nicht die grosse 
Neuigkeit). Die 8 Bits in diesem Byte haben unterschiedliche Wertigkeit:
1 2 4 8 16 32 64 und 128
Sind alle 8 Bits in diesem Byte gesetzt kommt man so auf die Summe von 
255 die das Byte dann als Wert hätte.

Wir interessieren uns zunächst aber nur für das höhstwertigste Bit 
(128). Deshalb blenden (maskieren) wir alle anderen Bits aus.

wert=command2 & 128;

War das MSB gesetzt, hat "wert" jetzt den Wert 128. Falls nicht, 0.

Ich habe dieses MSB (ob gesetzt oder nicht) dann einfach auf die 
Position von PB2 (um 5 nach 'unten') um es dann einfach direkt den 
PortBit zuzuweisen. Der Ausdruck dafür wäre aber vermutlich etwas zuviel 
für einen Anfänger gewesen, deshalb hab ichs dann doch mit IF gemacht. 
Etwas blöd...sorry. Tatsächlich kannst du die Zeile mit dem >>5 
weglassen.

command2 = command2 << 1 schubst einfach das Bit6 (64) auf die Stelle 
von Bit7(128), damit beim nächsten schleifendurchlauf damit gearbeitet 
wird.

von Niels H. (monarch35)


Lesenswert?

if (command2 & 0x8000)

urgs...
wenn schon Hexadezimal, dann auch richtig: 128 = 0x80

von Bj (Gast)


Lesenswert?

noch ein fehler von mir. logisch. aber so dämlich wie heute bin ich 
sonst nicht.

von Bj (Gast)


Lesenswert?

und wieder port und pin vertauscht

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.