Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit ADC
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:
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:
prozent_istwert=adc(1);
Und jetzt kommt nach das Unterprogramm selber:
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?
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
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
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
So hier ist der ganze Code:
1. der Header
#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:
#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,prozen t_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):
//_________________________________________Initialis ieren 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;
}
//__________________________________________________ __________________________________________________ ______________
//________________________________________Vergleichs wert 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)
#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=s telle_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!
5.Unterprogramme(adc_init, adc)
float prozent_wert; //Prozent wert nach ADC
//unsigned char kanal; //Variable wird bei der Funktion adc(kanal) übergeben
//_______________________________________initialisie ren 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.Unterprogramme:(senden, receive, uart_init)
#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;
//___________________________________________Initial iseren 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++;
}
//___________________________________________Program m 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.Unterprogramme:(timer8_init)
#include "funktion.h" //Header für meine eigen angelegten Funktionen
//_______________________________________initialisie ren 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)
#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!!!!
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
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
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.