also ich hab die berechnung der einzelnen stellen mit einer konstanten ausprobiert und sie funktioniert tadellos!
aber wie warte ich denn auf die konvertierung?
Druckbare Version
also ich hab die berechnung der einzelnen stellen mit einer konstanten ausprobiert und sie funktioniert tadellos!
aber wie warte ich denn auf die konvertierung?
in etwa so:
while ( ADCSRA & (1<<ADSC) ) {
; // auf Abschluss der Konvertierung warten
}
okay, danke an euch alle!!
ich habe den fehler gefunden! ich hatte ADATA im register gesetzt.
nun läufts.
Danke
Horsty
nabend euch allen,
heute war mal wieder bastelstunde, weil ich die letzten tage nicht so viel zeit hatte.
mit dem angepassten code funktionierte das ganze gut, allerdings nur einmal...
also das ganze dann irgendwie in eine schleife packen...
hier das ergebnis:
Kompiler sagt:Code:#define F_CPU 16000000UL
#include <avr/io.h>
#include <stdint.h>
uint8_t y;
int main(){
// port B und D werden als ausgang definiert
DDRB = 0x1f;
DDRD = 0xff;
uint16_t AD();
if (y>=0){
uint8_t LED();
}
else
main();
}
uint16_t AD(void)
{
//variablen
uint16_t x;
ADMUX |= (1<<REFS0); //AVCC als Referenzspannung wählen
//Prescaler auf 128 einstellen und ADC aktivieren
ADCSRA = (1<<ADPS0) | (1<<ADPS2) | (1<<ADEN);
ADCSRA |= (1<<ADSC);
while(ADCSRA & (1<<ADSC)){
;//Konvertierung abwarten
}
x=ADC; // eingangswert wird der variable x übergeben
y=x/4; // x wird durch 4 geteilt (von 10 auf 8 bit)
}
uint8_t LED(void){
int hunderter;
int zehner;
int einer;
// ----- ab hier wird die 8-bit zahl auseinander genommen
// die hunderter stelle
hunderter=y/100;
hunderter=hunderter%10;
switch (hunderter)
{
case 1:
PORTD |= (1<<PD3) | (0<<PD4) | (0<<PD5) | (0<<PD6);
break;
case 2:
PORTD |= (0<<PD3) | (1<<PD4) | (0<<PD5) | (0<<PD6);
break;
// abschaltung der hunderter stelle bei kleineren zahlen durch schalten auf high
default :
PORTD |= (1<<PD3) | (1<<PD4) | (1<<PD5) | (1<<PD6);
break;
}
zehner=y/10;
zehner=zehner%10;
// abschaltung der zehner stelle wenn hunnderter und zehner gleich 0 ist
if (hunderter==0 && zehner==0)
{
PORTB |= (1<<PB4);
PORTD |= (1<<PD0) | (1<<PD1) | (1<<PD2);
}
else
switch (zehner)
{
case 0:
PORTB |= (0<<PB4);
PORTD |= (0<<PD0) | (0<<PD1) | (0<<PD2);
break;
case 1:
PORTB |= (1<<PB4);
PORTD |= (0<<PD0) | (0<<PD1) | (0<<PD2);
break;
case 2:
PORTB |= (0<<PB4);
PORTD |= (1<<PD0) | (0<<PD1) | (0<<PD2);
break;
case 3:
PORTB |= (1<<PB4);
PORTD |= (1<<PD0) | (0<<PD1) | (0<<PD2);
break;
case 4:
PORTB |= (0<<PB4);
PORTD |= (1<<PD0) | (0<<PD1) | (0<<PD2);
break;
case 5:
PORTB |= (1<<PB4);
PORTD |= (0<<PD0) | (1<<PD1) | (0<<PD2);
break;
case 6:
PORTB |= (0<<PB4);
PORTD |= (1<<PD0) | (1<<PD1) | (0<<PD2);
break;
case 7:
PORTB |= (1<<PB4);
PORTD |= (1<<PD0) | (1<<PD1) | (0<<PD2);
break;
case 8:
PORTB |= (0<<PB4);
PORTD |= (0<<PD0) | (0<<PD1) | (1<<PD2);
break;
case 9:
PORTB |= (1<<PB4);
PORTD |= (0<<PD0) | (0<<PD1) | (1<<PD2);
break;
default:
PORTB |= (1<<PB4);
PORTD |= (1<<PD0) | (1<<PD1) | (1<<PD2);
break;
}
// anzeige der einer stelle
einer=y%10;
switch (einer)
{
case 0:
PORTB |= (0<<PA0) | (0<<PA1) | (0<<PA2) | (0<<PA3);
break;
case 1:
PORTB |= (1<<PA0) | (0<<PA1) | (0<<PA2) | (0<<PA3);
break;
case 2:
PORTB |= (0<<PA0) | (1<<PA1) | (0<<PA2) | (0<<PA3);
break;
case 3:
PORTB |= (1<<PA0) | (1<<PA1) | (0<<PA2) | (0<<PA3);
break;
case 4:
PORTB |= (0<<PA0) | (0<<PA1) | (1<<PA2) | (0<<PA3);
break;
case 5:
PORTB |= (1<<PA0) | (0<<PA1) | (1<<PA2) | (0<<PA3);
break;
case 6:
PORTB |= (0<<PA0) | (1<<PA1) | (1<<PA2) | (0<<PA3);
break;
case 7:
PORTB |= (1<<PA0) | (1<<PA1) | (1<<PA2) | (0<<PA3);
break;
case 8:
PORTB |= (0<<PA0) | (0<<PA1) | (0<<PA2) | (1<<PA3);
break;
case 9:
PORTB |= (1<<PA0) | (0<<PA1) | (0<<PA2) | (1<<PA3);
break;
default:
PORTB |= (1<<PA0) | (1<<PA1) | (1<<PA2) | (1<<PA3);
break;
}
main(); //ende und neustart
}
aber ich bekomm trotzdem nur 3 nullen angezeigt...Code:Build succeeded with 0 Warnings...
greetz horsty[/code]
Dein Controllertyp ist vermutlich (immer noch) geheim! ?
Bei meinen Atmelcontrollern gibts die Möglichkeit, den ADC gleich mit 8 Bit auszulesen. Das Stichwort heißt ADLAR.Zitat:
Zitat von horsty
Da lohnt es sich weiterzulesen.Zitat:
Zitat von Meine Doku
Hmmm, WENN Dein ADC auf Port B oder D liegt, dann liest Du über einen Ausgang ein. Darüber solltest Du nachdenken.Zitat:
Zitat von horsty
Das mit der Endlosschleife solltest du dir noch mal ansehen, die funktioniert so nicht.
Was rufst du mit main(); auf?
Ein else kannst du nicht alleine stehen lassen, da passiert nichts.
Für 8bit ADLAR verwenden und nur ADCH auslesen, hat "oberallgeier" ja schon geschrieben.
mein Controller ist ein Atmega32.
Mit main(); rufi ich am ende des programms wieder diese funktion auf.
Quasi eine Endlosschleife.
Und das mit dem ADLAR werde ich dann mal ausprobieren.
Ist das Programm denn sonst so korrekt?
greetz
horsty
Ob Dir mein Beispiel unten hilft, weiß ich nicht. Es läuft korrekt, aber eben NICHT auf einem m32 - ausserdem mit 10 bit (daher NICHT mit ADLAR), dummerweise auch noch mit einer Triggersource aus einer "fremden" Interruptquelle. Es sind zwei Bruchstücke: Initialisierung des Ports im main, initialisierung des ADC und die zugehörige ISR.
Viel ErfolgCode:/* >>
Sicherung 10Okt09 1810 ..\C2\D01-3_40\D01-3_40x23.c
===================================================================================
Target MCU : ATmega328
... */
...
// =================================================================================
// === HAUPTProgramm ==============================================================
// =================================================================================
int main(void)
{
...
// Pins/Ports als Ein- (0) oder Ausgänge (1) konfigurieren, Pull Ups (1) aktivieren
// A = Ausgang, E = Eingang ohne , EU = Eingang MIT PullUp
.....
DDRC = 0b01110000; // PC3 ist ADC3, PC0 .. 6 , kein PC7-Pin bei m168
PORTC = 0b00000111; // Beachte für ADC: PC3 ist ADC-Eingang ##>> OHNE Pullup !!
....
// ================================================================================
----- o ----- o ----- o ----- o ----- o ----- o ----- o ----- o ----- o -----
/* >>
Sicherung 15Sep09 2150 .\C2\D01-3_40\D01-3_40_gpd_x21.c ###>>> noch nicht
===================================================================================
Target MCU : M168
....
================================================================================ */
// =================================================================================
// === Initialisierung fuer ADC mega168 MIT Interrupt ========================
// ADC3/PC3 auf 10 Bit, Wandlung #####>>>>> Interrupt ausgelöst
void ADC3_10_init_irupt(void) //
{
ADMUX |= (1<<MUX1)|(1<<MUX0); // Wandlung mit ADC3
ADMUX |= (1<<REFS0); // Referenzspannung ist Vcc doc S 256
ADCSRA |= (1<<ADATE); // Auto Triggering Enable doc S 247 + 257
ADCSRB |= (1<<ADTS1)|(1<<ADTS0); // Triggersource = TC0 CmpA doc S 260
// es wird also mit 1/1220 getriggert ca. 0,82 ms
ADCSRA |= (1<<ADIE); // ADC Interrupt Enable doc S 258
ADCSRA |= (1<<ADEN); // AD Enable
ADCSRA |= (1<<ADSC); // starte gleich die erste Wandlung
}
// =================================================================================
// =================================================================================
// === Nicht unterbrechbare ISR für ADC3 auf Pin 26/PC3/mega168 ==================
// Routine übernimmt ADC-Wert
ISR(ADC_vect) // _VECTOR(21)
{
adc3_tmp = ADC; // Hole Wert
adc3_sum = adc3_sum + adc3_tmp; // ADC-Werte aufsummieren
//adc3_sum += ADC; // Werte aufsummieren für Durchschnitt
adc3_cnt = adc3_cnt + 1; // Hochzählen Counter für ISR-Aufruf
if (adc3_cnt >= 12) // Wenn Counter >= x, dann Messwert ausrechnen
{ // Wenn adc3_counter < x, dann keine Aktion
adc3_dat = adc3_sum / 12; // Gemittelten ADC-Wert ausrechnen
adc3_sum = 0; // adc3_sum und Counter rücksetzen
adc3_cnt = 1;
PORTC ^= (1<<PC4); // Zeitmessung: Port PC4 toggeln
}
}
// =================================================================================
// =================================================================================
// ===== ENDE Subroutinen =====================================================
// =================================================================================
Das geht so nicht. Das ist keine Endlosschleife, sondern eine Endlosrekursion, die den Stack überlaufen lässt.Zitat:
Zitat von horsty
War dir eine normale Schleife nicht cool genug?
hallo,
das mit ADLAR war ein guter tipp!! danke
das ganze funktioniert jetzt auch soweit, allerdings wieder nur jeweils einmal. anscheinend funktioniert die schleife nicht....
Code:#define F_CPU 16000000UL
#include <avr/io.h>
#include <stdint.h>
int main(){
//variablen
int y;
int hunderter;
int zehner;
int einer;
// port B und D werden als ausgang definiert
DDRB = 0x1f;
DDRD = 0xff;
ADMUX |= (1<<REFS0) | (1<<ADLAR); //AVCC als Referenzspannung wählen
//Prescaler auf 128 einstellen und ADC aktivieren
ADCSRA = (1<<ADPS0) | (1<<ADPS2) | (1<<ADEN);
while (1){
ADCSRA |= (1<<ADSC);
while(ADCSRA & (1<<ADSC)){
;//Konvertierung abwarten
}
y=ADCH; // eingangswert wird der variable y übergeben
// ----- ab hier wird die 8-bit zahl auseinander genommen
// die hunderter stelle
hunderter=y/100;
hunderter=hunderter%10;
switch (hunderter)
{
case 1:
PORTD |= (1<<PD3) | (0<<PD4) | (0<<PD5) | (0<<PD6);
break;
case 2:
PORTD |= (0<<PD3) | (1<<PD4) | (0<<PD5) | (0<<PD6);
break;
// abschaltung der hunderter stelle bei kleineren zahlen durch schalten auf high
default :
PORTD |= (1<<PD3) | (1<<PD4) | (1<<PD5) | (1<<PD6);
break;
}
zehner=y/10;
zehner=zehner%10;
// abschaltung der zehner stelle wenn hunnderter und zehner gleich 0 ist
if (hunderter==0 && zehner==0)
{
PORTB |= (1<<PB4);
PORTD |= (1<<PD0) | (1<<PD1) | (1<<PD2);
}
else{
switch (zehner)
{
case 0:
PORTB |= (0<<PB4);
PORTD |= (0<<PD0) | (0<<PD1) | (0<<PD2);
break;
case 1:
PORTB |= (1<<PB4);
PORTD |= (0<<PD0) | (0<<PD1) | (0<<PD2);
break;
case 2:
PORTB |= (0<<PB4);
PORTD |= (1<<PD0) | (0<<PD1) | (0<<PD2);
break;
case 3:
PORTB |= (1<<PB4);
PORTD |= (1<<PD0) | (0<<PD1) | (0<<PD2);
break;
case 4:
PORTB |= (0<<PB4);
PORTD |= (1<<PD0) | (0<<PD1) | (0<<PD2);
break;
case 5:
PORTB |= (1<<PB4);
PORTD |= (0<<PD0) | (1<<PD1) | (0<<PD2);
break;
case 6:
PORTB |= (0<<PB4);
PORTD |= (1<<PD0) | (1<<PD1) | (0<<PD2);
break;
case 7:
PORTB |= (1<<PB4);
PORTD |= (1<<PD0) | (1<<PD1) | (0<<PD2);
break;
case 8:
PORTB |= (0<<PB4);
PORTD |= (0<<PD0) | (0<<PD1) | (1<<PD2);
break;
case 9:
PORTB |= (1<<PB4);
PORTD |= (0<<PD0) | (0<<PD1) | (1<<PD2);
break;
default:
PORTB |= (1<<PB4);
PORTD |= (1<<PD0) | (1<<PD1) | (1<<PD2);
break;
}
}
// anzeige der einer stelle
einer=y%10;
switch (einer)
{
case 0:
PORTB |= (0<<PA0) | (0<<PA1) | (0<<PA2) | (0<<PA3);
break;
case 1:
PORTB |= (1<<PA0) | (0<<PA1) | (0<<PA2) | (0<<PA3);
break;
case 2:
PORTB |= (0<<PA0) | (1<<PA1) | (0<<PA2) | (0<<PA3);
break;
case 3:
PORTB |= (1<<PA0) | (1<<PA1) | (0<<PA2) | (0<<PA3);
break;
case 4:
PORTB |= (0<<PA0) | (0<<PA1) | (1<<PA2) | (0<<PA3);
break;
case 5:
PORTB |= (1<<PA0) | (0<<PA1) | (1<<PA2) | (0<<PA3);
break;
case 6:
PORTB |= (0<<PA0) | (1<<PA1) | (1<<PA2) | (0<<PA3);
break;
case 7:
PORTB |= (1<<PA0) | (1<<PA1) | (1<<PA2) | (0<<PA3);
break;
case 8:
PORTB |= (0<<PA0) | (0<<PA1) | (0<<PA2) | (1<<PA3);
break;
case 9:
PORTB |= (1<<PA0) | (0<<PA1) | (0<<PA2) | (1<<PA3);
break;
default:
PORTB |= (1<<PA0) | (1<<PA1) | (1<<PA2) | (1<<PA3);
break;
}
}
}