• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Вопрос Счетчик микросекунд

Br.Misha

New member
Здравствуйте!
Нужно нужно зафиксировать время от начала некоторого события до появления положительного сигнала на ножке (10-100 микросекунд).
Скажите, пожалуйста, есть ли у ESP какие-то счетчики для таких целей? Таймеры ОС здесь явно не помогут))).

Спасибо!
 

pvvx

Активный участник сообщества
Здравствуйте!
Нужно нужно зафиксировать время от начала некоторого события до появления положительного сигнала на ножке (10-100 микросекунд).
Скажите, пожалуйста, есть ли у ESP какие-то счетчики для таких целей? Таймеры ОС здесь явно не помогут))).

Спасибо!
uint32 phy_get_mactime(void); // в us (читает младшие 32 бита 64-х битного аппаратного счетчика)
Запоминаете и делаете разницу с новым значением.
Если надо больший период, например в сутках с дискретом в us, то:
Код:
#define MAC_TIMER64BIT_COUNT_ADDR 0x3ff21048
uint64 ICACHE_FLASH_ATTR get_mac_time(void)
{
    union {
        volatile uint32 dw[2];
        uint64 dd;
    }ux;
    volatile uint32 * ptr = (volatile uint32 *)MAC_TIMER64BIT_COUNT_ADDR;
    ux.dw[0] = ptr[0];
    ux.dw[1] = ptr[1];
    if(ux.dw[1] != ptr[1]) {
        ux.dw[0] = ptr[0];
        ux.dw[1] = ptr[1];
    }
    return ux.dd;
}
get_mac_time() - показывает время со старта модуля в us - читает полный аппаратный счетчик с учетом перехода старшего слова во время считывания...
uint32 system_get_time(); - аналог phy_get_mactime(), но прибавляет значение uint32 WdevTimOffSet.
 
Последнее редактирование:

vad7

Active member
у меня mac_time не работал на время запрещенных прерываний, разбираться особо не стал, использую system_get_time.
 

pvvx

Активный участник сообщества
у меня mac_time не работал на время запрещенных прерываний, разбираться особо не стал, использую system_get_time.
Чудеса в решете:
Код:
system_get_time:
    l32r            a3, a_WdevTimOffSet
    l32r            a2, dw0x3FF20A00
    l32i.n          a3, a3, 0
    memw
    l32i            a2, a2, 0x200    ; 0x3FF20C00
    add.n           a2, a2, a3
    ret.n

phy_get_mactime:
    l32r            a2, dw0x3FF20A00
    memw
    l32i            a2, a2, 0x200    ; 0x3FF20C00
    ret.n
Найдите различие. :) Оно в описанном ранее - system_get_time длиннее и прибавляет китайскую константу WdevTimOffSet...
А вот get_mac_time() и ets_intr_lock() :
Код:
           union {
                    uint32 dw[2];
                    uint64 dd;
                }ux;
             ets_intr_lock();
             ux.dd = get_mac_time();
             volatile uint32 x = 1024;
             while(x--);
             ux.dd = get_mac_time() - ux.dd;
             ets_intr_unlock();
             tcp_puts("0x%08x%08x", ux.dw[1], ux.dw[0]);
CONNECT: ws://192.168.4.1/web.cgi
CONNECTED
SEND TEXT: sys_test
RECEIVED TEXT: 0x000000000000002d
CLOSED: (1000)
 
Последнее редактирование:

gerkimuyda

New member
О, как раз собирался писать свою функцию, чтобы решить ограничения с переполнением uint32 system_get_time()
( system_get_time() и micros() переполняются каждые 72 минуты, а millies() - 49 дней)
Так что - апну тему ;), пригодилась.
 
Сверху Снизу