• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
DDR/PORT vs pinMode/digitalWrite
#1
Witam

Jestem początkującym użytkownikiem Arduino. W pierwszym swoim "projekcie" podłączyłem 3 diody i napisałem program który działa ale zastanawiam się co stosować DDR/PORT czy pinMode/digitalWrite. Obydwie funkcje działają z tym że PORT jest szybsze niż digitalWrite pytanie jest następujące czy zaczynać programować od PORT czy od digitalWrite ?

Poniżej dwa kody źródłowe:
Kod:
unsigned long aktualnyCzas = 0;
unsigned long zapamietanyCzas = 0;
unsigned long roznicaCzasu = 0;
byte stan = 0;

void setup() {
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
}

void loop() {
  //PORTB = B00000111;
  //digitalWrite(8, HIGH);

  aktualnyCzas = millis();
  roznicaCzasu = aktualnyCzas - zapamietanyCzas;

  if (roznicaCzasu >= 1000UL) {
    zapamietanyCzas = aktualnyCzas;
    stan++;
  }

  if (stan == 3)
  {
    stan = 0;
  }
  switch (stan) {
    case 0:
      digitalWrite(10, LOW);
      digitalWrite(8, HIGH);
      break;
    case 1:
      digitalWrite(8, LOW);
      digitalWrite(9, HIGH);
      break;
    case 2:
      digitalWrite(9, LOW);
      digitalWrite(10, HIGH);
      break;
  }
}

Kod:
unsigned long aktualnyCzas = 0;
unsigned long zapamietanyCzas = 0;
unsigned long roznicaCzasu = 0;
byte stan = 0;

void setup() {
  DDRB = B00000111;
  PORTB = B00000001;
}

void loop() {
  aktualnyCzas = millis();
  roznicaCzasu = aktualnyCzas - zapamietanyCzas;

  if (roznicaCzasu >= 1000UL) {
    zapamietanyCzas = aktualnyCzas;
    if (PORTB & _BV(2))
    {
      PORTB = PORTB << 1 | 1;
    }
    else
    {
      PORTB <<= 1;
    }
  }

}
 
Odpowiedź
#2
Ktoś kto korzysta tylko z Arduino będzie miał kłopot ze zrozumieniem o co Ci chodzi w tym kodzie. Jeśli wolisz operować wprost na rejestrach uC to prościej zainstalować sobie Eclipse i po prostu pisać w C - są podpowiedzi w IDE, ładniejszy edytor, jest dużo szybciej i dokładnie tak jak chcesz.
To że jest dłużej to jest koszt HAL, do wszystkiego są funkcje, trzeba je wywołać, wykonać, wrócic, a za to dostajesz kod działający na AVR, ARM, ESP, itd - oczywiście dopóki nie jest to próba użycia WIFI w AVR czy nieistniejącego numeru pinu w ESP8266. Ale w każdym zadziałać powinno tak samo Serial.println, digitalWrite, komunikacja po I2C i SPI. Choć tylko w ten sam uśredniony sposób.
No i setup z loop też nie są potrzebne w szkicu Arduino (choć już faktycznie nie jest szkic Arduino), można zrobić po prostu funkcję main i while(1), znikają wtedy również millis().
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#3
(25-08-2019, 13:15)kaczakat napisał(a): prościej zainstalować sobie Eclipse i po prostu pisać w C 

To już lepiej dedykowane oprogramowanie dla AVR, Atmel Studio. Masz przynajmniej konkretny debugger.

Anyway, praca na rejestrach zawsze przynosi wymierne korzyści, więc na pewno warto się uczyć.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#4
Dzięki za odpowiedzi, zainstaluje Atmel Studio i Eclipse i zobacze co będzie lepsze dla mnie. To że kod będzie mniej czytelny dla innych to trochę dziwne czyli wynika z tego iż więcej osób które pracuje na Arduino to nie korzysta bezpośrednio z rejestrów uC, tylko za pomocą funkcji pinMode itp. Bardziej mi chodziło o to jak pisać żeby było optymalnie. Obydwa kody działają, znając życie można to jeszcze napisać na kilka innych sposobów. Doczytałem że używanie PORT jest 20x szybsze od digitalWrite ale czy z tego powodu warto zaczynać się uczyć programować bezpośrednio rejestry uC ???
 
Odpowiedź
#5
Arduino to HAL, czyli hardware abstraction layer, nie interesuje mnie jakie są nazwy rejestrów i ich aktywacja. Żeby użyć operacji na portach w AVR z UNO muszę mieć mapę pinów, jaki port i pin to np. D1 czy D2, potem sięgnąć do pdf Atmegi i wertować jaki to port. Kurs podstaw Arduino użyjesz tak samo na ESP8266, STM32 czy Atmel ARM, funkjca digitalWrite na wszystkich tych płytkach zadziała tak samo. Oczywiście dedykowany kod zadziała szybciej, ale jest to mniej wygodne i więcej dziobania, coś za coś.
Atmel Studio działa bardzo topornie, pomimo I7 i 16GB RAM mam wrażenie że to bieg w wodzie. Ale oczywiście ma symulator i debuger. Eclipse mam z najnowszą wtyczką AVR 201809 i nowszej już raczej nie będzie, wielu rzeczy nie obsługuje, może nawet nie będzie najnowszych uC. Może faktycznie baw się na Atmel Studio, mniej będzie żal przesiadać się tam z Eclipse. Jest łatwiejsze, bardziej logiczne, lekkie (właściwie to rozpakowujesz w wybranym katalogu). W jednym dodajesz biblioteki CTR+C i CTR+V, w drugim "dołączasz" biblioteki na specjalne życzenie. No i tylko jeden projekt jest otwarty w danej chwili. W Arduino mam teraz na pulpicie pewnie z 50 szkicy, w zamkniętym Eclipse po otwarciu też wyskoczy mi kilkadziesiąt. No ale nie robię nic poważnego, jakiś rozbudowanych projektów, symulatora i debuggera użyłem tylko by zobaczyć jak to działa (trzeba go też mieć). Arduino mi wystarcza na razie. No i żeby używać innych płytek niż AVR to trzeba tam dorzucić wtyczkę Arduino, nie wiem czy tam się da w trakcie zabawy zmienić płytkę z UNO na ESP32.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#6
(25-08-2019, 18:59)twjx napisał(a): Doczytałem że używanie PORT jest 20x szybsze od digitalWrite
Żeby tylko 20 razy
Kod:
void digitalWrite(uint8_t pin, uint8_t val)
{
uint8_t timer = digitalPinToTimer(pin);
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *out;

if (port == NOT_A_PIN) return;

// If the pin that support PWM output, we need to turn it off
// before doing a digital write.
if (timer != NOT_ON_TIMER) turnOffPWM(timer);

out = portOutputRegister(port);

uint8_t oldSREG = SREG;
cli();

if (val == LOW) {
*out &= ~bit;
} else {
*out |= bit;
}

SREG = oldSREG;
}
a trzeba by jeszcze zobaczyć co się kryje za portOutputRegister. Zastanawia
Kod:
uint8_t oldSREG = SREG;
cli();
i
Kod:
SREG = oldSREG;
gdy istniej macro ATOMIC_BLOCK.

(25-08-2019, 18:59)twjx napisał(a): ale czy z tego powodu warto zaczynać się uczyć programować bezpośrednio rejestry uC ???
Zawsze warto poznać sprzęt. Kod funkcji digitalWrite potwierdza tezę, że gdy coś jest do wszystkiego to jest do niczego. Przekaźnikiem można sobie posterować ale zrobić np programowe SPI jest już nierozsądne. Używając rejestrów można programowo uzyskać prędkość interfejsu sprzętowego z digitalWrite też ale CPU taktowanego 500kHz.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości