Управление DDR по ссылке

Тема в разделе "Микроконтроллеры AVR", создана пользователем Dolphin54rus, 29 ноя 2015.

  1. Dolphin54rus

    Dolphin54rus Нуб

    Всем привет. Решил из "процедурной лапши" сделать небольшую библиотеку и сделать классы. Например был у меня код для управления DHT22 датчика. Написал для него класс.
    Код (C++):
    class DHT22
    {
       
    public:
        const uint8_t ERROR_NOT_FOUND;
        const uint8_t ERROR_CHECKSUM;
       
    private:
        uint8_t data[4];
        volatile uint8_t* ddr;
        volatile uint8_t* port;
        volatile uint8_t* pin;
        uint8_t error;
    public:
        DHT22(volatile uint8_t* ddr, volatile uint8_t* port, volatile uint8_t* pin);
        bool pull(const uint8_t pullPin);
        float getTemperature();
        float getHumidity();
        int getError();
       
    };
    Код (C++):
    DHT22::DHT22(volatile uint8_t* ddr, volatile uint8_t* port, volatile uint8_t* pin): ERROR_NOT_FOUND(1), ERROR_CHECKSUM(2)
    {
        this->ddr = ddr;
        this->port = port;
        this->pin = pin;
       
    }
    bool DHT22::pull(const uint8_t pullPin)
    {
        error = 0;
        data[0] = 0;
        data[1] = 0;
        data[2] = 0;
        data[3] = 0;
       
        *ddr |= (1<<pullPin);
        *port &= ~(1<<pullPin);
        _delay_ms(80);
        *port |=(1<<pullPin);
        *ddr &= ~(1<<pullPin);
        // Далее идет код получения данных...
    }
    В main создаю объект

    Код (C++):
    DHT22 dht(&DDRC, &PORTC, &PINC);
     
    Так вот, проблема в следующем, если в while в цикле вызывать dht.pull(0), то работает только при первом заходе. Остальные вызовы почему то не работают. Если в DHT22::pull поменять *ddr на DDRC то все прекрасно работает. Что я не так делаю?
     
  2. Alex19

    Alex19 Гуру

    У Вас не должно быть проблем с передачей DDRx по ссылке.

    Я даже набросал, код (хоть и без полезный) на основе Вашей библиотеке убрав лишнее в Arduino IDE, использовал ATmega328P.

    .ino
    Код (C++):
    #include "Arduino.h"

    #include "DHT22.h"

    #include <util/delay.h>

    // 13 пин на ардуине Nano (atmega328P - B5)
    #define LED_PIN 5

    uint32_t previousMillis = 0;      
    const uint32_t interval = 200;

    DHT22 dht(&DDRB, &PORTB, &PINB);

    void setup()
    {
      dht.setPin(LED_PIN, OUTPUT);
    }

    void loop()
    {
      /*uint32_t currentMillis = millis();
      if(currentMillis - previousMillis >= interval)
      {
        previousMillis = currentMillis;

        dht.writePinValue(LED_PIN, !dht.getPinValue(LED_PIN));
      }*/


      while (1)
      {
        dht.writePinValue(LED_PIN, !dht.getPinValue(LED_PIN));
        _delay_ms(200);
      }
    }
    .cpp
    Код (C++):
    #include "DHT22.h"

    DHT22::DHT22(volatile uint8_t* ddr, volatile uint8_t* port, volatile uint8_t* pin)
    {
        this->ddr = ddr;
        this->port = port;
        this->pin = pin;
     
    }
    void DHT22::setPin(uint8_t pinPort, uint8_t dir)
    {
      if (dir)
      {
        *ddr |= (1<<pinPort);
      }
      else
      {
        *ddr &= (~(1<<pinPort));
      }
    }
    uint8_t DHT22::getPinValue(uint8_t pinPort)
    {
      return (*pin & (1<<pinPort));
    }
    void DHT22::writePinValue(uint8_t pinPort, uint8_t value)
    {
      if (value)
      {
        *port |= (1<<pinPort);
      }
      else
      {
        *port &= (~(1<<pinPort));
      }
    }
    .h
    Код (C++):
    #ifndef DHT22_H_
    #define DHT22_H_

    #include "Arduino.h"

    class DHT22
    {
    public:
      DHT22(volatile uint8_t* ddr, volatile uint8_t* port, volatile uint8_t* pin);
      void setPin(uint8_t pinPort, uint8_t dir);
      uint8_t getPinValue(uint8_t pinPort);
      void writePinValue(uint8_t pinPort, uint8_t value);
    private:
      volatile uint8_t* ddr;
      volatile uint8_t* port;
      volatile uint8_t* pin;
    };

    #endif
     
    Так, что смотрите в коде, Вы не привели его полностью.