• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

почему noInterrupts не останавливает работу analogWrite

Eugenie

New member
Из за того что на esp8266 нет аппаратного PWM , известно что analogWrite , это софтверная реализация на таймерах.
логично что noInterrupts должен останавливать работу софтверного PWM . но на практике этого не происходит.

соединил GPIO4 c ADC входом ESP8266

uint16_t adc_addr[128];

long lasttick = 128;
static void IRAM_ATTR OSCSyncGPIO() {
if (lasttick--) return;
noInterrupts();// остановка работы всех прерываний , по идее все 128 значений должны содержать одно значение т.к генерация останавливается
lasttick = 128;

system_adc_read_fast(adc_addr, 128, 1); // но тут мы считываем полноценный меандр с указанной частотой

interrupts();
}

setup(){
osc = new OSC();
pinMode(3, OUTPUT);

analogWriteFreq(16750); // Устанавливаем частоту
analogWriteRange(1024); // Устанавливаем максимальное значение диапазона
analogWrite(3, 512); // 50% заполнение
attachInterrupt(digitalPinToInterrupt(3), OSCSyncGPIO, FALLING);
}

loop(){
выводим на экранчик показания АЦП
}

Подскажите почему noInterrupts никак не влияет на софтверный PWM?

ПС. есть еще одна проблема при считывании фаза сигнала "скачет"
WIFI не использую , выключен и не инициализирован даже
 

pvvx

Активный участник сообщества
Потому что есть маскируемые и немаскируемые прерывания.

PWM с некоторой версии Дурины работает от NMI. Иначе будут биения.
 

pvvx

Активный участник сообщества
ПС. есть еще одна проблема при считывании фаза сигнала "скачет"
WIFI не использую , выключен и не инициализирован даже
  • Прерывания по изменению сигнала на GPIO имеют шаг с частотой тактирования GPIO контроллера (ниже частоты кварца)
  • Обращение к регистрам контроллеров происходят с частой тактирования внутренней шины (это частота кварца, а не CPU). Плюс там работает FIFO и CPU приходится ожидать отработки шины. При этом потребление ESP возрастает, а должно быть иначе - но так реализована аппаратная часть в ESP.
  • Переключение прерывания GPIO в ESP8266 аппаратно реализовано ужасно. Требуется множество команд к контролеру в момент прерывания и запрета других прерываний. А реализация обработки прерывания в Дурина реализована кое-как. Плюс большая ветвистость программы вызывает дополнительные "биения" счета.
 

pvvx

Активный участник сообщества
Плюс ко всему поступление команд к ALU CPU происходит из кэш. А кэш заполняется из SPI-Flash кусочками и медленно = биения. И если код не влез в кэш, или кэш был сброшен любой командой прямого обращения к Flash через контролер SPI, то производительность любого ESP/ESP32 падает ниже CPU типа Cortex работающего на частоте 16МГц.
Чтобы этого не происходило, требуется не задействовать XIP (кэш FLash) = необходимо размещать такой код в IRAM.
 

pvvx

Активный участник сообщества
Некоторые инструкций C++ обращаются к HEAP памяти. А при выделение памяти или любые другие операции с HEAP производятся с запретом прерываний. Это ещё не говоря о неизбежной дефрагментации памяти, которая через некоторое время приведет к краху системы, если объем HAEP не превышает сумму всех запросов в вашей программы в десятки раз. Для решения проблемы дефрагментации человечество давно придумало аппаратную реализацию виртуализации памяти (это входит в MMU). Но у ESP/ESP32 этого нет. А в простых MCU используют статическое выделение памяти.
И запрет прерываний в этих командах так-же сказывается на ваши "биения" счетчика...
 
Сверху Снизу