So hier ist der ganze Code:
1. der Header
2. Das Hauptprogramm: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
3. Unterprogramme(pwm_init, pwm_vergleichswert):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 }
4.UnterprogrammeCode://_________________________________________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; }BCC, 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!







Zitieren

Lesezeichen