Я хочу сделать очень короткий импульс после входного сигнала восходящего фронта.Точные задержки на Arduino, используя nop-сборку?
Жесткая часть здесь заключается в том, что я хотел бы контролировать (до высокого разрешения) время задержки перед моим импульсом и длительность моего импульса. Я могу легко контролировать это, просто набирая nops самостоятельно, жесткие задержки кодирования, но я не уверен, как это сделать для некоторой произвольной задержки с одинаковым уровнем точности.
После многих головных болей, преследующих таймеров, а затем, в конце концов, понимая, что я в конечном счете ограничен временным временем входа/выхода в режиме interupt, я теперь решаюсь, пытаясь контролировать свою задержку через nops.
Я предположил, что это C переключатель заявление было бы то, что я хотел (после компиляции, в надежде, что это станет эффективным и просто изменить счетчик программы в нужном месте), но он производит некоторые очень странное поведение ...
switch(delayTime){ case 10: __asm__ __volatile__("nop"); case 9: __asm__ __volatile__("nop"); case 8: __asm__ __volatile__("nop"); case 7: __asm__ __volatile__("nop"); case 6: __asm__ __volatile__("nop"); case 5: __asm__ __volatile__("nop"); case 4: __asm__ __volatile__("nop"); case 3: __asm__ __volatile__("nop"); case 2: __asm__ __volatile__("nop"); case 1: __asm__ __volatile__("nop"); } PORTD = 0x10; ...
в идеале, я хотел бы в основном работать через некоторый код, который будет компилировать в этом: (это какой-то странный psuedocode с и сборки, до сих пор не знаю, как сделать некоторые из них в сборке)
0x005 Reg1 = 0xFF-val1 %(where somehow 0xFF is known?/found out?) 0x006 Reg2 =0x1FF-val2 0x007 IJMP Reg1 0x008 NOP 0x009 NOP 0x00A NOP ... 0x0FF MOV 0x40, PORTD % assign the value 0x40 to the static variable "PORTD" 0x100 IJMP Reg2 0x101 NOP 0x102 NOP 0x103 NOP 0x104 NOP ... 0x1FF MOV 0x00, PORTD % assign the value 0x00 to the static variable "PORTD"
Я просто не уверен, как найти место памяти для кода после/во время выполнения, так что аспекты «0xFF» и «0x1FF» этой программы не так уж плохи (кажется, что это супер опасно просто, получите сборку кода, а затем жесткий код, который в ... Я бы не хотел этого делать). Кроме того, в то время как легко просто налить его на 200+ nops, как заставить командлет IJMP вести себя так, как я этого хочу? (Я, честно говоря, даже не знаю, нужна ли мне такая команда).
Я предполагаю, что в общем, я ищу команду сборки (которую я не могу найти), которая позволяет мне «добавить N на счетчик программ », и я могу просто убедиться, что эта команда запущена в сборе с по меньшей мере N + 1 командами сборки впереди, жестко закодирована.
В качестве побочного примечания все это выполняется внутри прерывание, поэтому я не чувствую себя так плохо, чтобы играть с ПК ... Кроме того, я знаю, что это плохое блокирование до 500 операций, но для этой задачи время важнее, чем плохо блокирует как рутину.
Что случилось с процедурами задержки в AVR Libc? –
Чтобы получить точность, которую я хочу, я думаю, что мне нужно использовать что-то вроде «__builtin_avr_delay_cycles». Однако для этой функции требуется константа (это макрос, который, кажется, создается во время компиляции), в то время как вместо этого я ищу какую-то функцию, которая Я могу позвонить с переменной во время выполнения. Насколько я могу судить, простое перемещение ПК в память, чтобы получить точное количество nops, является самым надежным решением, но, возможно, я пропустил что-то в AVR libc. (Я вижу только способы сделать 3,4 цикла на итерацию), что недостаточно для разрешения времени на то, что я хочу, из этих 16 МГц часов. – BlueCoconut