Forum: Mikrocontroller und Digitale Elektronik Variabler Port


von Harald U. (cm-rex)


Lesenswert?

Hallo Leute,

Ists möglich bei einem Funktionsaufrum den Ausgangsport Variabel zu 
machen?
Variabler Pin ist mir klar.
zB:

void ausgang (??? Portx, uint_8 Pinx)
{
Portx |= (1<<Pinx);
}


ausgabe(???,meinpin);


und wie muss ich dann das deklarieren?

Danke schon im Voraus für eure Bemühungen :-)

Lg.

Harald

von N. G. (newgeneration) Benutzerseite


Lesenswert?

Wenns für den AVR ist:

http://nongnu.org/avr-libc/user-manual/FAQ.html#faq_port_pass

Wobei man evtl darüber nachdenken sollte, den Pin als Maske zu 
übergeben, also nicht:
function(&PORTA, 1);
sondern
function(&PORTA, 1<<1);

Das kann der Compiler nämlich besser optimieren (er übergibt einfach 
direkt die Zahl) und muss nicht ewig rum shiften.

mfG
N.G.

: Bearbeitet durch User
von Ralf G. (ralg)


Lesenswert?

N. G. schrieb:
> Das kann der Compiler nämlich besser optimieren

Das hat sich in der Regel sowieso schon mit der Übergabe der Portadresse 
erledigt. Über mehrere Dateien verliert auch da der LTO die Übersicht. 
(-> Es könnte sich ja auch um einen Port handeln, der nicht mit IN/ OUT 
erreichbar ist.)

Zur Frage:
1
void Set(volatile uint8_t* port, uint8_t pin_mask)
2
{
3
    *port = pin_mask;
4
}

: Bearbeitet durch User
von Harald U. (cm-rex)


Lesenswert?

Hi,

Danke für die schnelle Antwort:-)
Hat auch mehr oder weniger gut funktioniert....

noch eine andere frage, in einer forschleife kann ich da auch für "i" 
uint32 verwenden?
ich brauch pausen von 250us bis 5min. Mein cood sieht so aus:


const uint32_t t_daten[] PROGMEM = 
{1,4,10,16,20,40,80,160,400,4000,8000,16000,32000,60000,120000,180000,24 
0000,360000,480000,720000,1200000};




  uint32_t bel_time=400;
  if (time<=21) bel_time = t_daten[time];
  for (uint32_t i=0;i<bel_time;i++){
    _delay_us(250);
  }

aber irgendwie funktioniert das nicht.
Er kommt aus der schleife nicht mehr raus.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Harald U. schrieb:
> Er kommt aus der schleife nicht mehr raus.

 Er kommt gar nicht erst in die Schleife rein.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Harald U. schrieb:
> noch eine andere frage, in einer forschleife kann ich da auch für "i"
> uint32 verwenden?

Ja, aber statt
1
if (time<=21)

sollte da
1
if (time<21)

stehen, sonst wird für t = 21 ein Wert außerhalb des Arrays gelesen.

> Er kommt aus der schleife nicht mehr raus.

Nach spätestens 12,5 Tagen sollte es so weit sein. Hast du so lange
gewartet? ;-)

Edit: Falls eine 0 gelesen wird, wartest du tatsächlich ewig.

: Bearbeitet durch Moderator
von Ralf G. (ralg)


Lesenswert?

Zwei Fehler!

Harald U. schrieb:
1
  const uint32_t t_daten[] PROGMEM =
2
  {
3
    1,4,10,16,20,40,80,160,
4
    400,4000,8000,16000,32000,60000,120000,180000,
5
    240000,360000,480000,720000,1200000
6
  };
7
 
8
  uint32_t bel_time=400;
9
  if (time<=21) bel_time = t_daten[time];
10
//                         ^^^^^^^^^^^^^^ -> Zugriff entweder über die entsprechenden Routinen oder statt PROGMEM __flash verwenden
11
//        ^^ -> der höchste Index ist 20!
12
  for (uint32_t i=0; i<bel_time; i++)
13
  {
14
    _delay_us(250);
15
  }

Es hat nichts mit der Schleife zu tun. Der fälschlich gelesene Wert für 
bel_time ist nur möglicherweise seeeehr groß.

von Harald U. (cm-rex)


Lesenswert?

Hab in der Schleife ein uart_putc eingebaut, also rein kommt er.

void fokusausloesung ()
{
  uint32_t bel_time=400;
  int time = uart_getc();    //wenn ich hier 1 übergebe , kommt er dann 
unten auch nicht mehr raus.
  if (time<=21) bel_time = t_daten[time];
  PORTD |= (1<<PD3);
  PORTB |= (1<<PB0);
  _delay_ms(200);
  _delay_ms(200);
  _delay_ms(200);
  _delay_ms(200);
  _delay_ms(200);
  PORTB |= (1<<PB5);
  for (uint32_t i=0;i<bel_time;i++){
  _delay_us(250);
  uart_putc(i);         //zum prüfen
  }
  PORTB &= ~(1<<PB5);
  PORTB &= ~(1<<PB0);
  uart_putc(250);
  PORTD &= ~(1<<PD3);
  return;
}

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Harald U. schrieb:
1
 if (time<=21) bel_time = t_daten[time];

 Das ergibt genau 0.

Yalu X. schrieb:
> Edit: Falls eine 0 gelesen wird, wartest du tatsächlich ewig.

 Es wird eine 0 gelesen.

 Mit:
1
   bel_time = pgm_read_byte(&t_daten[time]);

 sollte es klappen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

S. Beitrag von Ralf: Die Array-Zugriffe gehen bei dir nicht ins Flash,
sondern ins RAM, und da liegen nicht die erwarteten Daten.

von Harald U. (cm-rex)


Lesenswert?

Ihr seits Spitze !!!!



  bel_time = pgm_read_byte(&t_daten[time])
Danke es funktioniert :-)

von Ralf G. (ralg)


Lesenswert?

Harald U. schrieb:
> bel_time = pgm_read_byte(&t_daten[time])
> Danke es funktioniert :-)
... kann eigentlich nicht sein. :-/
Die Funktion liest nur ein Byte. Du willst ja aber vier davon.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Ralf G. schrieb:
> Harald U. schrieb:
>> bel_time = pgm_read_byte(&t_daten[time])
>> Danke es funktioniert :-)
> ... kann eigentlich nicht sein. :-/
> Die Funktion liest nur ein Byte. Du willst ja aber vier davon.

 LOL. Auch erst jetzt gesehen...
 Dann eben:
1
    bel_time = pgm_read_dword_near(&t_daten[time])

: Bearbeitet durch User
von Harald U. (cm-rex)


Lesenswert?

hmmm, Ok,
Muss das am Abend dann testen....
Hab dasss nur mit kurz probiert....
Danke für den Hinweis :-)

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.