Hallo Zusammen,
lang ist es her, da habt Ihr mir bei meinen ADC Problemen bei der Bike Control V1.0 geholfen, und jetzt bei Version 2.1 steh ich schon wieder auf dem Schlauch.
Folgendes Problem:
Ich erzeuge ein 15,6kHz PWM und versorge über zwei Step Down Wandler mit P-FET zweiHochleistungs-LEDs.
Es Funktioniert alles bis auf dass die gegenkopplung des PWMs duch den ADC mysteriöse Verhaltensmuster aufweist. Solange der Sollstrom unter 500mA (=512 ADC) liegt, wird dieser nur minimal von 10 bis 30 mA erhöht. überschreite ich diesen Punkt wird stark aufgedreht bis zu dem hier abgebildeten Betriebspunkt. Eigenartigerweise stecken in der ADC-Eingangsspannung hohe Peaks obwohl da ein 1,5kHz Tiefpass vorgeschaltet ist. Vielleicht gibt es da ein Masseproblem? habe ich Irgendwas im Code falsch gemacht, weil gerade 512 eine so charakteristische Zahl ist. 0-1A durch den 0,5 Ohm Widerstand entsprechen 0-0.5V mit 10-facher verstärkung und 10 Bit Auflösung ergibt dies bei 5V Referenz genau eine Proportionalität zwischen ADC und Strom von 1 zu 1mA.
Außerdem erreiche ich bei 16 MHz Controllertakt und 128 prescaler einen 125kHz internen ADC-Takt und bei 3 kanälen mit 8samples und einem verworfenem Messwert eine Frequenz von 320Hz je Kanal. Geht das nicht auch schneller? Derzeit starte ich nach jedem ADC interrupt den ADC neu, geht das nicht auch direkt fortlaufend?
Code:// Programm for the Bike-Control V2.0 of S.Heidkamp// //**************************************************// //Includes: // #include <avr/io.h> // #include <avr/interrupt.h> // #include <math.h> // #include <stdint.h> // #include <avr/eeprom.h> // // #define F_CPU 16000000UL // #include <util/delay.h> // // // //**************************************************// //INPUTS: A7=ADCBAT;A1=CUR1;A2=CUR2;D2=DOWN(INT0);D3=UP(INT1);C3=LOCKED;B2=ALERT(INT2); D1=POWEROFF volatile uint8_t SOUNDRISE=1; volatile uint8_t WARNINGS=0; volatile uint16_t COUNTDOWN1=0; volatile uint8_t STATUS; volatile uint16_t UBAT=740; volatile uint16_t I1=100; volatile uint16_t I2=100; volatile uint16_t I_SET=100; volatile uint8_t ADC_CHANNEL=0; volatile uint8_t ADC_COUNT=0; volatile uint16_t ADC_TMP=0; volatile uint8_t GREEN_ENABLE=0; volatile uint8_t GREEN_TIMER=0; volatile uint8_t BACK_ENABLE=0; volatile uint8_t BACK_TIMER=0; volatile uint8_t SIDES_ENABLE=0; volatile uint8_t SIDES_TIMER=0; //**************************************************// //Defines // #define TAKT 16000000UL // #define EEPROM __attribute__((section(".eeprom")))// new symbol //INPUTS // #define LOCKED PINC & (1 << PC3) // highactive #define OFFSWITCH !(PIND & (1 << PD1)) // lowactive #define VIBRATION PINB & (1 << PB2) // highactive //OUTPUTS // #define REDON PORTC &= ~(1<<PC7); // lowactive #define REDOFF PORTC |= (1<<PC7); // #define REDISON !(PINC & (1<<PC7)) // #define GREENON PORTC &= ~(1<<PC6); // lowactive #define GREENOFF PORTC |= (1<<PC6); // #define GREENISON !(PINC & (1<<PC6)) // #define BACKOFF PORTB &= ~(1<<PB1); // highactive #define BACKON PORTB |= (1<<PB1); // #define BACKISON PINB & (1<<PB1) // #define SIDESOFF PORTC &= ~(1<<PC4); // highactive #define SIDESON PORTC |= (1<<PC4); // #define SIDESAREON PINC & (1<<PC4) // #define POWEROFF PORTD &= ~(1<<PD0); // highactive #define POWERON PORTD |= (1<<PD0); // #define SIRENOFF TCCR2 &= ~(1<<COM20); //(OC2) #define SIRENON TCCR2 |= (1<<COM20); // #define LIGHTSOFF TCCR1A&= ~((1<<COM1A1)|(1<<COM1B1));// #define LIGHTSON TCCR1A |= (1 << COM1A1)|(1 << COM1B1);// #define NEARON TCCR1A |= (1 << COM1A1); //(OC1A) PD5 #define NEAROFF TCCR1A &=~(1<<COM1A1); // #define FARON TCCR1A |= (1 << COM1B1); //(OC1B) PD4 #define FAROFF TCCR1A &=~(1<<COM1B1); // #define VIBSENSOFF GICR &=~(1<<INT2); // #define VIBSENSON GIFR |= (1<<INTF2);GICR |=(1<<INT2);// //STATUS // #define LIGHT 0 // #define ALLCLEAR 1 // #define NOISE 2 // #define ATTENTION 3 // #define ALERT 4 // #define LOWBAT 5 // #define SLEEP 6 // //BRIGHTNESS #define ULOW 0 // 50 mA #define LOW 1 // 100 mA #define MEDIUM 2 // 350 mA #define HIGH 3 // 700 mA #define PULSE 4 //1000 mA //ADJUSTMENTS // #define ADC_ADJUST -24 // //**************************************************// void tasks(void) { } int main(void) { //Initiator DDRA = 0b00000000; // Output Select DDRB = 0b00000010; // Back DDRC = 0b11010000; // RD GN SIDES DDRD = 0b10110001; PORTD |= (1<<PD5); // NEAR- & FAR-Lights are Lowactive so PD5&4 PORTD |= (1<<PD4); // should be set to Prevent LEDs from Damage MCUCR |= (1<<ISC11)|(1<<ISC10)|(1<<ISC01)|(1<<ISC00);//External Interrupts at rising edge MCUCSR |= (1<<ISC2); // External Interrupt at rising edge GICR |=(1<<INT0)|(1<<INT1); // Enable Buttons POWERON; cli(); //Timer 0 TCCR0 |= (1 << CS00)|(1 << CS02); // normal mode, prescaler 1024 TCNT0 = 256 - 156; // Timer0 mit 156 neu vorladen: 156*1024/4MHz = 9,984ms ~ 10ms TIMSK |= (1 << TOIE0); // Timer0 Interrupt freigegeben //Timer 1 TCCR1A |= (1 << WGM11)|(1 << WGM10); // 10-Bit PWM mode TCCR1B |= (1 << CS10)|(1 << WGM12); // prescaler 1, freq. fixed, 16MHz/2^10=15,625kHz OCR1A = 900; // Standard 10% as start Value OCR1B = 900; // TIMSK |= (1 << TOIE1); // enable overflow interrupt //Timer 2 TCCR2 |= (1 << CS21)|(1 << WGM21); // Prescaler 8 ,PWM 1:1, Freq.=16Mhz/(2*OC2+1*Prescaler) OCR2 = 50; //ADC ADCSRA|= 0b11101111; // ON/start/cont./Int.en./prescaler 128 ->125kHz ADMUX |= 0b01000111; // AREF/right/8 unipol./ADC7 sei(); GREENOFF REDOFF //Mainprogramm while(1) { if(UBAT==0) REDOFF; while(OFFSWITCH) { LIGHTSOFF; GREEN_ENABLE = 0; BACK_ENABLE = 0; SIDES_ENABLE = 0; BACKOFF; SIDESOFF; SIRENOFF; POWEROFF;} //SIRENON; //GREEN_ENABLE = 1; BACK_ENABLE = 1; SIDES_ENABLE = 1; //NEARON; //FARON; //VIBSENSON; LIGHTSON; } return 1; } SIGNAL(SIG_INTERRUPT0) //DOWN Button { if(I_SET >60) I_SET-=50; GIFR |=(1<<INTF0); } SIGNAL(SIG_INTERRUPT1) //UP Button { if(I_SET <950) I_SET+=50; GIFR |=(1<<INTF1); } SIGNAL(SIG_INTERRUPT2) //ALERT signal { GIFR |=(1<<INTF2); } SIGNAL(SIG_OVERFLOW0) //0,01s Timer Unit { TCNT0 = 256 - 156; //new Preload if(SOUNDRISE){ //Alternating Noise if(OCR2<180){ OCR2+=10;} else{ SOUNDRISE = 0;}} else { if(OCR2>30){ OCR2-=10;} else{ SOUNDRISE = 1;} } if(GREEN_ENABLE) //Green LED Control { GREEN_TIMER++; if(GREEN_TIMER == 0) GREENON; if(GREEN_TIMER == (UBAT>>2)) GREENOFF; } if(BACK_ENABLE) //Back LED Control { BACK_TIMER++; if(BACK_TIMER == 25) BACKON; if(BACK_TIMER>=50){ BACKOFF; BACK_TIMER = 0;} } if(SIDES_ENABLE) //Side LEDs Control { SIDES_TIMER++; if(SIDES_TIMER == 20) SIDESON; if(SIDES_TIMER>=40){ SIDESOFF; SIDES_TIMER = 0;} } } SIGNAL(SIG_OVERFLOW1) { } SIGNAL(SIG_ADC) { if(ADC_COUNT) ADC_TMP+=ADC; //akkumulate by dropping first measurement ADC_COUNT++; //increase measurement counter if(ADC_COUNT > 8) //every 8 measurements { switch(ADC_CHANNEL) //store value and change channel { case (0): UBAT=(ADC_TMP>>3); ADMUX|= 0b01001001; // AREF/right/2-CH amp./10*ADC1->0 ADC_CHANNEL++; break; case (1): I1=(ADC_TMP>>3); ADMUX|= 0b01001101; // AREF/right/2-CH amp./10*ADC3->2 ADC_CHANNEL++; if((I_SET+10>I1) && (OCR1A>500)){ REDOFF GREENON OCR1A--;} else if((I_SET-10<I1) && (OCR1A<1022)){ REDON GREENOFF OCR1A++;} break; case (2): I2=(ADC_TMP>>3); ADMUX|= 0b01000111; // AREF/right/8 unipol./ADC7 ADC_CHANNEL=0; if((I_SET+10>I2) && (OCR1B>500)){ OCR1B--;} else if((I_SET-10<I2) && (OCR1B<1022)){ OCR1B++;} break; } ADC_COUNT=0; ADC_TMP=0; } ADCSRA|= (1<<ADSC); //start next Conversion }
Hier ein Paar Dokumente:
Danke für eure Hilfe!







Zitieren

Lesezeichen