- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 4 von 8 ErsteErste ... 23456 ... LetzteLetzte
Ergebnis 31 bis 40 von 72

Thema: 100mm 7-Segment Stoppuhr

  1. #31
    Benutzer Stammmitglied
    Registriert seit
    20.12.2009
    Beiträge
    86
    Anzeige

    Praxistest und DIY Projekte
    Klicke auf die Grafik für eine größere Ansicht

Name:	main.jpg
Hits:	20
Größe:	39,0 KB
ID:	18558

    Also der Treiber ULN2803A müsste das schon aushalten, aber ja für die Anode,werde ich wohl die Mosfets mit BC547 ansteuern, die habe ich lagernd...

    Aber bezüglich der Vorwiderstände wenn (15V-10V)/(20mA*9)=27Ohm.. P = 5V * 0.18= 0,9W,

    das ist doch für di kleinen Widerstände zuviel nicht?

  2. #32
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.01.2006
    Beiträge
    4.555
    Zitat Zitat von Koertis Beitrag anzeigen
    Danke,

    gibt es eine Möglichkeit den Mosfet komplett durschalten zu lassen? Und sonst muss ich das hässlich machen, d.h. mit einen Transistor den Mosfet ansteuern...

    aber das würde ich gerne vermeiden...
    Google einmal nach logig level Fed, die Dinger kann man mit ttl Pegel betreiben.

    Gruß Richard

  3. #33
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Die BSP318 sind schon logic level FETs, nur halt N-Kanal. Für die Anoden braucht man High side Treiber, und dafür sind nun mal N Kanal MOSFETs nicht so gut, egal ob als Logic Level oder nicht.

    Man kann das noch gerade so machen: Das Gate kriegt über Transistor und Wiederstand bis zu 15 V, notfalls auch bis 18 V. Der Ausgang kriegt dann etwa 3 V weniger als das Gate. 3 V mal 1,2 A sind schon reichlich viel Leistung für den FET, aber das ist ja nur gepulst. Ein Problem ist, das der Spannungsabfall nicht immer gleich ist, es sei denn man hat am Gate z.B. 18 V und an Drain nur 14 V. Man braucht dann aber 2 geregelte Spannungen.

    Die kleinen Widerstände (mit Draht) sind bis etwa 250 mW, die üblichen SMD 0805 eher so bis 100 mW. Für 0,9 W braucht man schon etwas größere Widerstände.

  4. #34
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.01.2006
    Beiträge
    4.555
    Zitat Zitat von Besserwessi Beitrag anzeigen
    Die BSP318 sind schon logic level FETs, nur halt N-Kanal. Für die Anoden braucht man High side Treiber, und dafür sind nun mal N Kanal MOSFETs nicht so gut, egal ob als Logic Level oder nicht.

    Man kann das noch gerade so machen: Das Gate kriegt über Transistor und Wiederstand bis zu 15 V, notfalls auch bis 18 V. Der Ausgang kriegt dann etwa 3 V weniger als das Gate. 3 V mal 1,2 A sind schon reichlich viel Leistung für den FET, aber das ist ja nur gepulst. Ein Problem ist, das der Spannungsabfall nicht immer gleich ist, es sei denn man hat am Gate z.B. 18 V und an Drain nur 14 V. Man braucht dann aber 2 geregelte Spannungen.

    Die kleinen Widerstände (mit Draht) sind bis etwa 250 mW, die üblichen SMD 0805 eher so bis 100 mW. Für 0,9 W braucht man schon etwas größere Widerstände.

    @Besserwessi Ich habe keinen Schaltplan gesehen und auch kein Datenblatt. Bin einfach davon ausgegangen das die Passenden Bauteile benutzt werden.

    Gruß Richard

  5. #35
    Benutzer Stammmitglied
    Registriert seit
    20.12.2009
    Beiträge
    86
    Warum sollte es mit n- Kanal Mosfet nicht funktionieren? verstehe
    ich nicht...

  6. #36
    Benutzer Stammmitglied
    Registriert seit
    20.12.2009
    Beiträge
    86
    Klicke auf die Grafik für eine größere Ansicht

Name:	BC.jpg
Hits:	19
Größe:	40,5 KB
ID:	18563
    Jetzt habe ich eine Version gezeichnet mit BC547 Vorschaltung.

  7. #37
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.232
    Auch ein paar Gedanken...
    Bei 9 Stellen würde ich das Multiplexing auf 2x aufteilen.
    Also einmal 5 und einmal 4 Stellen multiplexen.
    Das bedeutet zwar, das man doppelt so viele low Side treiber und Port Ausgänge vom Controller braucht, die Segmente aber doppelt so oft angesteuert werden können.
    Das dürfte mehr Helligkeit für den Outdoorbetrieb bringen.

    Als Treibertransistoren könnte man z.B. auch BS170 einsetzen.
    Da wären dann 16Stück für die Kathoden fällig und 9 zur Ansteuerung der P-Kanal Fets für die Anoden fällig. Bei dem Preis dürfte das aber keine entscheidende Rolle spielen, da die Anzeigen, das teuerste sein dürften.

    Der Grund, warum man für die Anoden P-Kanal bzw. PNP Transistoren verwenden sollte ist, das man zwischen Drain und Source bei N-Kanal Typen eine positive Spannung von mindestens 5V braucht.
    Man müsste also eine zusätzliche Spannungsquelle haben, die um mindestens 5V höher liegt als die verwendete Segmentspannung. Das erfordert eine Modifikation des Netzteiles.
    Beim P-Kanal Typ liegt die Spannung im negativen Bereich.
    Da die Source ( Emitter ) aber auf +12V liegt lässt sich das problemlos erreichen.

    Das Stoppuhr Timing würd ich über Comparematch Interrupts lösen.
    Dann kannst Du auch mal im Hauptprogramm was ändern ohne das Timing der Stoppuhr zu beinflussen.
    Das Multiplex Timing hab ich bei meiner Uhr in einer Timer Overflow Routine erledigen lassen.

    Ich häng Dir mal den Quellcode meiner DCF 77 Uhr / Stoppuhr / Downcounter Schaltung mit 6 Segmenten an:
    Code:
    /*****************************************************
    Project : DCF77_Stoppuhr
    Version : 1.2
    Date    : 06.01.2009
    Author  : Wilhelm Krug                    
    Company : 92345 Dietfurt, Germany         
    Comments: 
    
    
    Chip type           : ATmega16L
    Program type        : Application
    Clock frequency     : 8,000000 MHz
    Memory model        : Small
    External SRAM size  : 0
    Data Stack size     : 256
    *****************************************************/
    
    #include <mega16.h>
    #include <delay.h>
    #include <stdlib.h>
    #include <string.h>
    
    // Zeichentabelle für 7 Segment Display
    //0,1,2,3,4,5,6,7,8,9,A,b,c,d,E,F,h,J,L,n,o,P,r,u,[]
    volatile unsigned char uc_chartable[25]={
    0b00111111,/*0*/
    0b00001100,
    0b01011011,
    0b01011110,
    0b01101100,
    0b01110110,
    0b01110111,
    0b00011100,
    0b01111111,
    0b01111110,/*9*/
    0b01111101,/*A*/
    0b01100111,/*b*/
    0b01000011,/*c*/
    0b01001111,/*d*/
    0b01110011,/*E*/
    0b01110001,/*F*/
    0b01101101,/*H*/
    0b00011110,/*J*/
    0b00100011,/*L*/
    0b01000101,/*n*/
    0b01000111,/*o*/
    0b01111001,/*p*/
    0b01000001,/*r*/
    0b00000111,/*u*/
    0b00000000};/*Leerzeichen*/
    
    
    // Segmentbuffer
    volatile unsigned char uc_segment[6]={0,0,0,0,0,0};
    volatile unsigned char uc_segmentcounter=0;
    
    // Displaysteuerung
    volatile unsigned char uc_dispmode=0;
    
    // Stoppuhr Zähler Steuerung
    bit ub_counting=0;                     /* Flag Stoppuhr läuft */
    bit ub_stopdelay=0;                     /* Flag Stopauslöseverzögerung aktiv */
    bit ub_autoreset=0;                     /* Flag Autoreset der Stoppuhr aktiv */
    volatile unsigned int ui_stopdelay;     /* Wert für das Stopdelay */
    volatile unsigned int ui_stopcounter=0; /* Counter für das Stopdelay */
    eeprom unsigned int ee_stopdelay=600;   /* EEPROM SPeicherplatz für das Stopdelay */
    volatile unsigned int ui_autoresetcount=0; /* Downcounter für den Autoreset */
    volatile unsigned int ui_autoreset;     /* Wert für den Autoreset */
    eeprom unsigned int ee_autoreset=500;   /* EEPROM Speicherplatz für den Autoreset */
    
    // Stoppuhr UP Zähler
    volatile unsigned char uc_countmsek=0;
    volatile unsigned char uc_countsek=0;
    volatile unsigned char uc_countmin=0;
    volatile unsigned char uc_countstd=0;
    
    // Stoppuhr Down Zähler
    volatile unsigned char uc_downmsek=0;
    volatile unsigned char uc_downsek=0;
    volatile unsigned char uc_downmin=0;
    volatile unsigned char uc_downstd=0;
    eeprom unsigned char ee_downmsek=0;
    eeprom unsigned char ee_downsek=0;
    eeprom unsigned char ee_downmin=1;
    eeprom unsigned char ee_downstd=1;
    
    // DCF Uhr
    unsigned int MS_Count = 0,old_ms_count = 0,MeasureBit = 0;
    volatile unsigned char cnt_okay = 0;
    volatile char sek_count = 0;
    volatile unsigned char TimeHours = 0, TimeMinutes = 0, TimeSeconds = 0, DateMonth = 0, DateDay = 0,Weekday = 0;
    volatile unsigned int  HiLoTimeAverage = 10;
    volatile unsigned int  TimeMilliseconds = 0;
    volatile unsigned char DCF77Bit = 0,NewBit = 0;
    volatile unsigned char value = 0;
    volatile char startbit,parity;
    volatile unsigned char dcf77_hour = 88, dcf77_minute = 88, dcf77_day = 88, dcf77_month = 88, dcf77_wday  = 88, dcf77_year  = 88;
    
    // Tastaturabfrage zum Setup
    volatile unsigned char uc_readtast=0;
    volatile unsigned char uc_oldtast=0;
    
    #define RXB8 1
    #define TXB8 0
    #define UPE 2
    #define OVR 3
    #define FE 4
    #define UDRE 5
    #define RXC 7
    
    #define FRAMING_ERROR (1<<FE)
    #define PARITY_ERROR (1<<UPE)
    #define DATA_OVERRUN (1<<OVR)
    #define DATA_REGISTER_EMPTY (1<<UDRE)
    #define RX_COMPLETE (1<<RXC)
    
    // USART Transmitter buffer
    #define TX_BUFFER_SIZE 40
    char tx_buffer[TX_BUFFER_SIZE];
    
    #if TX_BUFFER_SIZE<256
    unsigned char tx_wr_index,tx_rd_index,tx_counter;
    #else
    unsigned int tx_wr_index,tx_rd_index,tx_counter;
    #endif
    
    // USART Transmitter interrupt service routine
    interrupt [USART_TXC] void usart_tx_isr(void)
    {
    if (tx_counter)
       {
       --tx_counter;
       UDR=tx_buffer[tx_rd_index];
       if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
       };
    }
    
    #ifndef _DEBUG_TERMINAL_IO_
    // Write a character to the USART Transmitter buffer
    #define _ALTERNATE_PUTCHAR_
    #pragma used+
    void putchar(char c)
    {
    while (tx_counter == TX_BUFFER_SIZE);
    #asm("cli")
    if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))
       {
       tx_buffer[tx_wr_index]=c;
       if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
       ++tx_counter;
       }
    else
       UDR=c;
    #asm("sei")
    }
    #pragma used-
    #endif
    
    // External Interrupt 0 service routine -> Starten der Stoppuhr
    interrupt [EXT_INT0] void ext_int0_isr(void)
    {
    ub_counting=1;
    GICR&=0b00111111;
    GIFR|=0b11000000;
    ui_stopcounter=0;
    ub_stopdelay=1;
    
    
    };
    
    // External Interrupt 1 service routine -> Stoppen der Stopuhr
    interrupt [EXT_INT1] void ext_int1_isr(void)
    {
    unsigned char uc_i,uc_stringlengh;
    unsigned char uc_stringbuffer[4];
    unsigned char uc_sendstring [40];
    ub_counting=0;
    ui_stopcounter=0;
    GICR&=0b00111111;
    // Aktivierung des Autoreset bei Resetzeiten größer 1 Sekunde
    if(ui_autoreset>99)
        {
        ui_autoresetcount=ui_autoreset+100;
        ub_autoreset=1;
        };
    
    // Nur bei Stoppuhr Betrieb übertragung per seriell zum PC
    if(uc_dispmode==0)
        {
        itoa(uc_countstd,uc_stringbuffer);
        if(uc_countstd<10)
            {
            strcpyf(uc_sendstring,"0");
            strcat(uc_sendstring,uc_stringbuffer);
            }
        else
            {
            strcpy(uc_sendstring,uc_stringbuffer);
            };
        strcatf(uc_sendstring,";");
        itoa(uc_countmin,uc_stringbuffer);
        if(uc_countmin<10){strcatf(uc_sendstring,"0");};
        strcat(uc_sendstring,uc_stringbuffer);
        strcatf(uc_sendstring,";");
        itoa(uc_countsek,uc_stringbuffer);
        if(uc_countsek<10){strcatf(uc_sendstring,"0");};
        strcat(uc_sendstring,uc_stringbuffer);
        strcatf(uc_sendstring,";");
        itoa(uc_countmsek,uc_stringbuffer);
        if(uc_countmsek<10){strcatf(uc_sendstring,"0");};
        strcat(uc_sendstring,uc_stringbuffer);
        // Steuerzeichen anfügen
        uc_stringlengh=strlen(uc_sendstring);
        uc_sendstring[uc_stringlengh]=13;    /* Carriage Return 13*/
        uc_sendstring[uc_stringlengh+1]=10;    /* Line Feed 10 */
        uc_sendstring[uc_stringlengh+2]=0;     /* Stringende anfügen */
        
        uc_stringlengh=strlen(uc_sendstring);
        for(uc_i=0;uc_i<uc_stringlengh;uc_i++)
            {
            putchar(uc_sendstring[uc_i]);
            };
        };
    // Nur bei Stoppuhr Countdown betrieb übertragung per seriell zum PC
    if(uc_dispmode==1)
        {
        itoa(uc_downstd,uc_stringbuffer);
        if(uc_downstd<10)
            {
            strcpyf(uc_sendstring,"0");
            strcat(uc_sendstring,uc_stringbuffer);
            }
        else
            {
            strcpy(uc_sendstring,uc_stringbuffer);
            };
        strcpy(uc_sendstring,uc_stringbuffer);
        strcatf(uc_sendstring,";");
        itoa(uc_downmin,uc_stringbuffer);
        if(uc_downmin<10){strcatf(uc_sendstring,"0");};
        strcat(uc_sendstring,uc_stringbuffer);
        strcatf(uc_sendstring,";");
        itoa(uc_downsek,uc_stringbuffer);
        if(uc_downsek<10){strcatf(uc_sendstring,"0");};
        strcat(uc_sendstring,uc_stringbuffer);
        strcatf(uc_sendstring,";");
        itoa(uc_downmsek,uc_stringbuffer);
        if(uc_downmsek<10){strcatf(uc_sendstring,"0");};
        strcat(uc_sendstring,uc_stringbuffer);
        // Steuerzeichen anfügen
        uc_stringlengh=strlen(uc_sendstring);
        uc_sendstring[uc_stringlengh]=13;    /* Carriage Return 13*/
        uc_sendstring[uc_stringlengh+1]=10;    /* Line Feed 10 */
        uc_sendstring[uc_stringlengh+2]=0;     /* Stringende anfügen */
        
        uc_stringlengh=strlen(uc_sendstring);
        for(uc_i=0;uc_i<uc_stringlengh;uc_i++)
            {
            putchar(uc_sendstring[uc_i]);
            };
        };
    
    
    }
    
    // External Interrupt 2 service routine
    interrupt [EXT_INT2] void ext_int2_isr(void)
    {
     if((MCUCSR&0b01000000)>0)
        {
        
        MCUCSR&=0b10111111;
        MeasureBit=MS_Count-old_ms_count;  // Pausenzeitmessung
        old_ms_count=MS_Count;
        if(MeasureBit > 160)         // Rücksetzen der Sekunden auf 0
            {
            TimeMilliseconds=0;
            sek_count = 0;
            };
        
        }
     else
        {
        MCUCSR|=0b01000000;
        
        MeasureBit = MS_Count - old_ms_count; // Impulszeitmessung
        if(MeasureBit < 50)
            {
             if(MeasureBit > HiLoTimeAverage + 3) DCF77Bit = 1; 
             else DCF77Bit = 0; 
            }
        }
    }
    
     
    
    // Timer 0 overflow interrupt service routine
    interrupt [TIM0_OVF] void timer0_ovf_isr(void)
    {
    #asm("SEI");      /* Interrupts für Stoppuhr freigeben !*/
    switch (uc_segmentcounter)
        {
        case 0:
        PORTC=0;
        PORTA.5=0;
        delay_us(20);
        PORTA.0=1;
        PORTC=uc_segment[uc_segmentcounter];
        if(PINB.2>0)
            {
            PORTC.7=1;
            };
        break;
        case 1:
        PORTC=0;
        PORTA.0=0;
        delay_us(20);
        PORTA.1=1;
        PORTC=uc_segment[uc_segmentcounter];
        break;
        case 2:
        PORTC=0;
        PORTA.1=0;
        delay_us(20);
        PORTA.2=1;
        PORTC=uc_segment[uc_segmentcounter];
        break;
        case 3:
        PORTC=0;
        PORTA.2=0;
        delay_us(20);
        PORTA.3=1;
        PORTC=uc_segment[uc_segmentcounter];
        break;
        case 4:
        PORTC=0;
        PORTA.3=0;
        delay_us(20);
        PORTA.4=1;
        PORTC=uc_segment[uc_segmentcounter];
        break;
        case 5:
        PORTC=0;
        PORTA.4=0;
        delay_us(20);
        PORTA.5=1;
        PORTC=uc_segment[uc_segmentcounter];
        break;
            
        };
    uc_segmentcounter++;    
    if(uc_segmentcounter>5){uc_segmentcounter=0;};
    }
    
    // Timer 1 output compare A interrupt service routine
    interrupt [TIM1_COMPA] void timer1_compa_isr(void)
    {
    // Stopdelay aktiviert ?
    if(ub_stopdelay>0)
        {
        ui_stopcounter++;
        };
    // Autoreset aktiv ?
    if(ub_autoreset>0&&ui_autoresetcount>0)
        {
        ui_autoresetcount--;
        if((ui_autoresetcount+1)==0){ui_autoresetcount=0;};
        };
    // Stoppuhr
    if(ub_counting>0)
        {
        uc_countmsek++;
        if (uc_countmsek>99)
            {
            uc_countmsek=0;
            uc_countsek++;
            if (uc_countsek>59)
                {
                uc_countsek=0;
                uc_countmin++;
                if(uc_countmin>59)
                    {
                    uc_countmin=0;
                    uc_countstd++;
                    if(uc_countstd>99)
                        {
                        uc_countstd=0;
                        };
                    };
                };
            };
    // Countdown
        if(uc_downmsek==0&&uc_downsek==0&&uc_downmin==0&&uc_downstd==0)
            {
            // Aktivierung des Autoreset
            if(ui_autoreset>99&&ub_autoreset==0&&uc_dispmode==1)
                {
                ui_autoresetcount=ui_autoreset+100;
                ub_autoreset=1;
                };
            }
        else
            {
            uc_downmsek--;
            if(uc_downmsek+1==0)
                {
                uc_downmsek=99;
                uc_downsek--;
                if(uc_downsek+1==0)
                    {
                    uc_downsek=59;
                    uc_downmin--;
                    if(uc_downmin+1==0)
                        {
                        uc_downmin=59;
                        uc_downstd--;
                        };
                    };
                };
        
            };    
        };
    
    // static char startbit,parity;
     MS_Count++;
     TimeMilliseconds++;
     if(TimeMilliseconds > 99) // one second
      {
       NewBit = 1;
       TimeMilliseconds = 0;
       if(++TimeSeconds >59) 
        {
         TimeSeconds = 0;   
         if(++TimeMinutes > 59)
          {
            TimeMinutes = 0;
            if(++TimeHours > 23)
            {
             TimeHours = 0;
            }
          }
        }
      switch (sek_count++) 
             {
                case 20: /* startbit */
                    startbit = DCF77Bit; 
                    if(startbit)  cnt_okay++;
                    break;
                /* decode numbers */
                case 21: /* minute */
                case 29: /* hour */
                case 36: /* day */
                    parity  = value = DCF77Bit; 
                    break;   
                case 22: /* minute */
                case 30: /* hour */
                case 37: /* day */
                case 43: /* weekday */
                case 46: /* month */
                case 51: /* year */
                    parity ^= DCF77Bit; 
                    value += (DCF77Bit << 1); 
                    break;
                case 23: /* minute */
                case 31: /* hour */
                case 38: /* day */
                case 44: /* weekday */
                case 47: /* month */
                case 52: /* year */
                    parity ^= DCF77Bit; 
                    value += (DCF77Bit<<2); 
                    break;
                case 24: /* minute */
                case 32: /* hour */
                case 39: /* day */
                case 48: /* month */
                case 53: /* year */
                    parity ^= DCF77Bit; 
                    value += (DCF77Bit << 3); 
                    break;
                case 25: /* minute */
                case 33: /* hour */
                case 40: /* day */
                case 49: /* month */
                case 54: /* year */
                    parity ^= DCF77Bit; 
                    if(DCF77Bit == 1) value += 10; 
                    break;
                case 26: /* minute */
                case 34: /* hour */
                case 41: /* day */
                case 55: /* year */
                    parity ^= DCF77Bit; 
                    if(DCF77Bit == 1) value += 20; 
                    break;
                case 27: /* minute */
                case 56: /* year */
                    parity ^= DCF77Bit; 
                    if(DCF77Bit) value += 40; 
                    break;
                case 57: /* year */
                    parity ^= DCF77Bit; 
                    if(DCF77Bit) value += 80; 
                    break;
                case 28: /* minute */
                    if(DCF77Bit == parity) 
                      {
                       dcf77_minute = value; 
                       cnt_okay++;
                      } 
                       else dcf77_minute = 99;
                    break;
                case 35: /* hour */
                    if(DCF77Bit == parity) 
                      {
                       dcf77_hour = value; 
                       cnt_okay++;
                      } 
                       else dcf77_hour = 99;
                    break;
                case 42: /* weekday */
                    dcf77_day = value;
                    parity ^= DCF77Bit; 
                    value = DCF77Bit; 
                    break;   
                case 45: /* month */
                    dcf77_wday = value;
                    parity ^= DCF77Bit; 
                    value = DCF77Bit; 
                    break;   
                case 50: /* year */
                    dcf77_month = value;
                    parity ^= DCF77Bit; 
                    value = DCF77Bit; 
                    break;   
                case 59:
                     sek_count = 0;
                     break;
                case 58: /* Take all values  */
                     dcf77_year = value;
                    if(DCF77Bit == parity) cnt_okay++; 
                    startbit = 0;
                    break;
                case 1: /* Take all values  */
                     
                     if(cnt_okay == 4)
                      {
                        TimeHours   = dcf77_hour;
                        TimeMinutes = dcf77_minute;
                        DateMonth   = dcf77_month;
                        DateDay     = dcf77_day;
                        TimeSeconds = 1;
                      }
                     cnt_okay = 0;
                     break;   
    
            }  
      }   
        
    
    };
    
    void show_display(void)
    {
    unsigned char uc_buffer,uc_buffer1;
    switch (uc_dispmode)
        {
        case 0:
        if(uc_countstd>0)
            {
            uc_segment[0]=uc_chartable[(uc_countsek%10)];
            uc_segment[1]=uc_chartable[(uc_countsek/10)];
            uc_segment[2]=uc_chartable[(uc_countmin%10)];
            uc_segment[3]=uc_chartable[(uc_countmin/10)];
            uc_buffer=uc_chartable[(uc_countstd%10)];
            uc_buffer|=0b10000000;
            uc_segment[4]=uc_buffer;
            uc_segment[5]=uc_chartable[(uc_countstd/10)];
            }
        else
            {
            uc_segment[0]=uc_chartable[(uc_countmsek%10)];
            uc_segment[1]=uc_chartable[(uc_countmsek/10)];
            uc_segment[2]=uc_chartable[(uc_countsek%10)];
            uc_segment[3]=uc_chartable[(uc_countsek/10)];
            uc_segment[4]=uc_chartable[(uc_countmin%10)];
            uc_segment[5]=uc_chartable[(uc_countmin/10)];
            };
        break;
        
        case 1:
        if(uc_downstd>0)
            {
            uc_segment[0]=uc_chartable[(uc_downsek%10)];
            uc_segment[1]=uc_chartable[(uc_downsek/10)];
            uc_segment[2]=uc_chartable[(uc_downmin%10)];
            uc_segment[3]=uc_chartable[(uc_downmin/10)];
            uc_buffer=uc_chartable[(uc_downstd%10)];
            uc_buffer|=0b10000000;
            uc_segment[4]=uc_buffer;
            uc_segment[5]=uc_chartable[(uc_downstd/10)];
            }
        else
            {
            uc_segment[0]=uc_chartable[(uc_downmsek%10)];
            uc_segment[1]=uc_chartable[(uc_downmsek/10)];
            uc_segment[2]=uc_chartable[(uc_downsek%10)];
            uc_segment[3]=uc_chartable[(uc_downsek/10)];
            uc_segment[4]=uc_chartable[(uc_downmin%10)];
            uc_segment[5]=uc_chartable[(uc_downmin/10)];
            
            };
        break;
        
        // DCF 77 Funktion
        case 2:
            uc_segment[0]=uc_chartable[(TimeSeconds%10)];
            uc_segment[1]=uc_chartable[(TimeSeconds/10)];
            uc_segment[2]=uc_chartable[(TimeMinutes%10)];
            uc_segment[3]=uc_chartable[(TimeMinutes/10)];
            uc_buffer=uc_chartable[(TimeHours%10)];
            uc_buffer|=0b10000000;
            uc_segment[4]=uc_buffer;
            uc_segment[5]=uc_chartable[(TimeHours/10)];
            
        break;
        
        // DCF 77 Countdown
        case 3:
            uc_buffer1=59-TimeSeconds;
            uc_segment[0]=uc_chartable[(uc_buffer1%10)];
            uc_segment[1]=uc_chartable[(uc_buffer1/10)];
            uc_buffer1=59-TimeMinutes;
            uc_segment[2]=uc_chartable[(uc_buffer1%10)];
            uc_segment[3]=uc_chartable[(uc_buffer1/10)];
            uc_buffer1=23-TimeHours;
            uc_buffer=uc_chartable[(uc_buffer1%10)];
            uc_buffer|=0b10000000;
            uc_segment[4]=uc_buffer;
            uc_segment[5]=uc_chartable[(uc_buffer1/10)];
        }; 
    
    
    };
    
    unsigned char readtast(void)
    {
    unsigned char uc_buffer[2];
    uc_buffer[0]=PIND&0b00011100;   /* Port B einlesen und Tasten separieren */
    delay_ms(10);                   /* 10ms warten */
    uc_buffer[1]=PIND&0b00011100;   /* Port B nochmals einlesen und Tasten separieren */
    if(uc_buffer[0]==uc_buffer[1])  /* Sind beide Tasten gleich -> Werte zurückgeben */
    {
        return(uc_buffer[0]);
    }
    else
    {
        return (0);                 /* Verschieden = Fehler = 0 zurückgeben */
    }
    }
    
    
    void setup(void)
    {
    unsigned int ui_buffer=0;
    
    #asm("SEI")
    uc_readtast=readtast();
    uc_oldtast=uc_readtast;
    while(uc_readtast==uc_oldtast)
        {
        uc_readtast=readtast();     // Warten auf loslassen der Taste
        uc_segment[0]=uc_chartable[24];
        uc_segment[1]=uc_chartable[24];
        uc_segment[2]=uc_chartable[21]; /*P*/
        uc_segment[3]=uc_chartable[24]; /* Leerzeichen */
        uc_segment[4]=uc_chartable[14]; /*E*/
        uc_segment[5]=uc_chartable[5];  /*S*/
        };
    
    delay_ms(100);
    
    // Einstellung delay der Stoppfunktion
    while(uc_readtast!=0b00001100)
        {
        uc_readtast=readtast();
        if(uc_readtast!=uc_oldtast)
            {
            if (uc_readtast==0b00011000)
                {
                ui_stopdelay=ui_stopdelay+10;
                if(ui_stopdelay>990){ui_stopdelay=0;};
                }
            if (uc_readtast==0b00010100)
                {
                ui_stopdelay=ui_stopdelay-10;
                if(ui_stopdelay>990){ui_stopdelay=990;};
                }
            uc_oldtast=uc_readtast;
            }
        ui_buffer=ui_stopdelay/10;
        uc_segment[0]=uc_chartable[(ui_buffer%10)];
        uc_segment[1]=uc_chartable[(ui_buffer/10)];
        uc_segment[1]|=0b10000000;
        uc_segment[2]=uc_chartable[18]; /*L*/
        uc_segment[3]=uc_chartable[14]; /*E*/
        uc_segment[4]=uc_chartable[13]; /*d*/
        uc_segment[5]=uc_chartable[5];  /*S*/
        };
    if (ui_stopdelay!=ee_stopdelay){ee_stopdelay=ui_stopdelay;};
    
    
    while(uc_readtast==uc_oldtast)
        {
        uc_readtast=readtast();     // Warten auf loslassen der Taste
        };
    
    delay_ms(100);
    
    // Einstellen des Autoreset wertes
    while(uc_readtast!=0b00001100)
        {
        uc_readtast=readtast();
        if(uc_readtast!=uc_oldtast)
            {
            if (uc_readtast==0b00011000)
                {
                ui_autoreset=ui_autoreset+100;
                if(ui_autoreset>2000){ui_autoreset=2000;};
                }
            if (uc_readtast==0b00010100)
                {
                ui_autoreset=ui_autoreset-100;
                if(ui_autoreset>32767){ui_autoreset=0;};
                }
            uc_oldtast=uc_readtast;
            }
        ui_buffer=ui_autoreset/100;
        uc_segment[0]=uc_chartable[(ui_buffer%10)];
        uc_segment[1]=uc_chartable[(ui_buffer/10)];
        uc_segment[2]=uc_chartable[5];  /*S*/
        uc_segment[3]=uc_chartable[14]; /*E*/
        uc_segment[4]=uc_chartable[22]; /*r*/
        uc_segment[5]=uc_chartable[10];  /*A*/
        };
    ui_autoreset=ui_buffer*100;
    if (ui_autoreset!=ee_autoreset){ee_autoreset=ui_autoreset;};
    
    while(uc_readtast==uc_oldtast)
        {
        uc_readtast=readtast();     // Warten auf loslassen der Taste
        };
    
    delay_ms(100);
    
    // Einstellung Stunden Down Counter
    while(uc_readtast!=0b00001100)
        {
        uc_readtast=readtast();
        if(uc_readtast!=uc_oldtast)
            {
            if (uc_readtast==0b00011000)
                {
                uc_downstd++;
                if(uc_downstd>99){uc_downstd=0;};
                }
            if (uc_readtast==0b00010100)
                {
                uc_downstd--;
                if(uc_downstd+1==0){uc_downstd=99;};
                }
            uc_oldtast=uc_readtast;
            }
        uc_segment[0]=uc_chartable[(uc_downstd%10)];
        uc_segment[1]=uc_chartable[(uc_downstd/10)];
        uc_segment[2]=uc_chartable[22]; /*r*/
        uc_segment[3]=uc_chartable[16]; /*H*/
        uc_segment[4]=uc_chartable[24];
        uc_segment[5]=uc_chartable[13]; /*d*/
        };
    if (uc_downstd!=ee_downstd){ee_downstd=uc_downstd;};
    while(uc_readtast==uc_oldtast)
        {
        uc_readtast=readtast();     // Warten auf loslassen der Taste
        };
    
    delay_ms(100);
    // Einstellung Minuten Down Counter
    while(uc_readtast!=0b00001100)
        {
        uc_readtast=readtast();
        if(uc_readtast!=uc_oldtast)
            {
            if (uc_readtast==0b00011000)
                {
                uc_downmin++;
                if(uc_downmin>59){uc_downmin=0;};
                }
            if (uc_readtast==0b00010100)
                {
                uc_downmin--;
                if(uc_downmin+1==0){uc_downstd=59;};
                }
            uc_oldtast=uc_readtast;
            }
        uc_segment[0]=uc_chartable[(uc_downmin%10)];
        uc_segment[1]=uc_chartable[(uc_downmin/10)];
        uc_segment[2]=uc_chartable[19];  /*n*/
        uc_segment[3]=uc_chartable[19];  /*n*/
        uc_segment[4]=uc_chartable[24];  /* */
        uc_segment[5]=uc_chartable[13];  /*d*/
        };
    if (uc_downmin!=ee_downmin){ee_downmin=uc_downmin;};    
    
    while(uc_readtast==uc_oldtast)
        {
        uc_readtast=readtast();     // Warten auf loslassen der Taste
        };
    
    delay_ms(100);
    // Einstellung Sekunden Down Counter
    while(uc_readtast!=0b00001100)
        {
        uc_readtast=readtast();
        if(uc_readtast!=uc_oldtast)
            {
            if (uc_readtast==0b00011000)
                {
                uc_downsek++;
                if(uc_downsek>59){uc_downsek=0;};
                }
            if (uc_readtast==0b00010100)
                {
                uc_downsek--;
                if(uc_downsek+1==0){uc_downsek=59;};
                }
            uc_oldtast=uc_readtast;
            }
        uc_segment[0]=uc_chartable[(uc_downsek%10)];
        uc_segment[1]=uc_chartable[(uc_downsek/10)];
        uc_segment[2]=uc_chartable[14]; /*E*/
        uc_segment[3]=uc_chartable[5];  /*S*/
        uc_segment[4]=uc_chartable[24];
        uc_segment[5]=uc_chartable[13]; /*d*/
        };
    if (uc_downsek!=ee_downsek)
        {
        ee_downsek=uc_downsek;
        ee_downmsek=uc_downmsek;
        };
    #asm("CLI")
    GIFR|=0b11100000; /*Eventuell anstehende Interrupt Flags löschen */
    }
    
    
    void main(void)
    {
    // Declare your local variables here
    
    // Input/Output Ports initialization
    // Port A initialization
    // Func7=In Func6=In Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out 
    // State7=T State6=T State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 
    PORTA=0x00;
    DDRA=0x3F;
    
    // Port B 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=T State2=T State1=T State0=T 
    PORTB=0x00;
    DDRB=0x00;
    
    // Port C initialization
    // Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out 
    // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 
    PORTC=0x00;
    DDRC=0xFF;
    
    // 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=T State2=T State1=T State0=T 
    PORTD=0x00;
    DDRD=0x00;
    
    // Timer/Counter 0 initialization
    // Clock source: System Clock
    // Clock value: 125,000 kHz
    // Mode: Normal top=FFh
    // OC0 output: Disconnected
    TCCR0=0x03;
    TCNT0=0x00;
    OCR0=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
    // CTC Mode: On
    TCCR1A=0x00;
    TCCR1B=0x0A;
    TCNT1H=0x00;
    TCNT1L=0x00;
    ICR1H=0x00;
    ICR1L=0x00;
    OCR1AH=0x27;
    OCR1AL=0x0F;
    OCR1BH=0x00;
    OCR1BL=0x00;
    
    // Timer/Counter 2 initialization
    // Clock source: System Clock
    // Clock value: Timer 2 Stopped
    // Mode: Normal top=FFh
    // OC2 output: Disconnected
    ASSR=0x00;
    TCCR2=0x00;
    TCNT2=0x00;
    OCR2=0x00;
    
    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=0x11;
    
    ui_autoreset=ee_autoreset;
    ui_stopdelay=ee_stopdelay;
    uc_downmsek=ee_downmsek;
    uc_downsek=ee_downsek;
    uc_downmin=ee_downmin;
    uc_downstd=ee_downstd;
    
    
    if(PIND.4==0)
        {
        setup();
        };
    
    // External Interrupt(s) initialization
    // INT0: On
    // INT0 Mode: Falling Edge
    // INT1: Off
    // INT1 Mode: Falling Edge
    // INT2: On
    // INT2 Mode: Rising Edge
    GICR|=0xE0;
    MCUCR=0x02;
    MCUCSR=0x40;
    GIFR=0xE0;
    
    
    
    // USART initialization
    // Communication Parameters: 8 Data, 1 Stop, No Parity
    // USART Receiver: Off
    // USART Transmitter: On
    // USART Mode: Asynchronous
    // USART Baud Rate: 38400
    UCSRA=0x00;
    UCSRB=0x48;
    UCSRC=0x86;
    UBRRH=0x00;
    UBRRL=0x0C;
    
    // Analog Comparator initialization
    // Analog Comparator: Off
    // Analog Comparator Input Capture by Timer/Counter 1: Off
    ACSR=0x80;
    SFIOR=0x00;
    
    //****** Testroutines
    /*uc_dispmode=0;*/
    
    //****** End of Testroutines
    
    
    
    
    // Watchdog Timer initialization
    // Watchdog Timer Prescaler: OSC/1024k
    #pragma optsize-
    WDTCR=0x1E;
    WDTCR=0x0E;
    #ifdef _OPTIMIZE_SIZE_
    #pragma optsize+
    #endif
    
    // Global enable interrupts
    #asm("sei")
    
    while (1)
          {
          #asm("wdr");
          if (ui_stopcounter>=ui_stopdelay)
            {
            GIFR|=0b11000000;     /* Anstehende Interrupts löschen */
            GICR|=0b10000000;     /* INT1 = Stopp die Stoppuhr freigeben */
            ub_stopdelay=0;       /* Stopcounter Flag zurücksetzen */
            ui_stopcounter=0;     /* Stop Delay Zähler wieder auf 0 zurücksetzen */
            };
          if(PINB.0>0)
            {
            uc_dispmode=0; /* Pin B.0 mit Pullup =1 -> Stoppuhrbetrieb */
            }
          else
            {
            uc_dispmode=2; /* Pin B.0 mit Schalter auf GND -> DCF 77 Betrieb */
            };
          if(PINB.1>0)
            {
            uc_dispmode++; /* Pin B.1 mit Pullup =1 -> Reversebetrieb der Uhren */
            };
          
          // Pin D.4 = 0 -> Reset der Stoppuhren
          if(PIND.4>0)
            {
            // Tue nichs
            }
          else  
            {
            ub_autoreset=0;
            ui_autoresetcount=0;
            ub_stopdelay=0;
            ui_stopcounter=0;
            ub_counting=0;
            uc_countmsek=0;
            uc_countsek=0;
            uc_countmin=0;
            uc_countstd=0;
            uc_downmsek=ee_downmsek;
            uc_downsek=ee_downsek;
            uc_downmin=ee_downmin;
            uc_downstd=ee_downstd;
            GIFR|=0b11000000;
            GICR&=0b00111111;
            GICR|=0b01000000;
            };
          // Automatischer Reset der Stoppuhr
          if(ui_autoresetcount<100&&ub_autoreset>0)
            {
            ub_autoreset=0;
            ui_autoresetcount=0;
            ub_stopdelay=0;
            ui_stopcounter=0;
            ub_counting=0;
            uc_countmsek=0;
            uc_countsek=0;
            uc_countmin=0;
            uc_countstd=0;
            uc_downmsek=ee_downmsek;
            uc_downsek=ee_downsek;
            uc_downmin=ee_downmin;
            uc_downstd=ee_downstd;
            GIFR|=0b11000000;
            GICR&=0b00111111;
            GICR|=0b01000000;
            };
            
          show_display();
                 
          
          };
    }
    Eventuell kannst Du ja Teile davon gebrauchen...
    Schaltplan hab ich auch, aber ich hab hier auch ULN2803 und für die Anoden P-FET's verwendet.
    Übrigens hab ich für meine Schaltung ein einstellbares stabilisiertes Steckernetzteil verwendet.
    Damit kann man dan die Helligkeit der Segmente relativ einfach einstellbar machen.

  8. #38
    Benutzer Stammmitglied
    Registriert seit
    20.12.2009
    Beiträge
    86
    Mit einem Overflow schreibst du zwar zur gleichen Zeit das gleiche raus, aber warum sollten die Segmente doppelt so schnell angesteuert werden? Geschrieben wird ja ach nach der Reihe. Dann ist es ja wieder das selbe....

    Die Idee mit dem Steckernetzteil ist klasse... Ok dann lege ich mir P-FET's zu, das ist das einfachste, aber ich weiß nicht ob ich die Segmente aufteilen werde...

    Mein code:
    Code:
    #include <avr/io.h>
    #define F_CPU 16000000
    #include <util/delay.h>
    #include <avr/interrupt.h>
    
    #define ZERO     0x3f
    #define ONE      0x06
    #define TWO      0x5b
    #define THREE 0x4f
    #define FOUR    0x66
    #define FIFE    0x6d
    #define SIX     0x7d
    #define SEVEN 0x07
    #define EIGHT 0x7f
    #define NINE    0x6f
    
    
    #define    t            0
    #define hu        1
    #define z            2
    #define s            3
    #define ds        4
    #define m            5
    #define dm        6
    #define h            7
    #define dh        8
    
    #define defSek    16000
    #define waits   61
    
    volatile uint8_t stop = 0;
    volatile uint8_t pause = 0;
    volatile uint8_t Freigabe = 0;
    volatile uint8_t block = 0;
    
    ISR(INT0_vect) {
    if(Freigabe && (stop > waits)){
      Freigabe = 0;
        block = 0;
        }
    else if(!Freigabe && (stop >waits)){
        block = 0;
        Freigabe = 1;
    }
    }
    
    ISR(TIMER1_COMPA_vect){
    pause=0;
    }
    
    ISR(TIMER2_OVF_vect){
    stop++;
    if(stop == 254)
        stop = 254;
    }
    
    
    
    void func(uint8_t *A)    {
      A[t]++;
        if(A[t] == 10) { 
            A[t]= 0;
          A[hu]++;
            if(A[hu] == 10){
                A[hu]=0;
                A[z]++;
                if(A[z] == 10){
                    A[z] = 0;
                    A[s]++;
                    if(A[s] ==10){
                        A[s] = 0;
                        A[ds]++;
                        if(A[ds] == 6){
                            A[ds] = 0;
                            A[m]++;
                            if(A[m] == 10){
                              A[m] = 0;
                              A[dm]++;
                              if(A[dm]==6){
                              A[dm]=0;
                              A[h]++;
                              if(A[h]==10){
                                      A[h]=0;
                                      A[dh]++;
                                      if(A[dh]==10)
                                    A[dh]=0;
                                    }
                              }                            
                          }    
                        }
                    }
                }
            }
        }
    }
    
     
    int main(void)
    {
     
      // set Ports
        DDRD |= ((1<<PD3)|(1<<PD4)|(1<<PD5)|(1<<PD6)|(1<<PD7));
        PORTD &= ~((1<<PD3)|(1<<PD4)|(1<<PD5)|(1<<PD6)|(1<<PD7));
        DDRA = 0xff;
        PORTA = 0xff;
        // set Interrupt 0
        GICR  |= (1<<INT0);
        MCUCR |= (1<<ISC01);
        
        // set TImMER 1 to CTC Mode
        TCCR1B |= (1<<CS10)|(1<<WGM12);
        TIMSK |= (1<<OCIE1A);
        
        // Set Timer 2 OVF INterrupt
        TCCR2 |= (1<<CS22)|(1<<CS21)|(1<<CS20);
        TIMSK |= (1<<TOIE2);
        
        uint8_t LINE [9][10];
        uint8_t A[9] = {0,0,0,0,0,0,0,0,0};
        uint8_t COUNT[12] = {ZERO ,ONE, TWO , THREE, FOUR, FIFE, SIX, SEVEN, EIGHT, NINE};    
        uint8_t i = 0;
        uint8_t j = 0;
        OCR1A = defSek;
        
        for (i = 0; i<10; i++)
         for(j = 0; j<11; j++){
           if(i == 1)
                    LINE[i][j] = COUNT[j]|0x80;
                else
                  LINE[i][j] = COUNT[j];
    
        }
        
        sei();
        
        while(1){
        
        
            while(pause){
    
                for(i = 0; i< 5; i++){
                    PORTD = 0x08<<i;
                    _delay_us(1);
    
                    PORTA = LINE[i][A[4-i]];
                    _delay_us(194);
                    PORTD = 0x08<<i;
                    _delay_us(1);
                }
            
            }
            if(Freigabe)
                func(A);    
            if(!block){
                TCNT2 = 0;
                stop = 0;
                block = 1;
            }
            pause = 1;
      }
    
    
        cli();
        return 0;
    }

  9. #39
    Benutzer Stammmitglied
    Registriert seit
    20.12.2009
    Beiträge
    86
    Aber muss ich die p-Mosfets dann normal anschließen D-S oder "verkehrt" S-D??

  10. #40
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Die P MOSFETs werden schon richtig herum angeschlossen: Source nach 12 V (oder ggf. etwas mehr) und Drain an die Anoden.

    Die Aufteilung in 2 Hälften macht schon Sinn: bei 9 Stellen im Mulitplexing kommt man schon in den Bereich wo der maximale Pulsstrom der Anzeigen die Grenze ist. Es gibt z.B. welche mit DC bis 25 mA, aber gepulst nur bis 150 mA. Der maximale Pulsstrom ist dann oft auch nur zulässig wenn die Umschaltung etwas schneller ist als man es für die Anzeige eigentlich bräuchte.

    Durch das Aufteilen der Anzeige verschiebt sich die Zahl der Treiber, statt 7 mal Low Side (ulN2003 oder BS170) und 9 mal High Side (z.B. ULN2003+P-FET) sind es dann 14 mal low side und 5 mal High Side (auch nur gut 1 A). Von den Treibern hält sich der Aufwand etwa die Waage.

Seite 4 von 8 ErsteErste ... 23456 ... LetzteLetzte

Ähnliche Themen

  1. Stoppuhr
    Von derpedi im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 11
    Letzter Beitrag: 07.03.2010, 21:37
  2. Suche schweres Alu-T-Nuten-Profil 80-100mm Breite
    Von erik_wolfram im Forum Suche bestimmtes Bauteil bzw. Empfehlung
    Antworten: 4
    Letzter Beitrag: 26.01.2010, 08:47
  3. Drucksensor für 100mm Wassersäule gesucht
    Von BlaueLed im Forum Sensoren / Sensorik
    Antworten: 2
    Letzter Beitrag: 08.04.2008, 08:29
  4. Suche Hohlkugel Kunststoff/Gummi Dm. 80-100mm
    Von toemchen im Forum Mechanik
    Antworten: 22
    Letzter Beitrag: 19.10.2006, 22:50
  5. Stoppuhr an Lichtschranken
    Von Sebian im Forum Elektronik
    Antworten: 36
    Letzter Beitrag: 22.05.2005, 10:07

Stichworte

Berechtigungen

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

Labornetzteil AliExpress