Имхо, если в программе есть прерывания, то все эти суперточные задержки превращаются в тыкву. А прерывания есть в любой мало-мальски сложной программе.
Обычно при особых требованиях задержки генерируются программно. При подобном подходе естественно запрещаются ВСЕ прерывания на время генерации критичных временных интервалов. Дополнительная проблема - учет неравноценности времени обработки команд условного перехода в конце счетного цикла. И добавок в виде оценки условий при исполнении нескольких циклов в едином алгоритме. Как пример особо жесткого подхода к равнозначности серии временных интервалов при дополнительной оценке условий выполнения циклов - программная реализация протокола обмена для светодиодов типа WS2812 (выполнена как элемент - заготовка библиотеки): Спойлер; ; ; trd2812_m.txt ; ; файл обработчика передачи массива ; из буфера вывода в линейку на основе WS2812B ; базовый МК из линейки АТМЕЛ при тактовой частоте ; от 16 Мегагерц ( 0,000000062 S) ; ; требуемые интервалы по даташиту WS2812B ; ;Data transfer time( TH+TL=1.25µs±600ns) ; T0H 0 code ,high voltage time 0.4us ±150ns ; T1H 1 code ,high voltage time 0.8us ±150ns ; T0L 0 code ,low voltage time 0.85us ±150ns ; T1L 1 code ,low voltage time 0.45us ±150ns ; RES low voltage time Above 50µs ; исходный уровень линии связи = 0 ; данные передаются пакетами из трех байт на точку ; старшими битами вперед в последовательности ; соответствующей G - R - B цветам точки ; количество блоков должно соответствовать ; количеству точек в ленте ; ; реальные данные согласно тест - отладки дебаггером (версия1!) ; авр-студио 4.19 ; ; Data transfer time( TH+TL=1.38µs -10ns) ; T0H 0 code ,high voltage time 0.44us ±10ns ; T1H 1 code ,high voltage time 0.88us ±10ns ; T0L 0 code ,low voltage time 0.94us ±10ns ; T1L 1 code ,low voltage time 0.50us ±10ns ; RES low voltage time 192,88uS (Above 50µs) ; ; длина прерывания с пакетом загрузки (x60*3) = 2175uS (0.002175) ; интервал между прерываниями (irq t/c0) = 0.004S (4000uS) ; ; define datas ; .equ port_out = PORTB ; порт вывода (по усмотрению) ; .equ out_line = 0 ; линия вывода данных ; .equ bufout = SRAM_START ; начальный адрес буфера вывода ; .equ pixel = 60 ; количество точек в линейке/ленте ; .equ bufout_size = (pixel * 3) ; не может быть более объема ОЗУ - стек!!!
.cseg .org 0x0020 ; старовая позиция 0х0020 !!! slot0: ; 6/14 (6-4=2 посему роль остатка выполняет CBI) cbi port_out,out_line ; 2 цикла nop nop nop nop nop nop nop nop nop ret ; 4 цикла .org (slot0+16) slot1: nop ; 13/7 (13-4=9) nop nop nop nop nop nop cbi port_out,out_line ; 2 цикла nop nop ret ; 4 цикла .org 0x0060 xslot0: ; 6/14 (6-5=1 посему роль остатка выполняет CBI с избытком в 1 nop) cbi port_out,out_line ; 2 цикла cbr zl,(1<<6) ; модификация указателя 1 цикл nop nop nop nop nop nop ; -2 цикла на ld tmp0,x+ dec tmp1 ; 1 цикл brbs SREG_Z,ends_trd ; 1 цикл при неисполнении (в цикле) rjmp trasstt ; 2 цикла .org (xslot0+16) xslot1: nop ; 13/7 (13-5=8) cbr zl,(1<<6) ; модификация указателя 1 цикл nop nop nop nop nop cbi port_out,out_line ; 2 цикла ; -2 цикла на ld tmp0,x+ dec tmp1 ; 1 цикл brbs SREG_Z,ends_trd ; 1 цикл при неисполнении (в цикле) rjmp trasstt ; 2 цикла ; ends_trd: pop tmp0 pop tmp1 pop xl pop xh pop zl pop zh ; восстановить рабочую область из стека ret ;---------- ; ; предварительно: ; линия out_line настроена на вывод ; исходный уровень out_line =0 ; указатель стека усатновлен на RAMEND ; массив данных (bufout:bufout_size) предварительно загружен ; флаг готовности массива данных установлен ; mass_trm: push zh push zl push xh push xl push tmp1 push tmp0 ; храним рабочую область в стеке res_line: ldi tmp0,4 ser tmp1 cbi port_out,out_line res_time: dec tmp1 brne res_time dec tmp0 brne res_time ; =>50uS time out ldi xh,high (bufout) ldi xl,low (bufout) ; загрузка начального адреса массива ; в указатель ldi tmp1,bufout_size ldwi z,slot0 ; адрес начала таблицы в указателе ;---------- trasstt: ld tmp0,x+ ; 2 цикла slot_0: sbi port_out,out_line ; 2 цикла реально до установки 3 цикла bst tmp0,7 ; 1 цикл bld zl,4 ; 1 цикл icall ; 3 цикла = 4 цикла от out_line=1 ;---------- slot_1: sbi port_out,out_line bst tmp0,6 ; 1 цикл bld zl,4 ; 1 цикл icall ; 3 цикла ;---------- slot_2: sbi port_out,out_line bst tmp0,5 ; 1 цикл bld zl,4 ; 1 цикл icall ; 3 цикла ;---------- slot_3: sbi port_out,out_line bst tmp0,4 ; 1 цикл bld zl,4 ; 1 цикл icall ; 3 цикла ;---------- slot_4: sbi port_out,out_line bst tmp0,3 ; 1 цикл bld zl,4 ; 1 цикл icall ; 3 цикла ;---------- slot_5: sbi port_out,out_line bst tmp0,2 ; 1 цикл bld zl,4 ; 1 цикл icall ; 3 цикла ;---------- slot_6: sbi port_out,out_line bst tmp0,1 ; 1 цикл bld zl,4 ; 1 цикл icall ; 3 цикла ;---------- slot_7: sbi port_out,out_line sbr zl,(1<<6) ; модификация указателя под завершающий фрагмент ; 1 цикл bst tmp0,0 ; 1 цикл bld zl,4 ; 1 цикл ijmp ; 3 цикла ;---------- естественно прерывания на время выполнения загрузки массива должны быть запрещены.
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Подскажите примером как правильно на ассемблере забрать значения с регистров ADCH и ADCL и присвоить полученное значение регистру R16. При условии что выравнивания по левому краю установлено в настройках. На СИ нашел вроде так делается: v=(ADCL|ADCH<<8); а как на ассемблере.
так там v 16 битная... а утебя R16 восмибитный, так что выбирай какие биты ADC тебе нужны, если старшие то сначала прочитай в него ADCL, а потом в него же ADCH (старое значение затрется и останутся только старшие 8 бит)
Добавлено after 1 minute 42 seconds: на С часто делается v=ADC; остальное уже сам компилятор разберёт.
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
возможно, просто есть ряд 16битных регистров (у таймеров точно) при чтении (или записи) одного бита второй блокируется, чтобыпрочитано было именно то что было в регистре (а то пока читал один бит - регистр изменился и в результате получим хвост павлиний, рога оленьи - в смысле от совершенно разных значений)
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Если я правильно понял то можно прост считать ADCH после установки ADLAR. а ADCL можно вообще не трогать.
скорее всего да, ну если не взлетит - знаешь куда копать.
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
С АЦП такой проблемы нет, произвольно читай регистры. Он не меняется каждый такт и поэтому нет проблемы синхронного чтения двух байт. Пожалуй, с АЦП надо специально расставить и зарядить грабли чтобы прочитать старший байт от одной выборки а младший от другой. Темболее когда стоит выравнивание по старшей стороне и используется только 8 бит.
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
т.е. ADCL без ADCH читать нельзя, а наоборот можно, понятно. (я всегда старался читать всё, так, на всякий случай)
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Кстати, если речь идёт об avr-gcc, если нужна вся 10-битная точность, то есть ещё способ - читать сразу ADCW в 16-битную переменную. Если же 8 бит достаточно, то да, проще всего читать ADCH, с установленным выравниванием результата влево.
Подскажите кому не трудно что не так на схеме в протеусе, так как двигаю ползунок переменного резистора и нечего не происходит. В начальный момент времени Шим сигнал выставляется по умолчанию его скважность, А потом изменения скважности постоянны и на ползунок не реагируют?
Спойлер
Код:
.include "tn13Adef.inc"; Header files .list; // Отоброжения листинга исполнения команды. .cseg; работаем с програмной памятью а не озу или eeprom .org 0; устанавливаем начальную позицию строки rjmp START; Reset Handler rjmp START; IRQ0 Handler rjmp START;; PCINT0Z Handler rjmp START3; Timer0 Overflow Handler rjmp START; EEPROM Ready Handler rjmp START; Analog Comparator Handler rjmp START; TIM0_COMPA CompareA Handler rjmp START; Timer0 CompareB Handler rjmp START; Watchdog Interrupt Handler rjmp start3; ADC Conversion Handler
start3: CLV; //Считываем данные АЦП in R16, ADCL; //Записываем считанные данные в регистр. out OCR0A, R16; reti;
START: // команда запрещает глобальные прерывания. CLI; //инициализация стэка.(установка максимально размера ОЗУ); ldi R17, RAMEND; out SPL, R17;
//Выбираем коэфициент пределителя тактовой частоты АЦП при расчете что частота 9,6/8=1,2 Мгц; 1200/8=150; где 8 выбранный коэфициент //Запрещаем прерывание от компоратора ADIE LDI R16,(0<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(0<<ADIE); out ADCSRA, R16; //Включаем аналогово-цифровой преобразователь SBI ADCSRA, ADEN; //Режим работы выставляем непрерывное преобразования SBI ADCSRA, ADATE;
LDI R16,(0<<ADTS2)|(0<<ADTS1)|(0<<ADTS0); out ADCSRB, R16; //Выбираем ножку мк которая будет производить измерения ADC1 LDI R16, (0<<MUX1)|(1<<MUX0); out ADMUX, R16; //Делаем выравнивания по левому краю для считывания ADCH. SBI ADMUX, ADLAR; //Выбираем напряжение питание микроконтролера, ставим питания от ИОН. SBI ADMUX, REFS0;
//Запуск преобразования SBI ADCSRA, ADSC; //Оставляем работу ножки МК как на вход для измерения сигнала CBI DDRB, DDB0; CBI PORTB, PB0;
//Подключаем таймер в режиме FAST PWM - шИМ сигнала с установленным верхним значением OCR0A LDI R16, (1<<WGM01)|(1<<WGM00)|(1<<COM0A1)|(0<<COM0A0); OUT TCCR0A,R16; //Определяем состояение выводов OCOA - не инвертирующий шим как на выход. SBI DDRB, DDB0; SBI PORTB, PB0; /*Скорость работы таймера выбираем СК/1024 - где СК - частота работы микроконтролера в нашем случаи мы выставляем во fuces clkdiv8 что обеспечит нам частоту 9,6Мhz/8=1,2Mhz значит скорость работы таймера будет 1,2Mhz/1024=1,17Khz что увеличивает счет значения. Чем меньше частота тем большее время срабатывания прерывания*/ ldi R16, (1<<CS02)|(0<<CS01)|(1<<CS00)|(0<<WGM02); out TCCR0B, R16; //Прерывания от переполнения таймера ldi R16, (1<<TOIE0); out TIMSK0, R16;
(подсказка) пятью постами выше ссылка за стенку со стреляющими граблями это твой случай
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Сейчас этот форум просматривают: Martian, veso74 и гости: 45
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения