- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 12

Thema: Wieso läuft dat net so?

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    08.05.2005
    Alter
    48
    Beiträge
    33

    Wieso läuft dat net so?

    Anzeige

    Powerstation Test
    Tach alle zusammen.
    Erstmal ist mein erstes C program,2 es ist garnicht kommentier,dritens es funktioniert aber nicht so wie vorgesehen. Kann da mal jemand helfen bitte ?
    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
    #include <inttypes.h> 
    //#include <global.h>		// include our global settings
    //#include <uart.h>		// include UART function library
    
    #include <proc.h>
    #include <avr/pgmspace.h>
    
    #define uchar	unsigned char
    #define uint	unsigned int
    
    
    
    static void avr_init(void);
    
    unsigned const int phaseAngleTiming[257] = {
    498,704,863,997,1116,1223,1322,1414,1501,1583,
    1662,1737,1809,1878,1946,2011,2074,2136,2196,2254,
    2312,2368,2422,2476,2529,2581,2632,2682,2732,2780,
    2828,2876,2922,2968,3014,3059,3103,3147,3191,3234,
    3276,3319,3360,3402,3443,3483,3524,3564,3603,3643,
    3682,3721,3759,3797,3835,3873,3910,3948,3985,4022,
    4058,4094,4131,4167,4202,4238,4274,4309,4344,4379,
    4414,4448,4483,4517,4551,4585,4619,4653,4687,4721,
    4754,4787,4821,4854,4887,4920,4953,4985,5018,5051,
    5083,5116,5148,5180,5212,5245,5277,5309,5341,5373,
    5404,5436,5468,5500,5531,5563,5594,5626,5657,5689,
    5720,5751,5783,5814,5845,5876,5908,5939,5970,6001,
    6032,6063,6095,6126,6157,6188,6219,6250,6281,6312,
    6343,6374,6405,6437,6468,6499,6530,6561,6592,6624,
    6655,6686,6717,6749,6780,6811,6843,6874,6906,6937,
    6969,7000,7032,7064,7096,7127,7159,7191,7223,7255,
    7288,7320,7352,7384,7417,7449,7482,7515,7547,7580,
    7613,7646,7679,7713,7746,7779,7813,7847,7881,7915,
    7949,7983,8017,8052,8086,8121,8156,8191,8226,8262,
    8298,8333,8369,8406,8442,8478,8515,8552,8590,8627,
    8665,8703,8741,8779,8818,8857,8897,8936,8976,9017,
    9057,9098,9140,9181,9224,9266,9309,9353,9397,9441,
    9486,9532,9578,9624,9672,9720,9768,9818,9868,9919,
    9971,10024,10078,10132,10188,10246,10304,10364,10426,10489,
    10554,10622,10691,10763,10838,10917,10999,11086,11178,11277,
    11384,11503,11637,11796,12002};
    
    volatile unsigned char ch1_level = 50,ch2_level = 0;
    volatile unsigned char next_trigger;
    volatile int test = 50;
    volatile unsigned char clk_msec = 0,clk_sec = 0,clk_min = 00,clk_hour = 20;
    volatile unsigned int t_msec = 0,old_msec = 0;
    volatile unsigned char c_on=0;
    	
    int main(void)
    {
        avr_init();
        //Variable declaration
    	char btn_temp;
    	char btn1,btn2;
    	unsigned int btn1_time = 0;
    	while(1==1)
        {
    		btn_temp = PINA & 0b00001111;
    		btn1	 = PINA & 0b00000001;
    		btn2	 = PINA & 0b00000010;
    		//btn3	 = PINA & 0b00000100;
    		//btn4	 = PINA & 0b00001000;
    
    		if (old_msec != t_msec){
    		
    			if(!btn1){
    				btn1_time = btn1_time + (t_msec - old_msec);
    			}
    			old_msec = t_msec;
    		}
    
    
    		if (clk_msec>=100){
    			PORTB = PORTB ^ 1<<2;
    			clk_msec = 0;
    			clk_sec++;
    		}
    		if (!btn1){
    			//in_use = in_use ^ 1<<0; // Toggle
    			//in_use = in_use & ~(1<<0); // Set
    			if (btn1_time >= 150){
    //				put_char(ch1_level);		//Debuging
    				PORTB = PORTB & ~(1<<0);				//dem kneppi seng luuscht unmaan :
    				btn1_time=149;
    				ch1_level = ch1_level + 1;
    				if (ch1_level >=255){
    					ch1_level = 0;
    				}
    			}
    		}
    		else{
    			btn1_time = 0;
    			if (!(PORTB & 1<<0)){
    				PORTB = PORTB ^ 1<<0;
    			}
    		}
    	}
    }
    static void avr_init(void)
    {
        // Initialize device here.
    	// initialize the UART (serial port)
       	//UART einstellen 8 Bit, 1 Stoppbit
    	UCSRB = (1<<TXEN) ;
    	UBRRH = (uchar)(UART_BAUD_SELECT>>8);		// (uart.h)
    	UBRRL = (uchar)(UART_BAUD_SELECT);		//Baud rate einstellen
    	UCSRC = (1<<URSEL)|  (1<<UCSZ1)| (1<<UCSZ0);	// 8 Bit
    
    	DDRA = 0b11110000;    
    	PORTA = 0x00;       
    	DDRB = 0xFF;
    	PORTB = 0xFF;
    	DDRC = 0xFF;
    	PORTC = 0x00;
    	enable_int(0);
    	MCUCR =	(1<<ISC01) | (1<<ISC00); // int0 sense: rising edge
    	TCCR1B =  (1<<CS11);//Vorteiler auf 8
    //	TIMSK |= (1<<TOIE1);
    	TIMSK |= (1<<OCIE1A);
    	TCNT1 = 1;
    	OCR1A =65530;
    	sei();
        return;
    }	
    
    INTERRUPT(SIG_INTERRUPT0){
    	TCNT1 = 1; //TIMER_START + TIMER_FIXED_BIAS - (127 << 4) + (u16) (g_zeroCrossBias << 4);
    	TCCR1B = (1<<CS11); // CK/8
    	TIMSK &= ~((1<<OCIE1A) | (1<<OCIE1B) | (1<<TOIE2) | (1<<TOIE1));
    	GICR &= ~(1<<INT0); // make sure we're not called recursively
    	GIFR = (1<<INTF0); // clear flag in case it's been set again already
    	t_msec++;
    	clk_msec++;
    	TCNT1 = 1;
    	next_trigger = 1;
    	OCR1A = 498;
    //	OCR1A = phaseAngleTiming[(int) next_trigger];
    	PORTC = 0x00;
    	GICR |= (1<<INT0); // reenable this isr
    	TIMSK |= (1<<OCIE1A);
    return;
    }
    INTERRUPT(SIG_OUTPUT_COMPARE1A){
    
    	if (next_trigger >= ch1_level){
    		PORTC = PORTC | 0b00000001;
    	}
    
    	next_trigger = next_trigger + 1;
    
    	OCR1A = phaseAngleTiming[(int) next_trigger];
    
    return;
    }
    //Interrupt enabler
    void enable_int(char interrupt)
    {
    	switch(interrupt)
    		{
    		case 0:
    			GICR = (1<<INT0);
    		break;
    		case 1:
    			GICR = (1<<INT1);
    		break;
    		default:
    		break;
    		}
    }
    void disable_int(char interrupt)
    //Interrupt disabler
    {
    	switch(interrupt)
    		{
    		case 0:
    			GICR = (1>>INT0);
    		break;
    		case 1:
    			GICR = (1>>INT1);
    		break;
    		default:
    		break;
    		}
    }
    void put_int(char c)
    {
    	char c1=0;
    	while( (UCSRA & 1<<UDRE) == 0 );  //bereit für neues Zeichen ???
    //	itoa(c,c1,10);
    	UDR = c1;			  //und ausgeben
    }
    void put_char(char c)
    {
    	while( (UCSRA & 1<<UDRE) == 0 );  //bereit für neues Zeichen ???
    	UDR = c;			  //und ausgeben
    }
    also das ganze soll mal ne dimmer steuerung werden doch bis jetzt ist es nur ne "ich flakere nur mal kurz und bin dann ganz aus" steuerung.
    mfg

    getaco


    ---------------------------------------------------------------------------------------------
    Programiere lang und erfolgreich.

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    04.04.2005
    Ort
    Hamburg <-> Bremen
    Alter
    43
    Beiträge
    112
    Hmm,
    Kommentare waehren schon nicht schlecht...
    Mir ist da so auf Anhieb nicht klar was Du womit bezweckst, und dann ist natuerlich auch schwer nen Fehler zu finden wenn die richtige Funktion nicht bekannt ist...
    Besonders wuerd mich dieses riesen Array interissieren...

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    08.05.2005
    Alter
    48
    Beiträge
    33
    dieses riesen array sind zuendzeitpunkte.d.h. wie schon kurz gesagt soll das ganze mal ein 220V phasenanschnitt dimmer werden,ich muss also jede halbwelle der wechselspannung in 256 teile zerlegen, das sin eben diese werte im array.Das Programm soll an sich einen taster auswerten (die ganzen btnxxx variabeln) der die helligkeit beeinflussen soll. INT0 wird durch den Nulldurchgang des Phasenwechselstroms ausgeloest. Das andere Interrupt ist fuer den Timer Compare gedacht und ist an sich das herzstueck des dimmers. An PortC haengen die triacs,PortB sind ein par dumme Leds und PortA die Taster.

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    04.04.2005
    Ort
    Hamburg <-> Bremen
    Alter
    43
    Beiträge
    112
    Hmm,
    aber mueste es dann nicht bei 0 losgehen ?? Und der Verlauf ist doch vom Prinzip auch egal...
    Brauchst doch nur die frequenz=>Periodendauer, davon die haelfte und das dann so fein unterteilen wie du moechtest (wie Dein Timer kann) und dann einfach n fache davon in den Timer laden und dann entsprechend zuenden...

  5. #5
    Nur ein paar Dinge, die mir aufgefallen sind.

    phaseAngleTiming[257] ist 257 lang.
    Dein next_trigger ist unsigned char ( 0..255 )
    also erreichst du nie die letzen werte des arrays.


    Im Interrupt0 wird next_trigger = 1;
    also erreichst Du nie phaseAngleTiming[0]



    if(!btn1){
    btn1_time = btn1_time + (t_msec - old_msec);

    heist das - wenn Button 1 nicht gedrückt ist ?
    Wolltest Du da nicht auf gedrückt abfragen ( if(btn1){ )



    if (ch1_level >=255){
    ch1_level = 0;

    schadet nicht - ist aber auch nicht sinvoll.
    ch1_level wird nie groesser als 255 - ist ja unsigned char.
    Wenn nach 255 eine 1 addiert wird, geht er sowieso auf 0


    Gruss
    Frank

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.09.2004
    Ort
    In der Nähe von Esslingen am Neckar
    Beiträge
    706
    hallo getaco,
    warum muss dein erstes C programm gleich auch so riesig sein!!! Fang lieber erst mit kleineren an!
    Gruß Michi

  7. #7
    Nach was -

    was fuer einen Prozessor nimmst Du ?

    Du hast mit
    unsigned const int phaseAngleTiming[257]
    ja schon 257*2 Bytes Ram verbraten.
    Es gibt AVR Prozessoren mit 512 Byte Ram.
    Wenn Du so einen hast, dann hast Du auf jeden Fall den Speicher überladen.

    Kannst Diese Tabelle ja mal in's Flash legen.
    #include <avr/pgmspace.h> hast Du ja schon drin,
    nur noch nicht genutzt.

    Frank

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    08.05.2005
    Alter
    48
    Beiträge
    33
    Danke euch allen dass ihr so zahlreich geantwortet habt.

    @ Psiyou : Ich habe bereits ein programm in Bascom geschrieben und das funtz mit der gleichen methode wie die aus dem C teil. Aber hast schon recht der verlauf ist fast egal.

    @fwallenwein: Dass phaseAngleTiming[257] ist liegt nur daran dass ich bereits soviel rumgespielt und getested habe, und dabei halt auch des array auf 257 anstelle von 255 bzw 256. Da fällt mir gerade ein : Wo begint ein array in winavr bei array[0] oder array[1]?
    zum next_trigger im Int0 der muss auf 1 weil der Nullte (0) eigentlich der reale nulldurchgang der phase ist.

    !btn1 ist richtig die taster gehen gegen masse.

    die If(ch1_level) geschichte ist mir auch klar nur wust ich meinen fingern keinen rat mehr und hab überal hinzugefügt und weg kommentiert

    @michaelb : Warum? ist doch ein schönes kleines Problemschen das ich habe aber hast schon recht nur hab ich keinen bock auf "kleine" programme.


    Nochmal @fwallenwein : AHA :-O soviel Ram verbraten Hae? keine Ahnung Bascom hat mir das immer abgenommen Achso hmm dann sind die 103% die der compiler mir zeigt das ram Und wie krieg ich die variable ins flash ? Also mal ehrlich das mir dem Include hab ich irgendwo rauskopiert

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    04.04.2005
    Ort
    Hamburg <-> Bremen
    Alter
    43
    Beiträge
    112
    In C beginnt das Arry immer bei 0 !!
    (Array variable ist Pointer auf das erste Element im Array).

  10. #10
    Zitat Zitat von Getaco
    Danke euch allen dass ihr so zahlreich geantwortet habt.
    Bitte !

    Zitat Zitat von Getaco
    @fwallenwein: Da fällt mir gerade ein : Wo begint ein array in winavr bei array[0] oder array[1]?
    Bei 0

    Zitat Zitat von Getaco
    !btn1 ist richtig die taster gehen gegen masse.
    Dann müssen wir uns aber das nochmal anschauen
    Also, wenn die Taste gedrückt ist :

    Wenn Taste Gedrückt.............if (!btn1){
    wenn Zeit >= 150....................if (btn1_time >= 150){
    Zeit = 149.................................btn1_time=149;
    und Level hochzählen.................ch1_level = ch1_level + 1;

    in der nächsten Millisekunde wir in

    ....if (old_msec != t_msec){
    ........if(!btn1){
    .............btn1_time = btn1_time + (t_msec - old_msec);

    die Zeit wieder von 149 auf 150 hochgesetzt.
    Also kommt er in der nächsten millisekunde wieder
    in die If abfrage oben rein, zaehlt den level wieder hoch,
    setzt Zeit wieder auf 149 usw. usw.

    Hab ich das richtig verstanden ? Ist das so gewollt ?

    Zitat Zitat von Getaco
    Nochmal @fwallenwein : AHA :-O soviel Ram verbraten Hae? keine Ahnung Bascom hat mir das immer abgenommen Achso hmm dann sind die 103% die der compiler mir zeigt das ram Und wie krieg ich die variable ins flash ? Also mal ehrlich das mir dem Include hab ich irgendwo rauskopiert
    Ins Flash ist einfach :
    unsigned const int phaseAngleTiming[257] PROGMEM = {
    ....
    }

    rauslesen - da muss ich auch erst mal wieder die Doku befragen.
    Ich habe immer Strukturen in's Progmem gelegt, und diese zum bearbeiten mit "memcpy_P" ins RAM geholt.
    Aber da müsste ich selbst erst in der Doku nachlesen.
    Weiss ich nicht mehr auswendig.

    Gruss
    Frank[/code]

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

Solar Speicher und Akkus Tests