Установка числа внутри структуры приводит к неправильной работе таймера
Следующий код:
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. Эта строка и является причиной проблемы (и я до сих пор не понимаю)
@Brydon Gibson, 👍0
1 ответ
Лучший ответ:
Это:
led* redLed;
определяет глобальную переменную, неявно инициализированную нулем (т.е. NULL указатель). Это недопустимый указатель, который вы не можете использовать, пока вы правильно его инициализируете.
Здесь:
redLed->pin = 3;
вы записываете в память, на которую указывает этот недопустимый указатель. Этот вызывает то, что в стандартах C и C++ называется неопределенным поведением. Что это означает, что, согласно определению языка C++, поведение вашей программы не определено. Другими словами, все может случаться. Обычно вы получаете аварийное завершение программы, но даже такое поведение не является гарантировано.
Никогда не обращайтесь к памяти через недопустимый указатель.
- Использование millis() и micros() внутри процедуры прерывания
- Подсчет импульсов с прерыванием
- Устранение дребезга кнопки с помощью прерывания
- Программа arduino выдаёт ошибку expected //primary-expression before ')' token error: //expected ';' before '}' token E
- Почему необходимо использовать ключевое слово volatile для глобальных переменных при обработке прерываний в ардуино?
- Как сгенерировать аппаратное прерывание в mpu6050 для пробуждения Arduino из режима SLEEP_MODE_PWR_DOWN?
- Использование поворотных энкодеров с прерываниями смены контактов
- Arduino непрерывно считывает значение АЦП с помощью прерывания
Фу. Я знал, что это глупая оплошность. Спасибо!, @Brydon Gibson