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.Unterprogramme
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!
Lesezeichen