Установка числа внутри структуры приводит к неправильной работе таймера

Следующий код:

struct l{
    uint8_t pin;
    uint8_t sensePin;
    float brightnessTarget;
    uint8_t PWMvalue;
    uint8_t inc;
};
typedef struct l led;

led* redLed;
led* whiteLed;
unsigned long secondsOfDay = 79140;
unsigned long minutesOfDay = 0;
unsigned int hoursOfDay = 0;
uint8_t interrupted=0;
uint8_t runPID;
int pin13=0;

void setup() {
  cli();
  TCCR1A = 0;// устанавливаем весь регистр TCCR1A в 0
  TCCR1B = 0;// то же самое для TCCR1B
  TCNT1  = 0;//инициализировать значение счетчика до 0
  // установить регистр совпадения для сравнения с шагом 1 Гц
  OCR1A = OCR1A_val;// = (16*10^6) / (1*1024) - 1 (должно быть < 65536)
  // включаем режим CTC
  TCCR1B |= (1 << WGM12);
  // Установка битов CS10 и CS12 для прескалера 1024
  TCCR1B |= (1 << CS12) | (1 << CS10);  
  // включить прерывание сравнения таймера
  TIMSK1 |= (1 << OCIE1A);
  pinMode(13,OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  sei();
}

void loop() {
  if (runPID){
    PIControl(redLed);
    PIControl(whiteLed);
    pin13 = (~pin13 & 1);
    digitalWrite(13, pin13);
    runPID=0;
  }
}


SIGNAL(TIMER1_COMPA_vect){ // срабатывание таймера на 1 секунду
  runPID = 1;
}

Переключает контакт. Однако, если я добавлю:

redLed->pin = 3;
whiteLed->pin = 4;  
redLed->sensePin = 0;
whiteLed->sensePin = 1;

В любом месте установки (до cli(), после sei() или внутри блока) прерывание больше не переключается.

Я совершенно сбит с толку и понятия не имею, что происходит.

Редактировать: подходит все, кроме whiteLed->sensePin. Эта строка и является причиной проблемы (и я до сих пор не понимаю)

, 👍0


1 ответ


Лучший ответ:

1

Это:

led* redLed;

определяет глобальную переменную, неявно инициализированную нулем (т.е. NULL указатель). Это недопустимый указатель, который вы не можете использовать, пока вы правильно его инициализируете.

Здесь:

redLed->pin = 3;

вы записываете в память, на которую указывает этот недопустимый указатель. Этот вызывает то, что в стандартах C и C++ называется неопределенным поведением. Что это означает, что, согласно определению языка C++, поведение вашей программы не определено. Другими словами, все может случаться. Обычно вы получаете аварийное завершение программы, но даже такое поведение не является гарантировано.

Никогда не обращайтесь к памяти через недопустимый указатель.

,

Фу. Я знал, что это глупая оплошность. Спасибо!, @Brydon Gibson