-         

Ergebnis 1 bis 8 von 8

Thema: Problem mit ADC

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    01.02.2006
    Beiträge
    19

    Problem mit ADC

    Anzeige

    Da das letzte Problem gelöst ist habe ich ein schon wieder ein neues Problem:

    In meinem Programm verwende ich den Timer Interrupt: SIG_Overflow 0, dieser wird auch ausgelöst, nun möchte ich aber auch noch einen Analog Wert einlesen!

    Ich habe am Anfang meines Programm den ADC so initialisiert:
    Code:
    void adc_init(void)
    	{
    	ADMUX=0x00;							
    
    	ADCSRA=(1<<ADEN);					
    	ADCSRA|=(1<<ADPS2)|(1<<ADPS1);		
    	
    	SFIOR=0x00;													
    	}
    Und dann habe ich noch das Unterprogramm für den ADC im SIG_OVERFLOW0 aufgerufen:

    Code:
    prozent_istwert=adc(1);
    Und jetzt kommt nach das Unterprogramm selber:
    Code:
    float adc (unsigned char kanal)
    	{
    	long int x;
    	
    	
    	ADMUX |= kanal;						
    	ADCSRA|=(1<<ADSC);					
    		
    	while(ADCSRA&(1<<ADSC))			
    		;
    	
    	x=ADCL+ADCH*256;					
    									
    	
    	prozent_wert=(x*100)/1024;		
    									
    	return(prozent_wert);
    	
    	}

    Das Problem ist: wenn ich in das Unterprogramm gehe für den ADC, steigt er mir plötzlich aus und startet das Programm neu!!!

    Zumindest ist es so im AVR STUDIO!
    Deshalb meine Frage: Ist das nur im Studio so??? Weiß jemand warum das ist? Und was man dagegen tun kann?

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.11.2005
    Alter
    42
    Beiträge
    1.140
    Dem Symptom nach zu urteilen hast Du noch irgendeinen Interrupt aktiviert, zu dem keine Interrupt-Routine existiert. Dann wäre der Effekt erklärbar.

    askazo

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    01.02.2006
    Beiträge
    19
    Weißt du vielleicht auch noch wo man dort nachschauen kann, denn im C-Code selber habe ich nur einen UART Interrupt und diesen SIG_OVERFLOW0 Interrupt!!!

    Das komische aber ist: wenn ich es austeste, habe ich anscheinend einen Wert gewandelt!!

    Eine weitere Frage hätte ich auch noch, nämlich:
    Ich möchte auch noch PWM verwenden, habe vor ein paar monaten ein kleines Testprogramm geschrieben, welches einbandfrei funktioniert.

    Nun in meinem großen Programm funktionert dieses PWM nicht mehr!

    Ich hätte eine Ahnung. Kann es sein, dass der SIG_OVERFLOW0 das PWM beeinträchtig??

    Ich verwende einen ATMEGA 8535!! (Wenns hilft)

    MFG

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.11.2005
    Alter
    42
    Beiträge
    1.140
    Nachschauen kannst Du nur in Deinem Programm
    Hast Du denn für den UART-Interrupt auch schon die Interrupt-Routine geschrieben und auch im Programm mit drin?

    Zur PWM: Der Interrupt dürfte die PWM eigentlich nicht beeinflussen, es sei denn, die PWM läuft auch auf Timer 0.

    Kannst Du nicht mal ein wenig mehr von Deinem Programm posten? Das würde die Suche sehr vereinfachen...

    askazo

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    01.02.2006
    Beiträge
    19
    So hier ist der ganze Code:

    1. der Header

    Code:
    #ifndef __funktion.h__
    #define __funktion.h__
    
    #include<avr/io.h>				//allgemeine Header
    #include<math.h>				//Header für pow() funktion
    #include<string.h>
    #include<avr/signal.h>
    //#include <avr/interrupt.h>
    
    //----------------------------ADC-------------------------------
    
    inline void adc_init(void);
    
    float adc(unsigned char);
    
    //--------------------------------------------------------------
    
    
    
    //---------------------------UART-------------------------------
    
    inline void uart_init(void);
    
    void receive(void);				//zum erhalten der Daten
    
    void senden(char sende_string[]);					//wenn printf, wird das nicht benötigt
    
    //void string_empf(void);
    
    //--------------------------------------------------------------
    
    
    
    //---------------------------8Bit Timer-------------------------
    
    inline void timer8_init(void);
    
    //--------------------------------------------------------------
    
    
    //---------------------------PWM-------------------------------
    
    void pwm_init(void);
    
    inline void pwm_vergleichswert(int);
    
    //-------------------------------------------------------------
    
    
    
    //---------------------------Regler---------------------------
    
    int regler_funct (float, float, float, float);
    
    //------------------------------------------------------------
    
    //------------------------- Protokoll-------------------
    
    char BCC (char pc_daten[]);
    
    void auswerten(void);
    
    float zeichentofloat_daten(unsigned char string_teil[],char start, char stop);
    
    void nachricht(void);
    
    //void werte_schicken(unsigned char);
    
    //------------------------- Variablen-------------------------
     #define DATEN_LEN_MAX 20
     
     extern float prozent_wert;					//Prozent wert nach ADC
     extern int vergleichswert;			//Der vergleichwert bei PWM(OCR1A), in Regler.c verwendet
     //unsigned char kanal;					//Variable wird bei der Funktion adc(kanal) übergeben
     extern unsigned char pc_daten[DATEN_LEN_MAX];				//Das Feld in der ich die einzelnen Zeichen die ich vom PC bekomme reinspeichere, in protokoll.c verwendet
     extern char fehler;					//in protokoll.c, Die Variable in der das Ergebnis von BCC(pc_daten) gespeichert wird
     extern char start_brenn;				//in Regler.c verwendet
     //extern char mein_bcc;					
     extern float kurven_temp[10];			//in Protokoll.c verwendet, zum abspeichern der erhaltenen Temperatur Daten
     extern float kurven_zeit[10]; 			//in Protokoll.c verwendet, zum abspeichern der erhaltenen Zeit Daten
     extern unsigned char sende_string[20];	//für nachricht(), zum string generieren, in protokoll.c
     extern unsigned char j;                 //für string empfangen, in receive()
     extern unsigned char zeichen_empf;		//in Regler.c verwendet,(UART Interrupt)
     extern unsigned char zeit_abfrage;		//in Regler.c verwendet, für zeit abfrage
     extern unsigned char anz;				//in Protokoll.C verwendet
     extern int zaehlen;						//in Regler.C verwendet(Timer Interrupt)
     extern int zeit;							//in Regler.C verwendet (Timer Interrupt)
     extern float aktuelle_zeit;					//in Regler.C verwendet
     extern char uebert_beendet;				//in Regler.c, Hilfsvariable zum erkennen wann der erhaltene String zu Ende ist
     
    //Regler_funct.c Variablen
     
     
     extern float prozent_istwert;			//Nach ADC wandlung, auf Prozent*100 umgerechnet, Das ist der Istwert des Reglers
     extern float prozent_sollwert;		//Nach ADC wandlung, auf Prozent*100 umgerechnet, Das ist der Sollwert des Reglers
     extern float kp;						//die Reglerverstärkung
     extern float tn;						//die Nachstellzeit, für I-Anteil
    
     
    //------------------------------------------------------------
    #endif
    2. Das Hauptprogramm:
    Code:
    #include "funktion.h"
    
    int vergleichswert;			//Der vergleichwert bei PWM(OCR1A)
    char start_brenn;
    unsigned char zeit_abfrage;
    char uebert_beendet;
    float hzeit;
    unsigned char m;
    unsigned char zeichen_empf;
    int zaehlen;
    int zeit;
    float aktuelle_zeit;
    
    
    int main(void)
    	{
    	
    	
    	
    	SREG|=(1<<7);					//das I-Bit auf "1" setzen, für Overflow Interrupt
    	
    	DDRB=0x00;						//Datenrichtung von PORTB (Eingang)
    	DDRC=0xFF;						//Datenrichtung von PORTC (Ausgang)
    	DDRD=0xFF;						//Datenrichtung von PORTD (Ausgang) für PWM(PD5)
    	DDRA=0x00;						//Datenrichtung von PORTA (Eingang) für ADC(PA0)
    	
    	PORTC=0x01;
    	
    	/*Variablen Dekleration*/	
    	PORTB=0xFF;																	//PortB auf Pull up setzen
    	//kanal=0;																	//Kanal auf 0 (PA0) verwenden
    	aktuelle_zeit=0;
    	start_brenn=0;
    	anz=0;										//Feldindex für kurven_temp und kurven_zeit, damit nur bei erhalten eines ganzen
    												//strings die Variable hinaufgezählt wird
    	zaehlen=0;
    	PORTC=0x01;
    	m=0;
    	zeit=0;
    	j=0;
    	uebert_beendet=0;
    	zeit_abfrage=0;
    	
    	kp=2;										//angenommenes kp
    	tn=0.6;										//angenommene Tn
    
    	//PORTC=0x01;
    	
    	
    	
    	adc_init();						//Funktion: ADC initialisieren(Register)
    
    	uart_init();					//Funktion: UART initialisieren(Register)
    	
    	
    	sende_string[0]='\0';
    		
    
    	
    	
    	/*
    	kurven_zeit[0]=2.00;				kurven_temp[0]=50;
    	kurven_zeit[1]=300;				kurven_temp[1]=50;
    	kurven_zeit[2]=500;				kurven_temp[2]=100;
    	
    	start_brenn=1;
    	
    	PORTC=0x00;
    	hzeit=kurven_zeit[0];
    	*/
    	start_brenn=1;
    	
    	while(1)
    		{
    		pwm_init();
    		if(start_brenn==0&&uebert_beendet==0)
    			{
    			
    			while(uebert_beendet==0)						//Es wird solange receive() aufgerufen bis die übertragung beendet ist
    				{											// solange bis ein 'y' gesendet worden ist
    				PORTC=0xF0;
    				
    				if(zeichen_empf==1)
    					{
    					receive();
    					zeichen_empf=0;
    					}
    				}
    			
    				
    			uebert_beendet=0;							//danach wird die Variable wieder auf 0 gesetzt wür das nächste mal
    			j=0;
    			
    			if(start_brenn==0)
    				{
    				fehler=BCC(pc_daten);						//Beim erhaltenen String wird gleich BCC bestimmt, und mit dem erhaltenen verglichen
    				auswerten();								// zum abspeichern der Daten
    				}
    			
    			if(start_brenn==1)
    				{
    				fehler=BCC(pc_daten);						//Beim erhaltenen String wird gleich BCC bestimmt, und mit dem erhaltenen verglichen
    				auswerten();								//zum abspeichern der Daten
    				}
    			}
    			
    			
    			
    			
    		
    		if(start_brenn==1)
    			{
    			PORTC=0xF0;
    			//pwm_init();					//Funktion: 10 Bit PWM mit Phasen Correct Mode (Register)
    			//OCR1A=512;
    			timer8_init();						//Funktion: 8 Bit Timer initialisieren(Register)
    			
    			if(zeichen_empf==1)
    				{
    				PORTC=0x0F;
    				while(uebert_beendet==0)						//Es wird solange receive() aufgerufen bis die übertragung beendet ist
    					{											// solange bis ein 'y' gesendet worden ist
    					//PORTC=0x80;
    				
    					if(zeichen_empf==1)
    						{
    						receive();
    						zeichen_empf=0;
    						}
    					}
    				uebert_beendet=0;							//danach wird die Variable wieder auf 0 gesetzt wür das nächste mal
    				}
    			
    			if(zeit_abfrage==1)
    				{
    				fehler=BCC(pc_daten);						//Beim erhaltenen String wird gleich BCC bestimmt, und mit dem erhaltenen verglichen
    				auswerten();								//Die Funktion auswerten() wird auch aufgerufen
    				
    				zeit_abfrage=0;
    				//PORTC=0x01;
    				}
    			
    			if(aktuelle_zeit<=hzeit)
    				{
    				prozent_sollwert=kurven_temp[m];
    				}
    			else
    				{ 
    				m++;
    				prozent_sollwert=kurven_temp[m];
    				hzeit=kurven_zeit[m];		
    				}
    			
    			}
    		
    		}
    	}
    	
    	
    	
    //___________________________________________RXC Interrupt____________________________________________________________________
    
    
    SIGNAL(SIG_UART_RECV)
    	{
    	zeichen_empf=1;
    	}
    
    //__________________________________________TIMER0 Overflow____________________________________________________________________________
    
    
    SIGNAL (SIG_OVERFLOW0)
    	{
    	zaehlen++;
    		
    	
    	
    	if(zaehlen==30)								//ausgerechnet für  Sekunde pro Timer overflow
    		{			
    		//OCR1A=0;
    		
    		if(zeit==0)
    			zeit=1;
    		else
    			zeit=zeit+1;  						//zeit in sek.
    		
    		prozent_istwert=adc(1);			//den wert von der Funktion adc() in Prozent istwert schreiben
    		//prozent_sollwert=adc(2);		
    		
    		vergleichswert=regler_funct(prozent_istwert,prozent_sollwert,kp,tn);
    				
    		pwm_vergleichswert(vergleichswert);
    		
    		//prozent_istwert=0;
    		zaehlen=0; 
    
    		//PORTC=0xFF;
    		
    		}	
    	aktuelle_zeit=(zeit*100)/60;			//Mit Franz vereinbart, Minuten mal 100
    
    	}
    3. Unterprogramme(pwm_init, pwm_vergleichswert):
    Code:
    //_________________________________________Initialisieren des Timers________________________________________________
    
    void pwm_init(void)
    	{
    										//Für Puslweiten, Datenrichtung für PD5 auf Ausgang
    	PORTC=0x0F;
    	
    	TCCR1A=(1<<COM1A1)|(1<<COM1A0); 			// wird OC1A/OC1B zum vergleichen, clear bei TOP
    	
    	//zum auswählen von Phasen Correct Mode
    	TCCR1A|=(1<<WGM11)|(1<<WGM10);
    	
    
    	TCCR1B=(1<<CS10);						//Takt: Im Timer ControlRegister den Takt für den Prescaler festlegen
    											//jetzt wird die Oszillator Freqzenz verwendet (8 MHz)    
    	//OCR1A=512;
    
    	}
    //__________________________________________________________________________________________________________________
    
    
    
    //________________________________________Vergleichswert bestimmen__________________________________________________
    
    void pwm_vergleichswert(int vergleichswert)
    	{
    	int hilfpwm;
    	
    	//hilfpwm=1024-vergleichswert;
    	hilfpwm=vergleichswert;
    	if(hilfpwm<=10)
    		{
    		hilfpwm=21;
    		}
    	
    	if(hilfpwm>=1000)
    		{
    		hilfpwm=1023;
    		}
    	
    	//OCR1A= hilfpwm-10;
    	OCR1A=hilfpwm;
    	//OCR1A=512;
    	}
    4.UnterprogrammeBCC, auswerten, zeichentofloat_daten, nachricht)

    Code:
    #include "funktion.h"					//Header für meine eigen angelegten Funktione
    #include <stdlib.h>
    
    unsigned char pc_daten[DATEN_LEN_MAX];						//Das Feld in der ich die einzelnen Zeichen die ich vom PC bekomme reinspeichere (auswerten)
    float kurven_temp[10];
    float kurven_zeit[10];
    char fehler;           					//Die Variable in der das Ergebnis von BCC(pc_daten) gespeichert wird
    unsigned char sende_string[20];
    unsigned char anz;
    
    
    char BCC(char string[])				//Es werden die pc_daten übergeben
    	{ 
    	char ergebnis;						//Variable in der das Ergebnis des BCC abgespeichert wird
    	unsigned char n;							//Laufvariablen
    	char ok;							//sollte eine Variable zum überprüfen sein
      
    	ok=0;								//Am Anfang auf "0" gesetzt
    	ergebnis='\0';
    	
    	for( n=0;n<30;n++)
    		{
    		if(string[n]=='x')				//das Daten feld wird durchgelaufen, und überprüft ob ein 'x' drinnen ist
    			{   						//wenn ja, dann wird OK=1 gesetzt und die For schleife verlassen
    			ok=1;
    			break;	
    			}
    		}
    
    	if (ok==1)							//wenn 'x' drinnen ist, dann geht er in diesen Zweig
    		{ 
    		for(unsigned char k=n+1;k<60;k++)
    			{
    			if(k==n+1)					//wenn er das erste mal die Forschleife durchläuft, dann soll er als ergebnis
    				{						//das nächste zeichen nach dem 'x' übernehmen
    				ergebnis=string[k];
    				}
    			else						//wenn er die For schleife nicht zum ersten mal durchläuft, dann
    				{
    				ergebnis=ergebnis^string[k];		//soll er das ergebnis mit dem Zeichen EXOR verknüpfen
    				}
    
    			if(string[k]=='y')		//Wenn das übernächste Zeichen ein 'y' ist, dann soll er die For schleife verlassen
    				break;
    			}
    		}
    	
    	return(ergebnis);					//als char soll er ergebnis zurück liefern
    	}
    
    
    
    void auswerten(void)					
    	{
    	unsigned char i;
    	//unsigned char l;
    	char stelle_z, stelle_y, stelle_i,stelle_komma; 
    	unsigned char stelle_bcc,r;
    	char bcc_ok;
    	
    	
    	stelle_komma=stelle_bcc=stelle_z=stelle_i=bcc_ok=stelle_y=0; 
    	
    	
    	for(unsigned char l=0;l<60;l++)					// In dieser Schleife speichere ich jeweils die Stelle von 'z', 'i', und 'd' ab
    		{
    		
    		switch(pc_daten[l])
    			{
    			case 'z': stelle_z=l;		//zum herausfinden, an welcher stelle der jeweilige Buchstabe abgespeichert ist
    					   
    			case 'i': stelle_i=l;
    					   
    			//default: break;
    			}
    		
    		if(pc_daten[l]=='y')			//Hier wird die Stelle von Bcc herausgefunden
    			{
    			stelle_y=l;
    			stelle_bcc=l+1;				//Hier wird die Stelle vom BCC hinein gespeichert	
    			
    			if(fehler==pc_daten[stelle_bcc]&&zeit_abfrage==0)		//Wenn das vorher ausgerechnete eigene BCC gleich dem erhaltenen ist
    				{
    				sende_string[0]='x'; sende_string[1]='y';  sende_string[2]='\0';
    				senden(sende_string);
    				sende_string[0]='\0';
    				bcc_ok=1;
    				break;
    				}
    				
    			if(fehler==pc_daten[stelle_bcc]&&zeit_abfrage==1)
    				{
    				nachricht();
    				senden(sende_string);
    				sende_string[0]='\0';
    				break;
    				}
    			else
    				{
    				bcc_ok=0;
    				sende_string[0]='B'; sende_string[1]='C';  sende_string[2]='C';  sende_string[3]=fehler;   sende_string[4]=pc_daten[stelle_bcc];  sende_string[5]='\0'; 
    				senden(sende_string);
    				sende_string[0]='\0';
    				break;
    				}
    			
    			}
    		}
    	for(r=0;r<60;r++)
    		{
    		
    		if(pc_daten[r]=='x')
    			break;
    		}
    	
    	if(pc_daten[0+r]=='x'&&bcc_ok==1&&start_brenn==0)	
    		{								//wenn das erste Zeichen ein 'x' ist soll er in diesen Zweig gehen
    		
    		for(i=1+r;i<60;i++)
    			{
    			
    			switch(pc_daten[i])		//Es wird überprüft wo ein 't','z','p','i','d'
    				{
    				case 't': //	if(fehler!='t'&&pc_daten[i-1]!='y')
    								{
    								kurven_temp[anz]=zeichentofloat_daten(pc_daten,stelle_z,i);  	//es wird pc_daten, die stelle vom z und die aktuelle stelle(i) übergeben
    								break;	
    								}
    									
    				case 'z':	//if(fehler!='z'&&pc_daten[i-1]!='y')
    								{
    								kurven_zeit[anz]=zeichentofloat_daten(pc_daten,stelle_y,i);	//es wird pc_daten, die stelle vom bcc und die aktuelle stelle(i) übergeben
    								//PORTC=0x0F;
    								/*
    								werte_schicken(anz);
    								senden(sende_string);
    								sende_string[0]='\0';
    								PORTC=0x0F;
    								*/
    								anz++;
    								break;	
    								}
    				
    				case 'p':  if(fehler!='p'&&pc_daten[i-1]!='y')
    								{
    								kp=zeichentofloat_daten(pc_daten,stelle_i,i);					//es wird pc_daten, die stelle vom i und die aktuelle stelle(i) übergeben
    								break;
    								}
    				
    				case 'i':  if(fehler!='i'&&pc_daten[i-1]!='y')
    								{
    								tn=zeichentofloat_daten(pc_daten,stelle_y,i);					//es wird pc_daten, die stelle vom d und die aktuelle stelle(i) übergeben
    								break;
    								}
    				
    				default: break;
    				}
    								
    			if(fehler==pc_daten[i+1])
    				break;
    				
    			}
    		
    		}
    		bcc_ok=0;
    	
    	}
    	
    
    float zeichentofloat_daten(unsigned char string_teil[],char stop, char start)			//Funktion: Aus Zeichen wird eine Gleitpunktzahl gemacht
    	{
    	unsigned char k,m,n, stelle_komma;				
    	float ganzzahl;
    	float kommazahl;
    	float gleitpunktzahl;
    	double zw_speicher;
    	m=0;										//muss am anfang auf 0 sein!
    	n=1;										//muss am anfang auf 1 sein!
    	stelle_komma=kommazahl=ganzzahl=0;			//am anfang sicherheitshalber auf 0 gesetzt
    	
    	for(k=start+1;k<stop;k++)					//hier wird überprüft, ob in dem Teilstring von start bis stop ein Komma vorliegt
    		{
    		if(string_teil[k]==',')
    			{
    			stelle_komma=k;						//wenn ja, dann wird die Stelle abgespeichert
    			break;
    			}
    		}
    
    	if(stelle_komma>0)							//ist ein komma vorhanden, dann wird eine For Schleife gestartet, von
    		{										//Komma+1 weg bis stop
    		for(k=stelle_komma+1;k<stop;k++)
    			{
    			zw_speicher=pow(10,-n);
    			kommazahl=kommazahl+zw_speicher*(string_teil[k]-48);		//es wird immer zur kommazahl, das aktuelle zeichen mit 10 hoch -n multipliziert, -48 wegen Hex auf Dec
    			n++;												//ist die Wertigkeit für pow() funktion
    			}
    		
    		for(k=stelle_komma-1;k>start;k--)		//Komma-1 weg bis start
    			{
    			zw_speicher=pow(10,m);
    			ganzzahl=ganzzahl+zw_speicher*(string_teil[k]-48);			//es wird immer zur kommazahl, das aktuelle zeichen mit 10 hoch -n multipliziert, -48 wegen Hex auf Dec
    			if(m==0)
    				ganzzahl=ganzzahl*2;
    			m++;													//ist die Wertigkeit für pow() funktion
    			}
    		}
    	else										//ist kein komma vorhanden, dann wird eine For Schleife gestartet, von				
    		{
    		for(k=stop-1;k>start;k--)		//Komma-1 weg bis start
    			{
    			ganzzahl=ganzzahl+pow(10,m)*(string_teil[k]-48);			//es wird immer zur kommazahl, das aktuelle zeichen mit 10 hoch -n multipliziert, -48 wegen Hex auf Dec
    			if(m==0)
    				ganzzahl=ganzzahl*2;
    			m++;													//ist die Wertigkeit für pow() funktion
    			}
    		}
    
    	
    	gleitpunktzahl=ganzzahl+kommazahl;				
    		
    	return( gleitpunktzahl );				//als float return geliefert
    	}
    
    
    
    void nachricht(void)
    	{
    	
    	unsigned char hstring[5],bcc_senden;
    	unsigned char laenge1,laenge;
    	int zw_speicher_istwert,zw_speicher_aktuellezeit;
    	
    	for(unsigned char i=0;i<20;i++)
    		{
    		sende_string[i]='\0';
    		}
    	
    	sende_string[0]='x';
    	sende_string[1]='t';
    	
    	zw_speicher_istwert=prozent_istwert*10;
    	
    	itoa(zw_speicher_istwert,hstring,10);
    	
    	strcat(sende_string,hstring);
    	
    	laenge=strlen(sende_string);
    	sende_string[laenge]='z';
    	
    	zw_speicher_aktuellezeit=aktuelle_zeit;
    	itoa(aktuelle_zeit,hstring,10);
    	
    	strcat(sende_string,hstring);
    	
    	laenge1=strlen(sende_string);
     	sende_string[laenge1]='y';
    	
    	bcc_senden=BCC(sende_string);
    	sende_string[laenge1+1]=bcc_senden;
    
    	}

    Bei der nächsten Nachricht geht es weiter, darf nicht mehr wie 20000 Zeichen!

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    01.02.2006
    Beiträge
    19
    5.Unterprogramme(adc_init, adc)

    Code:
    float prozent_wert;					//Prozent wert nach ADC
    //unsigned char kanal;			//Variable wird bei der Funktion adc(kanal) übergeben
    
    //_______________________________________initialisieren der ADC Register____________________________________________
    
    void adc_init(void)
    	{
    	ADMUX=0x00;							//Den AusgangsPin 0 zum vergleichen festgelegt, Vref ist turned off
    
    	ADCSRA=(1<<ADEN);					//ADC  Enablen
    	ADCSRA|=(1<<ADPS2)|(1<<ADPS1);		//Prescaler Quotient festgelgt: 64, damit die Frequenz: 125kHz ist
    	
    	SFIOR=0x00;							//für den Free Running Mode(die ersten 3 Bits =0), die anderen brauchen wir nicht						
    	}
    //__________________________________________________________________________________________________________________
    
    
    //__________________________________________Free Running Mode_______________________________________________________
    
    float adc (unsigned char kanal)
    	{
    	long int x;
    	
    	
    	ADMUX |= kanal;						//Zum einstellen des Kanals(Vergleichs Pin an der Platine)
    
    	ADCSRA|=(1<<ADSC);					//Vergleich starten
    		
    	while(ADCSRA&(1<<ADSC))			//Warten bis der Vergleich zu Ende ist, dann wird das ADSC wieder auf "0" gesetzt
    		;
    	
    	x=ADCL+ADCH*256;					//Den wert des Hight und Low Registers in einer Variable zusammengefügt
    	
    	//return(x);				//Herauslesen der beiden Register, ADCH*256 weil man ja schon 8 Bits belegt hat
    											//:4 weil man sonst 1024 als höchsten Wert hat, man möchte es aber auf die 
    											//8 Leds ausgeben, deshalb 1024/4= 256(jetzt nicht mehr dabei, weil wir ja eine
    											//10 Bit Auflösung haben wollen!!!
    	
    	prozent_wert=(x*100)/1024;		//prozent_sollwert/100= x/1024--> damit habe ich einfach die Prozent ausgerechnet
    									
    	return(prozent_wert);
    	
    	}
    //__________________________________________________________________________________________________________________
    6.Unterprogrammesenden, receive, uart_init)

    Code:
    #include "funktion.h"			//Header für meine eigen angelegten Funktionen
    
    
    //_____________________________________Baudrate Berechnung____________________________________________________________________
    
    #define F_CPU 8000000  			//CPu mit einen 8Mhz Taktfrequenz definiert
    #define UART_BAUD_RATE 19200		// Baud Rate wie bei Serieller mit 9600 festgelegt
    
    //____________________________________________________________________________________________________________________________
    
    //Variabeln
    
    unsigned char j;
    
    
    //___________________________________________Initialiseren der UART Register__________________________________________________
    
    void uart_init(void)
    	{
    	UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);		/*USART settings: Parity=disable(das wäre mit Bit UPM1:0=0), 
    													  character size=8Bit(Mit UCSZ1:0)*/
    
        UCSRB=(1<<RXEN)|(1<<TXEN)|(1<<RXCIE);				/*Transmitter enabled(TXEN) (zum Senden an den PC) und TRansmitter 
    												   Data bit 8gesetzt ist (TXB8)*/
    											/*Receiver enabled(RXEN) (zu empfangen vom PC) und Receiver Data Bit 8 
    												  gesetzt ist (RXB8)*/
    												 
    												 //RXCIE Interrupt Enable
    												  
    	UBRRL=F_CPU/(UART_BAUD_RATE*16L)-1;		//Formel zum Berechnen der UART Bade Rate Register (Baudrate =51)
    	//UBRRH=0;
    	}
    //____________________________________________________________________________________________________________________________
    
    
    
    //______________________________________________________________________________________________________________________________
    
    void receive(void)
    	{
    	pc_daten[j]=UDR;
    	
    	if(pc_daten[j-1]=='y')					//Wenn bei den Abgespeicherten Daten ein 'y' schon vorhanden ist,
    		{									//ist die übertragung beendet, und die Variable uebert_beendet=1 gesetzt
    		uebert_beendet=1;					//und die For Schleife wird verlassen
    			
    		if(pc_daten[j-2]=='b'&&pc_daten[j-3]=='x')
    			{
    			start_brenn=1;
    			}
    			
    		if(pc_daten[j-2]=='a'&&pc_daten[j-3]=='x')
    			{
    			zeit_abfrage=1;
    			}
    		
    		}	
    		
    	if(j>=60)
    		j=0;
    	
    	if(uebert_beendet==1)
    		j=0;
    	else
    		j++;
    	}
    
    
    //___________________________________________Programm von senden()____________________________________________________________
    
    void senden(char sende_string_pc[])
    	{
    	
    	for(unsigned char i=0;i<=20;i++)
    		{
    		while(!(UCSRA&(1<<UDRE)))					//zuerst muss ich warten bis das Daten Register leer ist, damit ich nichts überschreibe
    			;
    		
    		if(sende_string_pc[i]=='\0')
    			break;
    		
    		UDR=sende_string_pc[i];									//dann überschreibe ich ins Daten Register die zu sendenden Daten
    	
    		while(!(UCSRA&(1<<TXC)))					//dann warte ich wieder bis die Sendung komplett ist
    			;
    		
    		}
    		
    	//return;										//Kein Rückgabe Wert
    	}
    //____________________________________________________________________________________________________________________________
    7.Unterprogrammetimer8_init)

    Code:
    
    #include "funktion.h"					//Header für meine eigen angelegten Funktionen
    
    
    
    
    //_______________________________________initialisieren des 8 Bit Timer Registers____________________________________________
    
    void timer8_init(void)
    	{
    	
    	TCCR0=(1<<CS02)|(1<<CS00);	//Takt: Im Timer ControlRegister den Takt für den Prescaler festlegen
    								//wenn CS02&CS00=1 dann Oszillator Frequ./1024=7812,5
    								//7812,5/256=30,51     t=1/30,51  
    	TIMSK=(1<<TOIE0);			//Interrupt Enable
    
    	}
    //___________________________________________________________________________________________________________________________
    8.Unterprogramme(regler_funct)

    Code:
    #include "funktion.h"
    
     float prozent_istwert;			//Nach ADC wandlung, auf Prozent*100 umgerechnet, Das ist der Istwert des Reglers
     float prozent_sollwert;		//Nach ADC wandlung, auf Prozent*100 umgerechnet, Das ist der Sollwert des Reglers
     float kp;						//die Reglerverstärkung
     float tn;						//die Nachstellzeit, für I-Anteil
    	
    
    
    int regler_funct (float istwert, float sollwert, float kp, float tn)
    	{
    	int hilf;
    	float xd_k,xd_k1,ta;
    	float y_k,y_k1;
    	float b0, b1;
    	int a0, a1;
    
    	ta=1;										//angenommene Abtastzeit (wird bei uns später die Timer Zeit sein)
    	xd_k=0;										//xd_k beim ersten Durchlauf auf 0 setzen, wird später berechnet
    	y_k1=0;
    
    	a0=1;
    	a1=-1;
    	b0=kp*(1+ta/(2*tn));
    	b1=kp*(-1+ta/(2*tn));				//a0,b0,a1,b1 sind die Koeffizienten für einen PI Regler Algorithmus
    	
    	xd_k1=xd_k;							//xd_k1 ist die Differenze von Sollwert und Istwert vom letzten Durchlauf
    	xd_k=sollwert-istwert;				//xd_k ist die derzeitige Differenz von Sollwert und IStwert
    	y_k1=y_k;							//y_k1 ist der Stellwert vom letzten Durchlauf
    	
    	y_k=(b0*xd_k+b1*xd_k1-a1*y_k1)/a0; //Das ist die Formel für einen PI-Regel Algorithmus
    	
    		if(istwert<=sollwert)
    			PORTC=0xFF;
    		else
    			PORTC=0x11;
    	
    		if(y_k<0)										//Wenn bei der Berechnung eine kleinere Stellgröße raus kommt als 0
    			{										//dann soll die Stellgröße 0 sein
    			y_k=0;
    			}
    	
    		if(y_k>100)									//Wenn bei der Berechnung eine größere Stellgröße raus kommt als 100
    			{										//dann soll die Stellgröße 0 sein
    			y_k=100;
    			}
    	/*
    								werte_schicken(y_k);
    								senden(sende_string);
    								sende_string[0]='\0';
    */
    	//y_k=50;
    	hilf=((y_k*1024.0)/100.0);								//Umrechnung von im Verhältnis von Prozent auf die 10 Bit
    	//prozent_istwert=hilf;
    	//hilf=512;
    	
    	
    	return(hilf);
    	}
    Es ist jetzt vor allem das Problem, dass das PWM nicht mehr geht!!!!

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.11.2005
    Alter
    42
    Beiträge
    1.140
    So, ich habe Dein Programm jetzt mal bei mir compiliert.
    Scheint so weit eigentlich alle zu laufen. Er steigt bei mir auch nicht aus, wenn er in die adc-Funktion geht.
    Dass Deine PWM nicht läuft, liegt wohl daran, dass Du die pwm_init() in der while-Schleife dauernd aufrufst. Initialisierungen sollte nur einmal beim Start aufgerufen werden.

    Gruß,
    askazo

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    01.02.2006
    Beiträge
    19
    Ja, das war das Problem!!
    Hab mein PWM init immer wieder durchlaufen!!
    Jetzt habe ich es umgeschrieben, dass es nur noch einmal durchlaufen wird, und jetzt geht es wieder!!!

    Hab gedacht wenns im SImulator geht, gehts in der Praxis auch!!!

    Weiß zwar nicht warum, aber der ADC funktioniert in der Praxis auch, im Simulator zwar nicht, aber wass solls!!

    Vielen Dank für die Hilfe !

    MFG

Berechtigungen

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