Hallo ich habe eine Platine die in eine Fernsteuerung kommt und in das vorhandene PPM Signal 3 weitere einfügt.Die Platine funktioniert auch tadellos.Jetzt habe ich noch eine zweite Funke wo ich es auch gerne einbauen möchte aber sie benutzt ein Negatives PPM Signal.Was muss ich am Code andern damit es klapt? main.C #define ENABLE_BIT_DEFINITIONS //#include <ioavr.h> //#include <inavr.h> #include <avr/io.h> #include <avr/interrupt.h> #include "main.h" enum{ stPPM_SYNC, stPPM_SYNC_WAIT, stPPM_CHANNEL_START, stPPM_CHANNEL_DATA, stPPM_CHANNEL_7_DATA_TRIGGER, stPPM_CHANNEL_7_DATA, stPPM_CHANNEL_8_START, stPPM_CHANNEL_8_DATA, stPPM_CHANNEL_9_START, stPPM_CHANNEL_9_DATA, stPPM_FINISH_PULSE, stPPM_FINISH_FRAME, stPPM_FRAME_END, stPCM_MODE_PULSE_LOW, stPCM_MODE_PULSE_HIGH, }; unsigned char channel_number = 0; unsigned char ppm_state = stPPM_SYNC; unsigned char adc_channel = 0; unsigned char sync_retry_count = 0; volatile unsigned int channel_7 = 0xffff; // set to max. for testing if conversion is valid volatile unsigned int channel_8 = 0xffff; // set to max. for testing if conversion is valid volatile unsigned int channel_9 = 0xffff; // set to max. for testing if conversion is valid /*---------------------------------------------------------------------- -------- ** ** ** function : init_pin(void) ** ** purpose : Initialise I/O pins ** ** ** **---------------------------------------------------------------------- ------*/ void init_pin(void) { DDRA &= ~(1<<PPM_IN); // set Input Capture Pin as input PORTA |= (1<<PPM_IN); // enable pullup DDRB |= (1<<PPM_OUT_PIN); // configure PPM_OUT pin as output SET_PPM_OUT_LOW; // set low DDRA &= ~(1 << CHANNEL_7_ADC); // Channel 7 (pin12) input PORTA &= ~(1 << CHANNEL_7_ADC); // disable pullup DDRA &= ~(1 << CHANNEL_8_ADC); // Channel 8 (pin11) input PORTA &= ~(1 << CHANNEL_8_ADC); // disable pullup DDRA &= ~(1 << CHANNEL_9_ADC); // Channel 8 (pin11) input PORTA &= ~(1 << CHANNEL_9_ADC); // disable pullup } /*-init_pin------------------------------------------------------------- ------*/ /*---------------------------------------------------------------------- -------- ** ** ** function : init_adc(void) ** ** purpose : Initialise ADC registers ** ** ** **---------------------------------------------------------------------- ------*/ void init_adc(void) { cli(); // disable interrupts DIDR0 |= ((1<<ADC2D)|(1<<ADC1D)); // digital input disable for pin 11 and 12 ADMUX = 0x00; // VCC as reference voltage, select channel 0 ADCSRA = (1 << ADPS2) | (1 << ADPS1)|| (0 << ADPS0); // 8.0 [Mhz] / 128 = 62,5 [kHz] ADCSRB = 0x00; // free running mode ADC_ENABLE; sei(); // enable interrupts } /*-init_adc------------------------------------------------------------- ------*/ /*---------------------------------------------------------------------- -------- ** ** ** function : init_timer1(void) ** ** purpose : Initialise timer0 ** ** Note(s) : Frequency : 8.0 [Mhz] ** ** 8 / 8.0 Mhz : 1.00 [us] ** ** ** **---------------------------------------------------------------------- ------*/ void init_timer1(void) { cli(); // disable interrupts TCCR1A = ((0<<WGM11)|(0<<WGM10)); // CTC mode TCCR1B = ((0<<WGM13)|(1<<WGM12)|(0<<CS12)|(1<<CS11)|(0<<CS10)); // CTC mode for COMPA, prescaler 8 / 8MHz => [1.0us] CLEAR_INPUT_CAPTURE_INTERRUPT_FLAG; // reset ICF flag SET_COUNTER_TO_ZERO; SET_COMPARE_COUNTER_TO_ZERO; ENABLE_INPUT_CAPTURE; DISABLE_OUTPUT_COMPARE; RISING_EDGE_TRIGGER; sei(); // enable interrupts } /*-init_timer1---------------------------------------------------------- ------*/ /*---------------------------------------------------------------------- -------- ** ** ** function : timer1_capture_interrupt(void) ** ** purpose : Synchronise PPM frame and copy input events to PPM_OUT, ** ** start mixing Ch7, 8 and 9 data when detect start pulse of Ch7 ** ** ** **---------------------------------------------------------------------- ------*/ //#pragma vector=TIM1_CAPT_vect //static __nested __interrupt void timer1_capture_interrupt (void) ISR(TIMER1_CAPT_vect) { cli(); // disable interrupts unsigned int data; switch (ppm_state) { case stPPM_SYNC: // detect rising edge pulse data = ICR1; // get timer value after input capture SET_COUNTER_TO_ZERO; FALLING_EDGE_TRIGGER; if(data >= MIN_SYNC_TIME && data <= MAX_SYNC_TIME) // valid sync trigger { SET_PPM_OUT_HIGH; ppm_state = stPPM_CHANNEL_DATA; // next state: get data channel_number = 0; sync_retry_count = 0; // when valid data, reset sync retry counter (v1.3) } else // trigger but not a valid sync time { SET_PPM_OUT_LOW; ppm_state = stPPM_SYNC_WAIT; // next state: wait for next sync event } break; case stPPM_SYNC_WAIT: sync_retry_count++; // count number of retry's (v1.3) SET_PPM_OUT_LOW; // not nessecery, output should already be low SET_COUNTER_TO_ZERO; SET_CAPTURE_COUNTER_TO_ZERO; RISING_EDGE_TRIGGER; if(sync_retry_count > 10) // 10x retry is to much, no PPM (v1.3) ppm_state = stPCM_MODE_PULSE_HIGH; // set to mode PCM pass thrue (v1.3) else // (v1.3) ppm_state = stPPM_SYNC; // next state: try again for new sync break; case stPPM_CHANNEL_START: // detect rising edge pulse SET_COUNTER_TO_ZERO; SET_PPM_OUT_HIGH; FALLING_EDGE_TRIGGER; channel_number++; // prepare for next MX12 channel clock if(channel_number>5) // all six channels read { ppm_state = stPPM_CHANNEL_7_DATA_TRIGGER; // 7th. channel but now self created channel_number = 0; } else ppm_state = stPPM_CHANNEL_DATA; break; case stPPM_CHANNEL_DATA: // detect falling edge pulse SET_COUNTER_TO_ZERO; SET_PPM_OUT_LOW; RISING_EDGE_TRIGGER; ppm_state = stPPM_CHANNEL_START; // wait for next channel rising edge pulse break; case stPPM_CHANNEL_7_DATA_TRIGGER: // detect rising edge pulse SET_COUNTER_TO_ZERO; SET_PPM_OUT_LOW; SET_TIMER_TO_COMPA_CTC; DISABLE_INPUT_CAPTURE; ENABLE_OUTPUT_COMPARE; OCR1A = START_PULSE_LOW; // startpulse length 0.3ms TRIGGER_INPUT_COMPARE_INTERRUPT; ppm_state = stPPM_CHANNEL_7_DATA; break; case stPCM_MODE_PULSE_LOW: // detect falling edge pulse (v1.3) SET_COUNTER_TO_ZERO; // prevent overflow interrupt SET_PPM_OUT_LOW; RISING_EDGE_TRIGGER; ppm_state = stPCM_MODE_PULSE_HIGH; break; case stPCM_MODE_PULSE_HIGH: // detect rising edge pulse (v1.3) SET_COUNTER_TO_ZERO; // prevent overflow interrupt SET_PPM_OUT_HIGH; FALLING_EDGE_TRIGGER; ppm_state = stPCM_MODE_PULSE_LOW; break; default: SET_PPM_OUT_LOW; // not nessecery, output should already be low SET_COUNTER_TO_ZERO; SET_CAPTURE_COUNTER_TO_ZERO; RISING_EDGE_TRIGGER; ppm_state = stPPM_SYNC; // next state: try again for new sync break; } sei(); } /*-timer1_capture_interrupt--------------------------------------------- ------*/ /*---------------------------------------------------------------------- -------- ** ** ** function : timer1_compare_interrupt(void) ** ** purpose : Mixing channel 7, 8 and 9 data into ppm out, ** ** start input capture for frame synchronisation ** ** ** **---------------------------------------------------------------------- ------*/ //#pragma vector=TIM1_COMPA_vect //__interrupt void timer1_compare_interrupt (void) ISR(TIM1_COMPA_vect) { cli(); switch (ppm_state) { case stPPM_CHANNEL_7_DATA: // create 7th channel data SET_PPM_OUT_LOW; SET_COUNTER_TO_ZERO; OCR1A = channel_7; // COMPA: 0,7ms + channel 7 ADC value ppm_state = stPPM_CHANNEL_8_START; // next State break; case stPPM_CHANNEL_8_START: // create 8th channel start pulse SET_PPM_OUT_HIGH; SET_COUNTER_TO_ZERO; OCR1A = START_PULSE_HIGH; // startpulse length 0.3ms ppm_state = stPPM_CHANNEL_8_DATA; // next State break; case stPPM_CHANNEL_8_DATA: // create 8th channel data SET_PPM_OUT_LOW; SET_COUNTER_TO_ZERO; OCR1A = START_PULSE_LOW + channel_8; // COMPA: 0,7ms + channel 7 ADC value ppm_state = stPPM_CHANNEL_9_START; // next State break; case stPPM_CHANNEL_9_START: // create 8th channel start pulse SET_PPM_OUT_HIGH; SET_COUNTER_TO_ZERO; OCR1A = START_PULSE_HIGH; // startpulse length 0.3ms ppm_state = stPPM_CHANNEL_9_DATA; // next State break; case stPPM_CHANNEL_9_DATA: // create 8th channel data SET_PPM_OUT_LOW; SET_COUNTER_TO_ZERO; OCR1A = START_PULSE_LOW + channel_9; // COMPA: 0,7ms + channel 7 ADC value ppm_state = stPPM_FINISH_PULSE; // next State break; case stPPM_FINISH_PULSE: // create last pulse SET_PPM_OUT_HIGH; SET_COUNTER_TO_ZERO; OCR1A = START_PULSE_HIGH; // startpulse length 0.3ms ppm_state = stPPM_FINISH_FRAME; // next State break; case stPPM_FINISH_FRAME: // create extra low pulse for masking PPM_IN data of channel 7 and 8 SET_PPM_OUT_LOW; SET_COUNTER_TO_ZERO; OCR1A = FORCE_LOW_END_FRAME; // keep last end low; 2 channels max - 2 channels min => 2x2ms - 2x1ms + extra length = 2 ms + 1 ms = 3ms => 3000 ticks ppm_state = stPPM_FRAME_END; // next State break; case stPPM_FRAME_END: default: RISING_EDGE_TRIGGER; DISABLE_OUTPUT_COMPARE; ENABLE_INPUT_CAPTURE; SET_TIMER_TO_COMPA_CTC; SET_COUNTER_TO_ZERO; SET_COMPARE_COUNTER_TO_ZERO; SET_CAPTURE_COUNTER_TO_ZERO; ppm_state = stPPM_SYNC; // next State TRIGGER_INPUT_CAPTURE_INTERRUPT; break; } sei(); } /*-timer1_compare_interrupt--------------------------------------------- ------*/ /*---------------------------------------------------------------------- -------- ** ** ** function : adc_server(void) ** ** purpose : Handle Analog conversion of RC channel 7, 8 and 9 ** ** ** **---------------------------------------------------------------------- ------*/ //#pragma vector=ADC_vect //__interrupt void adc_server(void) ISR(ADC_vect) { unsigned int AdcResult; ADC_DISABLE; AdcResult = ADC; if(AdcResult > 1000) // limit conversion value AdcResult = 1000; // 1000 => 1ms ADMUX &= ~(ADC_CHANNEL_MASK); // clear channel select bits if(adc_channel == ADC_CHANNEL_7) { channel_7 = AdcResult; // set channel 7 value; adc_channel = ADC_CHANNEL_8; // set next event for channel 8 conversion } else if(adc_channel == ADC_CHANNEL_8) { channel_8 = AdcResult; // set channel 8 value; adc_channel = ADC_CHANNEL_9; // set next event for channel 9 conversion } else { channel_9 = AdcResult; // set channel 9 value; adc_channel = ADC_CHANNEL_7; // set next event for channel 7 conversion } ADMUX |= adc_channel; // select new conversion channel ADC_ENABLE; } /*-adc_server----------------------------------------------------------- ------*/ /*---------------------------------------------------------------------- -------- ** ** ** function : check_valid_adc_value(void) ** ** purpose : wait until 3 ADC channels are processed at least once ** ** before init Input Capture/Timer1 ** ** ** **---------------------------------------------------------------------- ------*/ void check_valid_adc_value (void) { unsigned char exit = FALSE; do { if(channel_7 < 0xffff && channel_8 < 0xffff && channel_9 < 0xffff) // All three channels must be processed exit = TRUE; }while (!exit); } /*-check_valid_adc_value------------------------------------------------ ------*/ /*---------------------------------------------------------------------- -------- ** ** ** function : main(void) ** ** ** **---------------------------------------------------------------------- ------*/ int main(void) { init_pin(); init_adc(); check_valid_adc_value(); // wait until both ADC channels are processed at least once init_timer1(); while(1) {} } /*-main----------------------------------------------------------------- ------*/ hier main.h #include <avr/io.h> #include <inttypes.h> /* CONSTANTS */ #define TRUE 0xFF #define FALSE 0x00 #define CHANNEL_7_ADC PORTA1 // (pin12) #define CHANNEL_8_ADC PORTA2 // (pin11) #define CHANNEL_9_ADC PORTA3 // (pin11) #define PPM_IN PORTA7 // (pin6) #define PPM_OUT_PIN PORTB2 // (pin5) #define ADC_CHANNEL_7 0x01 // ADC1 - PORTA1 (pin12) #define ADC_CHANNEL_8 0x02 // ADC2 - PORTA2 (pin11) #define ADC_CHANNEL_9 0x03 // ADC3 - PORTA3 (pin10) #define ADC_CHANNEL_MASK 0x03 #define START_PULSE_HIGH 400 // [0.4ms] #define START_PULSE_LOW 600 // [0.6ms] //#define FORCE_LOW_END_FRAME 2100 // [2.1ms] //#define MIN_SYNC_TIME 2400 // [2.4ms] //NEW definition in main.h #define FORCE_LOW_END_FRAME 500 // [0,5ms] #define MIN_SYNC_TIME 3000 // [3.0ms] #define MAX_SYNC_TIME 22000 // total frame time - 8 x min channel frame time = 22ms - 8 x 1ms = 22 - 8 // minimum channel frame = START_PULSE_HIGH + START_PULSE_LOW = 400 + 600 counts = 1000 counts = 1ms // PPM frame length = 22ms = 22000 counts /**** MACROS ******************************************************************/ #define SET_PPM_OUT_HIGH PORTB |= (1<<PPM_OUT_PIN) #define SET_PPM_OUT_LOW PORTB &= ~(1<<PPM_OUT_PIN) #define FALLING_EDGE_TRIGGER TCCR1B &= ~(1<<ICES1) #define RISING_EDGE_TRIGGER TCCR1B |= (1<<ICES1) #define SET_COMPARE_COUNTER_TO_ZERO OCR1A = 0 #define SET_COUNTER_TO_ZERO TCNT1 = 0 #define SET_CAPTURE_COUNTER_TO_ZERO ICR1 = 0 #define DISABLE_INPUT_CAPTURE TIMSK1 &= ~(1<<ICIE1) // disable input capture #define ENABLE_INPUT_CAPTURE TIMSK1 |= (1 << ICIE1) // enable input capture #define DISABLE_OUTPUT_COMPARE TIMSK1 &= ~(1<<OCIE1A) // disable Output Compare A Match Interrupt #define ENABLE_OUTPUT_COMPARE TIMSK1 |= (1<<OCIE1A) // enable Output Compare A Match Interrupt #define TRIGGER_INPUT_CAPTURE_INTERRUPT TIFR1 |= (1<<ICF1) // #define CLEAR_INPUT_CAPTURE_INTERRUPT_FLAG TIFR1 &= ~(1<<ICF1) // reset ICF flag #define TRIGGER_INPUT_COMPARE_INTERRUPT TIFR1 |= (1<<OCF1A) #define SET_TIMER_TO_ICP_CTC TCCR1B |= (1<<WGM13) // CTC mode for ICP, prescaler 8 / 8MHz => [1.0us] #define SET_TIMER_TO_COMPA_CTC TCCR1B &= ~(1<<WGM13) // CTC mode for COMPA, prescaler 8 / 8MHz => [1.0us] // clear ADC enable & ADC Start Conversion & ADC Interrupt Enable bit #define ADC_DISABLE ADCSRA &= ~((1<<ADEN)|(1<<ADSC)|(1<<ADIE)) // set ADC enable & ADC Start Conversion & ADC Interrupt Enable bit #define ADC_ENABLE ADCSRA |= (1<<ADEN)|(1<<ADSC)|(1<<ADIE) /**** END MACROS ************************************************************************ *****/ //#define cli() __disable_interrupt() //#define sei() __enable_interrupt()
>aber sie benutzt ein Negatives PPM Signal.Was muss ich >am Code andern damit es klapt Den Code so lassen wie er ist. Eine negative Spannungsversorgung besorgen und einen einfachen invertierenden Verstärker an den PPM Ausgang hängen.
> Eine negative Spannungsversorgung > besorgen und einen einfachen invertierenden Verstärker > an den PPM Ausgang hängen. Nix negative Spannung. Nur einen Inverter, z.B. mit einem Transistor, verwenden. Und zwar am Ausgang der zusätzlichen Platine, damit das Signal zur anderen Fernsteuerung paßt. Was noch zu tun wäre, ist am Eingang auch einen Inverter zu schalten, damit die Polarität der Abfrage stimmt. Das ist das Orginal (hier nur 5 Kanäle)? ___ _____ ___ _______ ____ __| |_| |_| |_| |_| |____________________________ Das ist das das "negative" Signal (nach dem Inverter)? _ _ _ _ _ ___________________________ |____| |_____| |___| |_______| |_____| Blackbird
Hätte ich doch als C-Code eingefügen sollen =( Blackbird
Willwissen schrieb: > einbauen möchte aber sie benutzt ein Negatives PPM Signal.Was muss ich > am Code andern damit es klapt? Einfach den Programmierer des Codes fragen? MfG Klaus
Das problem ist das es mit einem Inventierer nicht funktioniert ich weiß nicht wieso.
ZWEI Inverter! Oder wie Klaus (Gast) schrieb: -- Frage den Programmierer --- Blackbird
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.