Добрый день!
Разбираюсь с работой аппаратного таймера ESP. Сделал простую программу, которая тикает каждую секунду и осуществляет вывод в UART.
В принципе программа работает, правда показания вывода времени тиков плавают на единицы миллисекунд. Теперь стоит задача этим таймером организовать 2 интервала времени, что-то типа ШИМ, с возможностью изменения скважности выходного сигнала, формируемого при помощи этого таймера. Но непонятно, как правильно следует инициализировать аппаратный таймер, чтобы получить шим сигнал. В коде выше используется автоповторение.
Переменная req задает режим работы таймера, однократный или повторяющийся.
Как я понимаю, для организации режима ШИМ необходимо в секции setup() единоразово запустить таймер, а далее в обработчиках прерывания от этого таймера инициализировать таймер противоположными значениями времени и изменять состояние флага для организации ШИМ. А в основном цикле уже по флагу переключать вывод GPIO.
Также смотрел на форуме реализации диммеров и не могу понять, как рассчитывают длительность требуемой задержки включения симистора. Вот ссылка на тему https://esp8266.ru/forum/threads/up...tjazhnogo-ventijaltora.4115/page-3#post-59600
Вот инициализация таймера в прерывании по переходу через "0"
Почему умножают на 30 и прибавляют 400.
Если судить по логике работы функции hw_timer_arm в нее необходимо передать значение в микросекундах.
Следовательно, для организации диммирования необходимо в эту функцию передавать значения от 50 мкс до 10000 мкс
Также имеет ли смысл рулить выходным пином в основном цикле, или можно сделать смену состояния пина в обработчиках прерываний?
Разбираюсь с работой аппаратного таймера ESP. Сделал простую программу, которая тикает каждую секунду и осуществляет вывод в UART.
Код:
#include "user_interface.h"
#include "hw_timer.h"
bool tickOccured;
void hw_test_timer_cb() {
tickOccured = true;
}
void ICACHE_FLASH_ATTR user_init(void) {
// hw_timer_init(NMI_SOURCE, 1);
hw_timer_init(FRC1_SOURCE, 1);
hw_timer_set_func(hw_test_timer_cb);
hw_timer_arm(1000000);
} // End of user_init
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println();
Serial.println("");
Serial.println("--------------------------");
Serial.println("ESP8266 Timer Test");
Serial.println("--------------------------");
tickOccured = false;
user_init();
}
void loop() {
if (tickOccured == true)
{
Serial.println("Tick Occurred");
tickOccured = false;
}
yield(); // or delay(0);
//system_soft_wdt_feed();
} //end loop
Код:
void ICACHE_FLASH_ATTR hw_timer_init(frc1_timer_source_type source_type, uint8_t req)
{
if (req == 1) {
RTC_REG_WRITE(FRC1_CTRL_ADDRESS,
FRC1_AUTO_LOAD | DIVDED_BY_16 | FRC1_ENABLE_TIMER | TM_EDGE_INT);
} else {
RTC_REG_WRITE(FRC1_CTRL_ADDRESS,
DIVDED_BY_16 | FRC1_ENABLE_TIMER | TM_EDGE_INT);
Как я понимаю, для организации режима ШИМ необходимо в секции setup() единоразово запустить таймер, а далее в обработчиках прерывания от этого таймера инициализировать таймер противоположными значениями времени и изменять состояние флага для организации ШИМ. А в основном цикле уже по флагу переключать вывод GPIO.
Также смотрел на форуме реализации диммеров и не могу понять, как рассчитывают длительность требуемой задержки включения симистора. Вот ссылка на тему https://esp8266.ru/forum/threads/up...tjazhnogo-ventijaltora.4115/page-3#post-59600
Вот инициализация таймера в прерывании по переходу через "0"
Код:
int dimDelay = 30 * (255 - curDimmerVal) + 400;//400
hw_timer_arm(dimDelay);
Если судить по логике работы функции hw_timer_arm в нее необходимо передать значение в микросекундах.
Следовательно, для организации диммирования необходимо в эту функцию передавать значения от 50 мкс до 10000 мкс
Также имеет ли смысл рулить выходным пином в основном цикле, или можно сделать смену состояния пина в обработчиках прерываний?