Генерация наносекундной задержки в C на STM32
3 ответа
Использование stopwatch_delay(ticks
) ниже, чтобы выполнить ваши задержки. Он использует регистр STT32 DWT_CYCCNT, который специально разработан для подсчета фактических тактов, расположенных по адресу 0xE0001004.
Чтобы проверить точность задержки (см. main
), ты можешь позвонить STOPWATCH_START
, бежать stopwatch_delay(ticks)
затем позвоните STOPWATCH_STOP
и проверить с CalcNanosecondsFromStopwatch(m_nStart, m_nStop)
, регулировать ticks
по мере необходимости.
uint32_t m_nStart; //DEBUG Stopwatch start cycle counter value
uint32_t m_nStop; //DEBUG Stopwatch stop cycle counter value
#define DEMCR_TRCENA 0x01000000
/* Core Debug registers */
#define DEMCR (*((volatile uint32_t *)0xE000EDFC))
#define DWT_CTRL (*(volatile uint32_t *)0xe0001000)
#define CYCCNTENA (1<<0)
#define DWT_CYCCNT ((volatile uint32_t *)0xE0001004)
#define CPU_CYCLES *DWT_CYCCNT
#define STOPWATCH_START { m_nStart = *((volatile unsigned int *)0xE0001004);}
#define STOPWATCH_STOP { m_nStop = *((volatile unsigned int *)0xE0001004);}
static inline void stopwatch_reset(void)
{
/* Enable DWT */
DEMCR |= DEMCR_TRCENA;
*DWT_CYCCNT = 0;
/* Enable CPU cycle counter */
DWT_CTRL |= CYCCNTENA;
}
static inline uint32_t stopwatch_getticks()
{
return CPU_CYCLES;
}
static inline void stopwatch_delay(uint32_t ticks)
{
uint32_t end_ticks = ticks + stopwatch_getticks();
while(1)
{
if (stopwatch_getticks() >= end_ticks)
break;
}
}
uint32_t CalcNanosecondsFromStopwatch(uint32_t nStart, uint32_t nStop)
{
uint32_t nDiffTicks;
uint32_t nClkTicksPerMicrosec;
nDiffTicks = nStop - nStart;
nDiffTicks *= 1000; // Scale diff by 1000.
nClkTicksPerMicrosec = SystemCoreClock / 1000000; // Convert (clkTicks/sec) to (clkTicks/microsec), SystemCoreClock = 168000000
return nDiffTicks / nClkTicksPerMicrosec; // nanosec = (ticks * 1000) / (clkTicks/microsec)
}
void main(void)
{
int timeDiff = 0;
stopwatch_reset();
STOPWATCH_START;
run_my_function();
STOPWATCH_STOP;
timeDiff = CalcNanosecondsFromStopwatch(m_nStart, m_nStop);
printf("My function took %d nanoseconds\n", timeDiff);
}
Первая найденная мной спецификация Stm32f2 предполагает тактовую частоту 120 МГц. Это около 8 нс за такт. Вам понадобится около трех команд одного цикла между последовательными операциями записи или чтения / записи. В С, a++;
вероятно будет делать (если находится в стеке).
Вы должны посмотреть на периферийные устройства FSMC, имеющиеся в вашем чипе. Хотя конфигурация может быть сложной, особенно если вы не добавляете часть памяти, для которой она была разработана, вы можете обнаружить, что ваше устройство с параллельным интерфейсом довольно хорошо отображает один из режимов интерфейса памяти.
Эти виды контроллеров внешней памяти должны иметь множество настраиваемых опций синхронизации, чтобы поддерживать диапазон различных микросхем памяти, чтобы вы могли гарантировать время, требуемое вашей таблицей данных.
Приятным преимуществом этой возможности будет то, что ваш ЖК-дисплей будет похож на любое старое периферийное устройство с отображенной памятью, абстрагируя детали интерфейса нижнего уровня.