- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 10 von 60

Thema: Mehrere Servo-Signale einlesen, ggf. manipulieren, ausgeben

Baum-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #31
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.237
    Ok, Ich bin dann mal so frech und hau nen Code raus.
    Im Simulator hab ich das mal getestet - Da scheints zu funktionieren.
    Mit nem Controller kann ich leider nicht testen ( Kein ATMEGA 88 hier ).
    Ich hab das Prinzip mit dem Pinchange umgesetzt.
    Die Simulation war mit 8MHz, dabei kann ein Versatz ( Jitter ) von 30µS bei den Signalen entstehen.

    Code:
    /*****************************************************
    
    Project : Einzelimpulse zu Summensignal
    Version : 0.1
    Date    : 19.12.2014
    Author  :                  
    Company :          
    Comments: 
    
    
    Chip type           : ATmega88
    Program type        : Application
    Clock frequency     : 8,000000 MHz
    Memory model        : Small
    External SRAM size  : 0
    Data Stack size     : 256
    
    Zeitversatz beim Einlesen der Impulse 30µs!
    *****************************************************/
    
    /********
    PC0 = Kanal 1
    PC1 = Kanal 3
    PC2 = Kanal 5
    PC3 = Kanal 7
    PD0 = Kanal 2
    PD1 = Kanal 4
    PD2 = Kanal 6
    PD3 = Kanal 8
    PB1 = Summensignalausgang
    ********/
    
    #include <mega88.h>
    
    volatile unsigned int ui_timerold[8];    //Speicherwerte für die Steigende Flanke der entsprecheden Kanäle
    volatile unsigned int ui_pulslengh[8]={1500,1500,1500,1500,1500,1500,1500,1500};   //Ermittelte Pulslängen
    volatile unsigned char uc_oldgerade=0;     //Zwischenspeicher für den alten Zustand der geraden Kanäle 2,4,6,8
    volatile unsigned char uc_oldungerade=0; //Zwischenspeicher für den alten Zustand der geraden Kanäle 1,3,5,7
    volatile unsigned char uc_cyclecount;     //Zyklenzähler für die Impulsausgabe
    #define maxcycle 15
    #define interpulspause 50                 //50 = 50µs
    #define interframepause 4000              //4000 = 4ms Interframepause
    
    //#define normal                          //Bestimmt ob die Impulsausgabe normal oder invers geschehen soll
    //#define revers
    #define portsungerade PINC
    #define portsgerade PIND
    #define outport PORTB.1
    // Pin change 8-14 interrupt service routine
    interrupt [PCINT1] void pin_change_isr1(void)
    {
    unsigned char uc_portungerade,uc_result;
    unsigned int ui_timer;
    ui_timer=TCNT1H;
    ui_timer=(ui_timer<<8)+TCNT1L;
    uc_portungerade=portsungerade&0x0F;
    uc_result=uc_portungerade^uc_oldungerade;
    if(uc_result&0x01)
        {
        if(uc_portungerade&0x01)        //Es war ne steigende Flanke
            {
            ui_timerold[0]=ui_timer;
            }
        else                            //Es war ne fallende Flanke
            {
            ui_pulslengh[0]=ui_timer-ui_timerold[0];
            };
        }
    
    if(uc_result&0x02)
        {
        if(uc_portungerade&0x02)        //Es war ne steigende Flanke
            {
            ui_timerold[2]=ui_timer;
            }
        else                            //Es war ne fallende Flanke
            {
            ui_pulslengh[2]=ui_timer-ui_timerold[2];
            };
        }
        
    if(uc_result&0x04)
        {
        if(uc_portungerade&0x04)        //Es war ne steigende Flanke
            {
            ui_timerold[4]=ui_timer;
            }
        else                            //Es war ne fallende Flanke
            {
            ui_pulslengh[4]=ui_timer-ui_timerold[4];
            };
        }
        
    if(uc_result&0x08)
        {
        if(uc_portungerade&0x08)        //Es war ne steigende Flanke
            {
            ui_timerold[6]=ui_timer;
            }
        else                            //Es war ne fallende Flanke
            {
            ui_pulslengh[6]=ui_timer-ui_timerold[6];
            };
        }
    uc_oldungerade=uc_portungerade;
    }
    
    // Pin change 16-23 interrupt service routine
    interrupt [PCINT2] void pin_change_isr2(void)
    {
    unsigned char uc_portgerade,uc_result;
    unsigned int ui_timer;
    ui_timer=TCNT1H;
    ui_timer=(ui_timer<<8)+TCNT1L;
    uc_portgerade=portsgerade&0x0F;
    uc_result=uc_portgerade^uc_oldgerade;
    if(uc_result&0x01)
        {
        if(uc_portgerade&0x01)        //Es war ne steigende Flanke
            {
            ui_timerold[1]=ui_timer;
            }
        else                            //Es war ne fallende Flanke
            {
            ui_pulslengh[1]=ui_timer-ui_timerold[1];
            };
        }
    
    if(uc_result&0x02)
        {
        if(uc_portgerade&0x02)        //Es war ne steigende Flanke
            {
            ui_timerold[3]=ui_timer;
            }
        else                            //Es war ne fallende Flanke
            {
            ui_pulslengh[3]=ui_timer-ui_timerold[3];
            };
        }
        
    if(uc_result&0x04)
        {
        if(uc_portgerade&0x04)        //Es war ne steigende Flanke
            {
            ui_timerold[5]=ui_timer;
            }
        else                            //Es war ne fallende Flanke
            {
            ui_pulslengh[5]=ui_timer-ui_timerold[5];
            };
        }
        
    if(uc_result&0x08)
        {
        if(uc_portgerade&0x08)        //Es war ne steigende Flanke
            {
            ui_timerold[7]=ui_timer;
            }
        else                            //Es war ne fallende Flanke
            {
            ui_pulslengh[7]=ui_timer-ui_timerold[7];
            };
        }
    uc_oldgerade=uc_portgerade;
    }
    
    // Timer 1 output compare A interrupt service routine
    interrupt [TIM1_COMPA] void timer1_compa_isr(void)
    {
    unsigned char uc_low,uc_high;
    unsigned int ui_buffer;
    switch(uc_cyclecount)
        {
        case 0:
        outport=1;                     //Der erste Impuls
        ui_buffer=OCR1AH;              //Aktuelle Werte holen
        ui_buffer=(ui_buffer<<8)+OCR1AL;
        ui_buffer+=ui_pulslengh[0];    //Pulslänge dazuzählen
        uc_low=ui_buffer&0x00FF;       //OCR Register für nächsten Interrupt vorbelegen
        uc_high=(ui_buffer>>8)&0x00FF;
        OCR1AH=uc_high;
        OCR1AL=uc_low;
        break;
        case 1:                       //Die Pausen
        case 3:
        case 5:
        case 7:
        case 9:
        case 11:
        case 13:
        outport=0;
        ui_buffer=OCR1AH;              //Aktuelle Werte holen
        ui_buffer=(ui_buffer<<8)+OCR1AL;
        ui_buffer+=interpulspause;
        uc_low=ui_buffer&0x00FF;
        uc_high=(ui_buffer>>8)&0x00FF;
        OCR1AH=uc_high;
        OCR1AL=uc_low;
        break;
        case 2:
        outport=1;                     //Der zweite Impuls
        ui_buffer=OCR1AH;              //Aktuelle Werte holen
        ui_buffer=(ui_buffer<<8)+OCR1AL;
        ui_buffer+=ui_pulslengh[1];    //Pulslänge dazuzählen
        uc_low=ui_buffer&0x00FF;       //OCR Register für nächsten Interrupt vorbelegen
        uc_high=(ui_buffer>>8)&0x00FF;
        OCR1AH=uc_high;
        OCR1AL=uc_low;
        break;
        
        case 4:
        outport=1;                     //Der dritte Impuls
        ui_buffer=OCR1AH;              //Aktuelle Werte holen
        ui_buffer=(ui_buffer<<8)+OCR1AL;
        ui_buffer+=ui_pulslengh[2];    //Pulslänge dazuzählen
        uc_low=ui_buffer&0x00FF;       //OCR Register für nächsten Interrupt vorbelegen
        uc_high=(ui_buffer>>8)&0x00FF;
        OCR1AH=uc_high;
        OCR1AL=uc_low;
        break;
        
        case 6:
        outport=1;                     //Der vierte Impuls
        ui_buffer=OCR1AH;              //Aktuelle Werte holen
        ui_buffer=(ui_buffer<<8)+OCR1AL;
        ui_buffer+=ui_pulslengh[3];    //Pulslänge dazuzählen
        uc_low=ui_buffer&0x00FF;       //OCR Register für nächsten Interrupt vorbelegen
        uc_high=(ui_buffer>>8)&0x00FF;
        OCR1AH=uc_high;
        OCR1AL=uc_low;
        break; 
        
        case 8:
        outport=1;                     //Der fünfte Impuls
        ui_buffer=OCR1AH;              //Aktuelle Werte holen
        ui_buffer=(ui_buffer<<8)+OCR1AL;
        ui_buffer+=ui_pulslengh[4];    //Pulslänge dazuzählen
        uc_low=ui_buffer&0x00FF;       //OCR Register für nächsten Interrupt vorbelegen
        uc_high=(ui_buffer>>8)&0x00FF;
        OCR1AH=uc_high;
        OCR1AL=uc_low;
        break; 
        
        case 10:
        outport=1;                     //Der sechste Impuls
        ui_buffer=OCR1AH;              //Aktuelle Werte holen
        ui_buffer=(ui_buffer<<8)+OCR1AL;
        ui_buffer+=ui_pulslengh[5];    //Pulslänge dazuzählen
        uc_low=ui_buffer&0x00FF;       //OCR Register für nächsten Interrupt vorbelegen
        uc_high=(ui_buffer>>8)&0x00FF;
        OCR1AH=uc_high;
        OCR1AL=uc_low;
        break; 
        
        case 12:
        outport=1;                     //Der siebte Impuls
        ui_buffer=OCR1AH;              //Aktuelle Werte holen
        ui_buffer=(ui_buffer<<8)+OCR1AL;
        ui_buffer+=ui_pulslengh[6];    //Pulslänge dazuzählen
        uc_low=ui_buffer&0x00FF;       //OCR Register für nächsten Interrupt vorbelegen
        uc_high=(ui_buffer>>8)&0x00FF;
        OCR1AH=uc_high;
        OCR1AL=uc_low;
        break; 
        
        case 14:
        outport=1;                     //Der achte Impuls
        ui_buffer=OCR1AH;              //Aktuelle Werte holen
        ui_buffer=(ui_buffer<<8)+OCR1AL;
        ui_buffer+=ui_pulslengh[7];    //Pulslänge dazuzählen
        uc_low=ui_buffer&0x00FF;       //OCR Register für nächsten Interrupt vorbelegen
        uc_high=(ui_buffer>>8)&0x00FF;
        OCR1AH=uc_high;
        OCR1AL=uc_low;
        break; 
        
        case 15:
        outport=0;
        ui_buffer=OCR1AH;              //Aktuelle Werte holen
        ui_buffer=(ui_buffer<<8)+OCR1AL;
        ui_buffer+=interframepause;
        uc_low=ui_buffer&0x00FF;
        uc_high=(ui_buffer>>8)&0x00FF;
        OCR1AH=uc_high;
        OCR1AL=uc_low;
        break;
        
        default:
        uc_cyclecount=0;
        }
    uc_cyclecount++;
    if(uc_cyclecount>maxcycle){uc_cyclecount=0;}
    }
    
    // Declare your global variables here
    
    void main(void)
    {
    // Declare your local variables here
    
    // Crystal Oscillator division factor: 1
    #pragma optsize-
    CLKPR=0x80;
    CLKPR=0x00;
    #ifdef _OPTIMIZE_SIZE_
    #pragma optsize+
    #endif
    
    // Input/Output Ports initialization
    // Port B initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=Out Func0=In 
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=0 State0=T 
    PORTB=0x00;
    DDRB=0x02;
    
    // Port C initialization
    // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
    // State6=T State5=T State4=T State3=P State2=P State1=P State0=P 
    PORTC=0x0F;
    DDRC=0x00;
    
    // Port D initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
    // State7=T State6=T State5=T State4=T State3=P State2=P State1=P State0=P 
    PORTD=0x0F;
    DDRD=0x00;
    
    // Timer/Counter 0 initialization
    // Clock source: System Clock
    // Clock value: Timer 0 Stopped
    // Mode: Normal top=FFh
    // OC0A output: Disconnected
    // OC0B output: Disconnected
    TCCR0A=0x00;
    TCCR0B=0x00;
    TCNT0=0x00;
    OCR0A=0x00;
    OCR0B=0x00;
    
    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: 1000,000 kHz
    // Mode: Normal top=FFFFh
    // OC1A output: Discon.
    // OC1B output: Discon.
    // Noise Canceler: Off
    // Input Capture on Falling Edge
    // Timer 1 Overflow Interrupt: Off
    // Input Capture Interrupt: Off
    // Compare A Match Interrupt: On
    // Compare B Match Interrupt: Off
    TCCR1A=0x00;
    TCCR1B=0x02;
    TCNT1H=0x00;
    TCNT1L=0x00;
    ICR1H=0x00;
    ICR1L=0x00;
    OCR1AH=0x00;
    OCR1AL=0x00;
    OCR1BH=0x00;
    OCR1BL=0x00;
    
    // Timer/Counter 2 initialization
    // Clock source: System Clock
    // Clock value: Timer 2 Stopped
    // Mode: Normal top=FFh
    // OC2A output: Disconnected
    // OC2B output: Disconnected
    ASSR=0x00;
    TCCR2A=0x00;
    TCCR2B=0x00;
    TCNT2=0x00;
    OCR2A=0x00;
    OCR2B=0x00;
    
    // External Interrupt(s) initialization
    // INT0: Off
    // INT1: Off
    // Interrupt on any change on pins PCINT0-7: Off
    // Interrupt on any change on pins PCINT8-14: On
    // Interrupt on any change on pins PCINT16-23: On
    EICRA=0x00;
    EIMSK=0x00;
    PCICR=0x06;
    PCMSK1=0x0F;
    PCMSK2=0x0F;
    PCIFR=0x06;
    
    // Timer/Counter 0 Interrupt(s) initialization
    TIMSK0=0x00;
    // Timer/Counter 1 Interrupt(s) initialization
    TIMSK1=0x02;
    // Timer/Counter 2 Interrupt(s) initialization
    TIMSK2=0x00;
    
    // Analog Comparator initialization
    // Analog Comparator: Off
    // Analog Comparator Input Capture by Timer/Counter 1: Off
    ACSR=0x80;
    ADCSRB=0x00;
    
    // Watchdog Timer initialization
    // Watchdog Timer Prescaler: OSC/128k
    // Watchdog Timer interrupt: Off
    /*#pragma optsize-
    #asm("wdr")
    WDTCSR=0x1E;
    WDTCSR=0x0E;
    #ifdef _OPTIMIZE_SIZE_
    #pragma optsize+
    #endif   */
    
    // Global enable interrupts
    #asm("sei")
    
    while (1)
          {
          #asm("wdr")
          
          // Place your code here
    
          };
    }
    Auch wenn mehrere Ports ihre Level zu gleichen Zeit ändern, sollte der Code funzen.
    Geändert von wkrug (19.12.2014 um 20:11 Uhr)

Ähnliche Themen

  1. Mehrere RC Signale einlesen und mehrere Servos ausgeben
    Von R2D2 Bastler im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 74
    Letzter Beitrag: 10.01.2022, 08:35
  2. RC-Signal einlesen verändern und wieder ausgeben.
    Von DanielSan im Forum Arduino -Plattform
    Antworten: 1
    Letzter Beitrag: 21.03.2013, 11:58
  3. Atmel128 Spannungen einlesen und Ausgeben (Display3000)
    Von Gantenbein im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 31.08.2007, 21:41
  4. Mehrere Signale umschalten
    Von flexxo im Forum Elektronik
    Antworten: 1
    Letzter Beitrag: 25.02.2007, 13:56
  5. Servoimpulse einlesen und ausgeben
    Von moelski im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 21.08.2006, 07:24

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests