2017-02-16 2 views
1

Я бегу на микроконтроллере STM32F0xx, и у меня есть следующий код, который просто переключает штырь, используя задержки блокировки (да, я знаю, что задержки блокировки плохие, а не точки здесь).Задержки блокировки STM32 несовместимы с прерываниями отключены

uint32_t ticks = 0; 
// Disable interrupts 
__disable_irq(); 
for (int bit = 0; bit < 10; bit++) { 
    // Toggle pin high 
    WritePin(GPIO_PIN_SET); 
    ticks = 500; 
    while (ticks--) { 
    __NOP(); 
    } 
    // Toggle pin low 
    WritePin(GPIO_PIN_RESET); 
    ticks = 500; 
    while (ticks--) { 
    __NOP(); 
    } 
    // Repeat 
    WritePin(GPIO_PIN_SET); 
    ticks = 500; 
    while (ticks--) { 
    __NOP(); 
    } 
    WritePin(GPIO_PIN_RESET); 
    ticks = 500; 
    while (ticks--) { 
    __NOP(); 
    } 
} 
__enable_irq(); 

Отключить прерывания, чтобы убедиться, что в этот момент ничего не происходит. Когда я использую эти формы сигнала, я вижу 10 периодов синхронизации; однако периоды этих осциллограмм не совпадают. Все четные формы волны (0,2,4,6,8) имеют одинаковый период, и все нечетные формы волны (1,3,5,7,9) имеют одинаковый период, но четные и нечетные формы колебаний различаются на значительную величину (% 12). Четные осциллограммы коррелируют с первой задержкой переключения и нечетны ко второму в цикле for. Я не знаю, почему они будут отличаться по времени. У кого-нибудь есть понимание?

+0

Я также проверил разборку, и сборка выглядит идентичной для всех реализаций цикла while. – ryeager

ответ

3

Смотрите эту документацию о NOP на ядре ARM Cortex-M0:

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/CHDJJGFB.html

Операция

NOP не выполняет никаких операций и не гарантируется отнимает много времени. Процессор может удалить его из конвейера, прежде чем он достигнет этапа выполнения .

Используйте NOP для заполнения, например, для размещения последующих инструкций на 64-битной границе.

К этому необходимо добавить другие переменные факторы, как заправку трубопровода (за счет ветвления) и флэш-WAIT-состояния (изменения, так как блоки команд в разных циклах может не быть выровнены идеально подходит для флэш-ускорителя).

Единственный надежный способ выполнения точных задержек - использовать таймер.

Смежные вопросы