Как принять сигнал с приемника в AVR (PWM|Digital)
Сейчас нашел в интернете
Документация по таймеру на ардуино
Документация по прерываниям на ардуино
Пытаюсь понять исходники библиотеки servo, немного не хватает знаний. Не пойму какие таймеры использует эта библиотека?
не успел нажать на кнопку спасибо за ссылки. хоть так нажму.
Длина импульса 2.1 мс, минимум 0.8 мс Кто что еще подскажет?
У моих дистух заявлены длины импульсов у одной 1000-2000мс а у другой 1200-2400 )) итого - надо настраиваться на передатчик …
0.8 - 2.4милисек или 800-2400микро сек (в зависимости кому в чем удобнее…) наверное в целых числах правильнее в принципе если удалить нолик и принять все более мелкие колебания за шум, то можно поместиться в один байт (int) … получается точность позиции один градус для сервы, и вдвое меньше на стиках, на сколько вероятно что на столько точные движения на пальцАх? к тому же по любому импульсы дрожат, ну никак не получаются точной длины даже если не трогать стики…
Нафига синхронизация между ними?
По большому счету нафиг не нужна, но для порядка! опять же при синхронизированной паре можно достаточно точно отследить момент когда пора быть посылке, и даже делать попытки восстановления частично потеряного сигнала, к тому же можно оперативно делать правильные выводы о потере связи …
Возможность подключения дисплея к устройству для использования его в качестве тахометра, и для настройки устройства.
На арду есть готовая либа частотомер )) считает встроенным 16 бит таймером-счетчиком напрямую до 8 Мгц только в путь… чем не тахометр? периодичность чтения задается вторым таймером и перемножается на коэффициэнт пересчета, на ЛСД выводится разумеется уже так как попросишь…
Настраиваем таймер так, чтобы он выдавал прерывания каждую (2мс-1мс)/256. 2мс общая длина импульса, 1мс длительность сигнала до начала отсчета.
Как то не серьйозно это, с таким успехом можно и в loop читать состояние всех портов и не задумываться об остальном… Прерывания хороши какраз тем, что бездельника - ЦПУ зовут только когда он нужен… а в остальное время хоть в спячку пусть идет, заодно и кушать будет меньше 😉
Если я повешу первый обработчик на INT0 (PD2) а второй на PCINT2, и у меня придет сигнал на PD2, то сработают оба прерывания?
Сработают. при этом если запросы пришли одновременно то(на примере ATmega128 проц):
“Меньшие адреса обладают более высоким уровнем приоритетом. Сброс (RESET) имеет наивысший приоритет, за ним следует INT0 – запрос на внешнее прерывание по входу INT0.”
непосредственный и весьма полезный источник - www.gaw.ru/html.cgi/txt/doc/micros/avr/…/1_2.htm (ближе к концу текста)
Полный перечень векторов приведен к примеру тут же www.gaw.ru/html.cgi/txt/doc/micros/avr/…/6.htm
При вызове обработчика прерывания, пока выполняется одно прерывание все остальные прерывания запрещаются, при reti автоматически разрешаются…
Как то не серьйозно это, с таким успехом можно и в loop читать состояние всех портов и не задумываться об остальном… Прерывания хороши какраз тем, что бездельника - ЦПУ зовут только когда он нужен… а в остальное время хоть в спячку пусть идет, заодно и кушать будет меньше
Я написал маленькую библиотечку (смотри вложение выше). Там все нормально работает. Не напрягаясь читает 4 канала. Использует только одно прерывание PCINT. Не использует таймер. Перед чтением данных, надо вызвать функцию read. Эта функция записывает актуальные данные в массив. А потом читаем из массива показания. Как только появится немного времени, приведу её в божеский вид.
Я написал маленькую библиотечку
я ее уже взял, но пока не разглядывал… все равно в ближайших планах было разобраться с этой задачей, так что тоже покопаюсь…
скорее бы до планов добраться …
Я раньше тоже заморачивался с чтением отдельных каналов и решил взять отдельно PPM из приемника и по одному входу считывать данные для восьми каналов.
Ниже готовый скетчь для моей АрдуиныМега, там стоит АтМега 1280, но кому интересно, может переделать, но данные как вкопанные.
#include <TimerOne.h>
volatile uint16_t timerCount; // переменная счетчика
#define BTNPIN 2 //Входной сигнал PPM на 2 пине
int ppmImpuls[9]; // Массив импульсов для паузы и 8 каналов
int chImpuls[9] = {1000, 100, 100, 100, 100, 100, 100, 100, 100}; // Массив средних значений для паузы и 8 каналов
int chanel = 0 ; // Номер канала
int upImpuls = 50; // Положительный импульс
int Error = 2 ; // Переменная ошибок. 0 - помеха, 1 - длинная пауза, 2 - хороший сигналvoid setup()
{
Serial.begin(115200);
pinMode (BTNPIN, INPUT);
Timer1.initialize(10);
Timer1.attachInterrupt(callback);
attachInterrupt(0, impDown, RISING);
}void loop()
{
for (int i=0; i <= 8; i++)
{
chImpuls[i] = (3 * chImpuls[i] + ppmImpuls[i]) / 4 ; // усреднение 4 импульсов
Serial.print(“CH”); Serial.print(i); Serial.print(“=”); Serial.print(chImpuls[i]);
Serial.print(" I=“); Serial.print(upImpuls); Serial.print(” “);
}
Serial.println(”");
}void callback() { timerCount++; } //--------- Счетчик------------
void impUp() //---------- Функция обработки положительного импульса
{
detachInterrupt(0) ;
upImpuls = timerCount ;
if ( upImpuls > 43 && upImpuls < 51) { Error = 2 ; } else { Error = 0 ; delay(50) ; chanel = 0 ; }
timerCount = 0 ;
attachInterrupt(0, impDown, RISING);
}void impDown() // Функция обработки отрицательного импульса
{
int ppm = timerCount;
detachInterrupt(0);
if( ppm > 400 ) { chanel = 0 ; } else { chanel ++ ; }
ppmImpuls[chanel] = ppm ;
timerCount=0;
attachInterrupt(0, impUp, FALLING);
}
А для чего используешь такое “хитрое” переназначение вектора прерывания да еще и внутри каждого обработчика?
detachInterrupt/attachInterrupt; Как то не айс, может как то попытать вроде такого?:
int Int0Pin=2;
void setup()
{
…
…
attachInterrupt(0, AllPulse, CHANGE);
}
Void AllPulse()
{
TimeInt = timerCount;
timerCount=0;
IF( digitalRead(Int0Pin) > 0)
{
impUP()
}
else
{
impDown()
}
}
void impUp() //---------- Функция обработки положительного импульса
{
upImpuls = timeInt ;
if ( upImpuls > 43 && upImpuls < 51) { Error = 2 ; } else { Error = 0 ; delay(50) ; chanel = 0 ; }
}
void impDown() // Функция обработки отрицательного импульса
{
int ppm = timeInt;
if( ppm > 400 ) { chanel = 0 ; } else { chanel ++ ; }
ppmImpuls[chanel] = ppm ;
}
Напишите окончательный скетчь для получения значений каждого канала. Ваш вариант с функцией IF( digitalRead(Int0Pin) > 0) не устраивает самой функцией, которая только условно стабильна. Попробуйте мой и сравните со своим, в жизни, но не на эмуляторах.
Напишите окончательный скетчь для получения значений каждого канала. Ваш вариант с функцией IF( digitalRead(Int0Pin) > 0) не устраивает самой функцией, которая только условно стабильна. Попробуйте мой и сравните со своим, в жизни, но не на эмуляторах.
Не знаю что нестабильного в чтении состояния, пока еще ни разу жаловаться не приходилось. единственно внутри IF чтение мне самому не очень нравится, надежнее бы промежуточную переменную использовать, но как правило и так работает…
Пробовать буду, но немного поздже 😉
Да нет, я немного о другом, что будет в главном цикле, а тут только одноразовый запуск прерывания без его отключения. Если его не сделать, то много функций перестанут работать правильно.
У меня одновременно с чтением PPM идет сбор данных с GPS, управление сервами и много-много всего другого где есть и работа с 2 портами и micros() и delayMicroseconds().
Для справочки по прерыванию
Замечание по использованию
Внутри функции обработки прерывания не работает delay(), значения возвращаемые millis() не изменяются. Возможна потеря данный передаваемых по последовательному соединению (Serial data) в момент выполнения функциии обработки прерывания. Переменные, изменяемые в функции, должным быть объявлены как volatile.
Полное описание arduino.ru/Reference/AttachInterrupt
Поэтому после измерения длительности, я отключаю прерывания, а потом снова включаю.
Вот данные на ком-порту
CH0-пауза между пакетами
I-импульс между каналами
CH1-CH8 - соответственно сами каналы.
CH0=1035 I=46 CH1=101 I=46 CH2=98 I=46 CH3=106 I=46 CH4=101 I=46 CH5=48 I=46 CH6=101 I=48 CH7=94 I=47 CH8=104 I=47
CH0=1035 I=48 CH1=101 I=47 CH2=98 I=47 CH3=106 I=47 CH4=101 I=46 CH5=48 I=46 CH6=101 I=46 CH7=94 I=46 CH8=104 I=46
CH0=1035 I=46 CH1=101 I=46 CH2=98 I=48 CH3=106 I=47 CH4=101 I=47 CH5=48 I=47 CH6=101 I=47 CH7=94 I=46 CH8=104 I=47
CH0=1035 I=46 CH1=101 I=46 CH2=98 I=46 CH3=106 I=46 CH4=101 I=46 CH5=48 I=46 CH6=101 I=48 CH7=94 I=48 CH8=104 I=48
CH0=1035 I=48 CH1=101 I=47 CH2=98 I=47 CH3=106 I=46 CH4=101 I=47 CH5=48 I=47 CH6=101 I=47 CH7=94 I=47 CH8=104 I=47
CH0=1035 I=46 CH1=101 I=46 CH2=98 I=47 CH3=106 I=48 CH4=101 I=48 CH5=48 I=47 CH6=101 I=47 CH7=94 I=46 CH8=104 I=46
CH0=1035 I=47 CH1=101 I=47 CH2=98 I=47 CH3=106 I=47 CH4=101 I=47 CH5=48 I=47 CH6=101 I=48 CH7=94 I=48 CH8=104 I=47
CH0=1035 I=47 CH1=101 I=47 CH2=98 I=47 CH3=106 I=46 CH4=101 I=46 CH5=48 I=46 CH6=101 I=46 CH7=94 I=46 CH8=104 I=46
CH0=1035 I=46 CH1=101 I=46 CH2=98 I=48 CH3=106 I=48 CH4=101 I=47 CH5=48 I=47 CH6=101 I=46 CH7=94 I=47 CH8=104 I=46
CH0=1035 I=46 CH1=101 I=46 CH2=98 I=46 CH3=106 I=46 CH4=101 I=46 CH5=48 I=46 CH6=101 I=48 CH7=94 I=47 CH8=104 I=47
CH0=1035 I=47 CH1=101 I=47 CH2=98 I=46 CH3=106 I=47 CH4=101 I=46 CH5=48 I=46 CH6=101 I=46 CH7=94 I=46 CH8=104 I=46
CH0=1035 I=46 CH1=101 I=46 CH2=98 I=48 CH3=106 I=48 CH4=101 I=47 CH5=48 I=47 CH6=101 I=47 CH7=94 I=47 CH8=104 I=46
CH0=1035 I=46 CH1=101 I=46 CH2=98 I=46 CH3=106 I=46 CH4=101 I=46 CH5=48 I=46 CH6=101 I=47 CH7=94 I=47 CH8=104 I=48
CH0=1035 I=47 CH1=101 I=47 CH2=98 I=47 CH3=106 I=46 CH4=101 I=47 CH5=48 I=47 CH6=101 I=47 CH7=94 I=47 CH8=104 I=47
CH0=1035 I=46 CH1=101 I=46 CH2=98 I=47 CH3=106 I=47 CH4=101 I=48 CH5=48 I=47 CH6=101 I=46 CH7=94 I=46 CH8=104 I=46
CH0=1035 I=46 CH1=101 I=46 CH2=98 I=46 CH3=106 I=46 CH4=101 I=46 CH5=48 I=46 CH6=101 I=48 CH7=94 I=48 CH8=104 I=47
CH0=1035 I=48 CH1=101 I=47 CH2=98 I=46 CH3=106 I=46 CH4=101 I=46 CH5=48 I=46 CH6=101 I=46 CH7=94 I=46 CH8=104 I=46
CH0=1035 I=46 CH1=101 I=46 CH2=98 I=48 CH3=106 I=48 CH4=101 I=47 CH5=48 I=46 CH6=101 I=46 CH7=94 I=47 CH8=104 I=46
CH0=1035 I=46 CH1=101 I=46 CH2=98 I=46 CH3=106 I=46 CH4=101 I=46 CH5=48 I=46 CH6=101 I=47 CH7=94 I=48 CH8=104 I=47
CH0=1035 I=47 CH1=101 I=46 CH2=98 I=46 CH3=106 I=46 CH4=101 I=46 CH5=48 I=46 CH6=101 I=46 CH7=94 I=46 CH8=104 I=46
CH0=1035 I=46 CH1=101 I=46 CH2=98 I=48 CH3=106 I=47 CH4=101 I=47 CH5=48 I=47 CH6=101 I=47 CH7=94 I=47 CH8=104 I=46
CH0=1035 I=46 CH1=101 I=46 CH2=98 I=46 CH3=106 I=46 CH4=101 I=46 CH5=48 I=48 CH6=101 I=48 CH7=94 I=47 CH8=104 I=48
CH0=1035 I=47 CH1=101 I=47 CH2=98 I=47 CH3=106 I=47 CH4=101 I=46 CH5=48 I=46 CH6=101 I=46 CH7=94 I=46 CH8=104 I=46
CH0=1035 I=46 CH1=101 I=48 CH2=98 I=48 CH3=106 I=47 CH4=101 I=48 CH5=48 I=47 CH6=101 I=46 CH7=94 I=46 CH8=104 I=46
CH0=1035 I=46 CH1=101 I=46 CH2=98 I=46 CH3=106 I=46 CH4=101 I=46 CH5=48 I=48 CH6=101 I=48 CH7=94 I=48 CH8=104 I=47
CH0=1035 I=48 CH1=101 I=47 CH2=98 I=46 CH3=106 I=46 CH4=101 I=46 CH5=48 I=46 CH6=101 I=46 CH7=94 I=46 CH8=104 I=46
CH0=1035 I=46 CH1=101 I=48 CH2=98 I=48 CH3=106 I=47 CH4=101 I=47 CH5=48 I=46 CH6=101 I=46 CH7=94 I=46 CH8=104 I=46
что будет в главном цикле, а тут только одноразовый запуск прерывания без его отключения. Если его не сделать, то много функций перестанут работать правильно.
Это еще почему? в обработчик прерывания будем попадать кратковременно при получении каждого перепада на входе. При этом получаем длительность последнего импульса/паузы.
Во время нахождения в обработчике прерывания запрещены (условно, скидывается флаг EI, (бит 7 SREG)) ибо так устроен проц. по выходу - комманде reti прерывание снова разрешается (установится EI) в посте #136 в конце есть 2 ссылочки на не плохую русскую доку.
внутри обработчика функции micros() и delayMicroseconds() не работают и не нужны. Но “посещение” прерывания никак не влияет на их работу в основном цикле…
Внутри функции обработки прерывания не работает delay(), значения возвращаемые millis() не изменяются.
Согласен, если из обработчика прерывания вызывать delay() то результат может оказаться не предсказуемым, а millis(), если она почему то заинтересует, вернет значение которое было на момент входа в прерывание … внутри обработчика в принципе и не следует задаваться какими то временными интервалами, оттуда вообще надо уходить как можно быстрее, чтобы не тратить чужое время… Полагаю что все обработки переменных и анализ можно и нужно делать в основном цикле программы… тогда ни что не будет мешать принять данные и от других портов и устройств… у процессора “сил” достаточно много чтобы со всеми справиться, да еще и “перекурить” )
У меня процик будет под завязку загружен, т.к. я решил на него повесить почти все, вот мой проект, правда на другом форуме и если это нарушает правила, то дайте знать или удалите ссылку.
Но ppm не с любого приемника снять можно, хотя для ppm используется всего одна нога. Я немного переделал свою программку и исправил одну ошибку, если кому надо то могу выложить.
Но ppm не с любого приемника снять можно, хотя для ppm используется всего одна нога. Я немного переделал свою программку и исправил одну ошибку, если кому надо то могу выложить.
Естественно, но проблема только самыми последними выпусками, а в старых наверно везде возможно. PCM-приемники конечно не подходит.
А программку конечно интересно.
Хороший проектик, зачетно-позитивный… Давно уже хочется реализовать что то очень подобное …
А программку конечно интересно.
Вот последняя версия. Только я её проверить не успел, т.к. ардуино отдал на время другу, но компилируется. Как будет время, добавлю больше комментариев и всяких опций.
Хороший проектик, зачетно-позитивный… Давно уже хочется реализовать что то очень подобное …
Спасибо, но только я похоже замахнулся на длительный проект, попробую за зиму осилить.
Вот последняя версия.
Спасибо, ознакомлюсь.
Заметил одну особенность, если в программе использовать постоянно Serial.print (например в loop, как у меня), то сервы начинают дрожать.
Есть еще одна засада. Если мозг приемника слегка съедет, и на одном из каналов который мониторится контроллером появится сигнал с частотой ~ 1 MГц, контроллер все время будет в прерываниях, на остальное ему сил не хватит. Блокировки канала от неверного сигнала (времянка меньше 0.5 мс) нету.
Есть еще одна засада. Если мозг приемника слегка съедет, и на одном из каналов который мониторится контроллером появится сигнал с частотой ~ 1 MГц, контроллер все время будет в прерываниях, на остальное ему сил не хватит. Блокировки канала от неверного сигнала (времянка меньше 0.5 мс) нету.
Не понятно, откуда там возникает такой “интересный” сигнал? это продуманная фича от производителя или глюк какого то реального приемника? и на сколько часто происходит такой “сьезд мозга”? шибко это похоже на очень не штатную ситуацию…
впрочем PPM обычно не снимается “с одного из каналов”.
я вот такую конструкцию накатал в виде библиотеки - кладем в libraries, пишем в коде:
#include <PPMint.h>
...
PPMint ppm;
...
void setup(){....
ppm.setup();
...}
void loop(){...
<используем по назначению> ppm.realRaw[<номер канал>]
...}
Мне удобно, может еще кому полезно будет www.nest.org.ru/…/ardiuno-библиотека-ppmint/
Использую для подключения пульта Futaba T7C по Bluetooth (к ящику сим подключаю).
Есть также библиотека для аналогичной обработки PWM - отдельно с каждого канала приемыша R6017HS - что не важно - но показать пока не могу - работает через ж…у, и не оформлено пригодно для использования - кое-какая муть с использованием более 2-х пинов с прерываниями, но чисто технически все уже понятно.
делаю дискретный регулятор хода коллекторных двигателей на ATmega88PA. пишу на asm. в работе с микроконтроллерами новичок. в качестве примера взял исходники для контроллера квадракоптера. вот они
накопипастил кода для 3х каналов. написал код обработки длительности импулься для включение 2х ножек для 1 канала. долго боролся с случайным блужданием контроллера по строкам кода, с цикличным прохождением прерывания по reset. после чего добился стабильного свечения светодиодов без видимых мерцаний во время включения\работы. вот код (не без мусора)
.device ATmega88PA
.include "C:\Program Files\Atmel\AVR Studio 5.0\avrassembler\include\m88PAdef.inc"
;обзываем некоторые из 16 РОН (регистров общего назначения): R16…R31
.def Temp=r16
.def Temp1=r17
.def Temp2=r18
.def Temp3=r19
.def Temp4=r20
.def Temp5=r21
.def RxChannel1StartL =r0
.def RxChannel1StartH =r1
.def RxChannel2StartL =r2
.def RxChannel2StartH =r3
.def RxChannel3StartL =r4
.def RxChannel3StartH =r5
.def RxChannel1L =r8
.def RxChannel1H =r9
.def RxChannel2L =r10
.def RxChannel2H =r11
.def RxChannel3L =r12
.def RxChannel3H =r13
.def tisp=r14
;.dseg ; Сегмент ОЗУ
;Line: .byte 2 ;константа в ОЗУ sram!
.cseg ;обозначает начало программного сегмента (запись во флэшь)
;.ESEG ; Сегмент EEPROM
.org 0 ;задает начальный адрес. В данном случае он = 0
rjmp reset
rjmp RxChannel2 ;INT0 PD2
rjmp RxChannel3 ;INT1 PD3
rjmp unused
rjmp unused
rjmp RxChannel1 ;PCINT17 PD1
rjmp unused
rjmp unused
rjmp unused
rjmp unused
rjmp unused
rjmp unused
rjmp unused
rjmp unused
rjmp unused
rjmp unused
rjmp unused
rjmp unused
rjmp unused
rjmp unused
rjmp unused
rjmp unused
rjmp unused
rjmp unused
rjmp unused
rjmp unused
unused: reti
;************************
;прерывания
;************************
RxChannel1:
in tisp, sreg
sbis pind,1 ;rising or falling?
rjmp rx1m1
lds RxChannel1StartL, tcnt1l ;rising, store the start value
lds RxChannel1StartH, tcnt1h
out sreg,tisp ;выход сразу из прерывания
reti
flagon:
lds RxChannel1StartL, tcnt1l ;rising, store the start value
lds RxChannel1StartH, tcnt1h
out sreg,tisp ;выход сразу из прерывания
reti
rx1m1:
lds RxChannel1L, tcnt1l ;falling, calculate the pulse length
lds RxChannel1H, tcnt1h
sub RxChannel1L, RxChannel1StartL
sbc RxChannel1H, RxChannel1StartH
out sreg,tisp ;выход сразу из прерывания
reti
RxChannel2:
in tisp, sreg
sbis pind,2 ;rising or falling?
rjmp rx2m1
lds RxChannel2StartL, tcnt1l ;rising, store the start value
lds RxChannel2StartH, tcnt1h
out sreg,tisp ;выход сразу из прерывания
reti
rx2m1:
lds RxChannel2L, tcnt1l ;falling, calculate the pulse length
lds RxChannel2H, tcnt1h
sub RxChannel2L, RxChannel2StartL
sbc RxChannel2H, RxChannel2StartH
out sreg,tisp ;выход сразу из прерывания
reti
RxChannel3:
in tisp, sreg
sbis pind,3 ;rising or falling?
rjmp rx3m1
lds RxChannel3StartL, tcnt1l ;rising, store the start value
lds RxChannel3StartH, tcnt1h
out sreg,tisp ;выход сразу из прерывания
reti
rx3m1:
lds RxChannel3L, tcnt1l ;falling, calculate the pulse length
lds RxChannel3H, tcnt1h
sub RxChannel3L, RxChannel3StartL
sbc RxChannel3H, RxChannel3StartH
out sreg,tisp ;выход сразу из прерывания
reti
;****************************************************
; ИНИЦИАЛИЗАЦИЯ
;****************************************************
Reset:
ldi Temp1,0 ;задержка запуска после сброса против всякой фигни
ldi Temp2,0
ldi Temp3,10
l_res:
dec Temp1
brne l_res
dec Temp2
brne l_res
dec Temp3
brne l_res
ldi Temp,Low(ramend) ; Инициализация стека
out spl,Temp ; Обязательно!!!
ldi Temp,High(ramend)
out sph,Temp
;--- setup IO ---
; 76543210
ldi Temp,0b11111111 ;настройка портов
out DDRB,Temp ;порт Б настроили на вывод
; 76543210
ldi Temp,0b00000000 ;все вырубить
out PortB,Temp
; 76543210
ldi Temp,0b11110001 ;настройка портов
out DDRD,Temp ;1,2,3 ногу порта Д настроили на ввод
; 76543210
ldi Temp,0b00000000 ;все вырубить
out PortD,Temp
; 76543210
;ldi Temp,0b00001110 ;настройка портов в режиме чтения
;out PORTD,Temp ;установили подтягивающий резистор однеркой.
;нулем поставили 3 состояние с высоким сопротивлением.
;--- Setup pin change interrupt on PD1, PD2, PD3, PB4
;установка разрешенных прерываний по ногам
; 76543210
ldi Temp,0b00000101 ;PB7, PD1 разрешение прерыв по pcint
sts pcicr,Temp
; 76543210
ldi Temp,0b00000010 ;PD1 пок какой ноге pcint
sts pcmsk2,Temp
; 76543210
ldi Temp,0b00000101 ;PD2, PD3 разрешение прерыв по int
sts eicra,Temp
; 76543210
ldi Temp,0b00000011 ;PD2, PD3 запись что и по read & write
out eimsk,Temp ;STS? OUT? Come on!
;---- таймер 1 будет на 1MHz (8MHz/8) ----
; 76543210
ldi Temp,0b00000010
sts tccr1b,Temp
;****************************************************
;прочие начальные установки
;****************************************************
Load:
ldi xl,low(1500) ;загружаем константы
ldi xh,high(1500)
mov RxChannel1L,xl
mov RxChannel1H,xh
mov RxChannel2L,xl
mov RxChannel2H,xh
mov RxChannel3L,xl
mov RxChannel3H,xh
sei ;разрешить глобальные прерывания
;****************************************************
; ОСНОВНОЙ ЦИКЛ
;****************************************************
Inf:
;cli
ldi xl,low(1700) ;загружаем константы
ldi xh,high(1700)
cp RxChannel1L,xl
cpc RxChannel1H,xh
BRSH da
ldi xl,low(820) ;загружаем константы
ldi xh,high(820)
cp RxChannel1L,xl
cpc RxChannel1H,xh
BRSH net
;sei
pinout:
cbi PortD,6
cbi PortD,7
timeflagon:
rcall Delay ;вызов задержки
rjmp Inf ;бесконечный цикл
;****************************************************
da:
sbi PortD,6
rjmp timeflagon
net:
ldi xl,low(1350) ;загружаем константы
ldi xh,high(1350)
cp RxChannel1L,xl
cpc RxChannel1H,xh
BRSH pinout
sbi PortD,7
rjmp timeflagon
;****************************************************
;Задержка
;****************************************************
Delay:
ldi Temp,0 ;присвоение 10тичной константы
ldi Temp1,0
Doop:
dec Temp
brne Doop
; dec Temp2
; brne Doop
ret
работает, но полагаю могут быть ошибки. что можно\нужно пофиксить\улучшить?