DMC.21 · Приём управления · ATmega328P
Задача
Из суммарного PPM-сигнала выделить длительности отдельных каналов.
Алгоритм
По каждому фронту захвата считается пауза от предыдущего; длинная пауза (>3мс) = синхро, сброс индекса каналов.
Исходный код (C, avr-gcc)
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
#include <avr/io.h>
#include <avr/interrupt.h>
#define NCH 8
volatile uint16_t ch[NCH];
volatile uint8_t idx=0;
volatile uint16_t last=0;
ISR(TIMER1_CAPT_vect){
uint16_t t=ICR1; uint16_t d=(t-last)/2; last=t;
if(d>3000){ idx=0; } // синхропауза
else if(idx<NCH){ ch[idx++]=d; }
}
int main(void){
DDRB&=~(1<<PB0);
TCCR1B=(1<<ICES1)|(1<<CS11);
TIMSK1=(1<<ICIE1);
sei();
DDRB|=(1<<PB5);
for(;;){ if(ch[2]>1500) PORTB|=(1<<PB5); else PORTB&=~(1<<PB5); } // канал газа как пример
}
Сборка: avr-gcc -mmcu=atmega328p -DF_CPU=16000000UL -Os файл.c -o файл.elf
Пояснения
До 8 каналов. Значения в мкс (тик 0.5мкс /8). Синхропауза разделяет кадры.