PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : AD Kanal bestimmen



horsty
12.12.2009, 21:13
Hallo,

wie sage ich dem AD-Wandler welchen Kanal er als eingang nutzen soll??
hab dazu im avr-gcc-tuto nichts gefunden.

Danke
Horsty

radbruch
12.12.2009, 21:22
Bei den Atmegas und Tinies wird der ADC-Kanal im ADMUX-Register in den Bits 0,1 und 2 (MUX0-2)angegeben.

shedepe
12.12.2009, 23:27
Im Tutorial auf Mikrocontroller.net ist das auch noch mal beschrieben.
Just in case dass du noch weitere infos dazu brauchst

horsty
13.12.2009, 00:33
Vielen Dank schonmal.

Hatte das überlesen.

Stimmen die einstellungen im nachfolgenden code, wenn ich nur ADC0 als eingang nutzen möchte:

int16_t ad ()
{
int8_t y;
int16_t x;

ADMUX |= (1<<REFS0);

ADCSRA |= (1<<ADEN) | (1<<ADATE) | (1<<ADSC) | (1<<ADPS2) | (1<<ADPS0);

x = ADCW;

y=x/4;
}

greetz
horsty[/quote]

Hubert.G
13.12.2009, 09:31
Wenn du noch sagst für welchen Kontroller das sein soll.
ADC0 wäre schon mal richtig.
Kommentare, zumindest bei den Registeranweisungen, würden das lesen sehr erleichtern. Selbst tust du dir auch leichter wenn du das in einem Jahr wieder liest. Wenn du nicht jeden Tag so etwas schreibst weisst du nicht mehr was die Zeilen sollen.

oberallgeier
13.12.2009, 09:54
Hi Horsty,

manchmal wundere ich mich, mit wie wenig Kommentar man auskommen kann. Bei mir ist das viel mehr Schreibarbeit *kopfschüttel*. Für eine interruptgetriebene ADC-Erfassung auf Kanal ADC3 habe ich diese beiden Routinen in Betrieb. Wenn Du ADC0 haben willst, wird ADMUX entsprechend geändert. Die Angabe der Spannungsreferenz mit REFS2..0 ist sinnvoll, wenn Du nichts angibst, dann gilt nach Datenblatt "... VCC used as Voltage Reference, disconnected from PB0 (AREF) ...". Meine Angabe REFS0 ist kommentiert, genauer stehts im Datenblatt "... External Voltage Reference at PB0 (AREF) pin, Internal Voltage Reference turned off..." - hängt halt mit meiner Controllerbeschaltung zusammen. Für eine genauere Messung habe ich eine "Statistik" und nehme den Durchschnitt (arithmetisches Mittel ā) von 12 Messungen. WENN Du ein 8bittiges Ergebnis möchtest, dann musst Du entsprechend angepasst coden. Die Variablen sind alle extern und volatile deklariert.

// ================================================== ===============================
// === 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

adc3_cnt = 0; // ADC-Wert wird x-fach aufaddiert
adc3_tmp = 0; // ADC-x-fach-Speicher
}
// ================================================== ===============================


// ================================================== ===============================
// === 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_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;
}
}
// ================================================== ===============================
Viel Erfolg

Anmerkung: uuuups - da war Hubert.G wieder schneller :(

horsty
13.12.2009, 12:55
vielen dank für die tipps!

mittlerweile scheint es u funktionieren, aber die 7-segment an der der wert ausgegeben werden soll, zeigt nur eine null an. (verzweiflung macht sich breit =) )

hier habe ich mal das gesamte programm:

#define F_CPU 16000000
#include <avr/io.h>



int16_t main ()
{
// port B und D werden als ausgang definiert
DDRA = 0x00;
DDRB = 0x1f;
DDRC = 0x00;
DDRD = 0xff;

//variablen
int y;
int hunderter;
int zehner;
int einer;
int16_t x;

ADMUX |= (1<<REFS0);
ADCSRA |= (1<<ADEN) | (1<<ADATE) | (1<<ADSC) | (1<<ADPS2) | (1<<ADPS0);
x = ADCW; // eingangswert wird der variable x übergeben
y=x/4; // x wird durch 4 geteilt (von 10 auf 8 bit)

// ----- 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;
}
return(0); //ende und neustart
}


wo liegt der da der fehler?

greetz
horsty

sternst
13.12.2009, 12:58
wo liegt der da der fehler?Du kannst nicht die AD-Wandlung starten, und dann sofort das Ergebnis auslesen. Du musst schon warten, bis die AD-Wandlung fertig ist.

021aet04
13.12.2009, 13:07
Der Fehler liegt in der Berechnung der einzelnen Stellen. So habe ich es gelöst. https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=48539&highlight=zehner

MfG Hannes

sternst
13.12.2009, 13:15
Der Fehler liegt in der Berechnung der einzelnen Stellen.Und welcher soll das sein? Ich kann da keinen entdecken.

horsty
13.12.2009, 13:49
also ich hab die berechnung der einzelnen stellen mit einer konstanten ausprobiert und sie funktioniert tadellos!

aber wie warte ich denn auf die konvertierung?

shedepe
13.12.2009, 15:19
in etwa so:
while ( ADCSRA & (1<<ADSC) ) {
; // auf Abschluss der Konvertierung warten
}

horsty
13.12.2009, 16:50
okay, danke an euch alle!!

ich habe den fehler gefunden! ich hatte ADATA im register gesetzt.
nun läufts.

Danke
Horsty

horsty
16.12.2009, 22:20
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:

#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
}


Kompiler sagt:


Build succeeded with 0 Warnings...

aber ich bekomm trotzdem nur 3 nullen angezeigt...

greetz horsty[/code]

oberallgeier
16.12.2009, 23:22
Dein Controllertyp ist vermutlich (immer noch) geheim! ?



x=ADC; // eingangswert wird der variable x übergeben
y=x/4; // x wird durch 4 geteilt (von 10 auf 8 bit) Bei meinen Atmelcontrollern gibts die Möglichkeit, den ADC gleich mit 8 Bit auszulesen. Das Stichwort heißt ADLAR.

... By default, the result is presented right adjusted, but can optionally be presented left adjusted by setting the ADLAR bit in ADMUX ...Da lohnt es sich weiterzulesen.



// port B und D werden als ausgang definiertHmmm, WENN Dein ADC auf Port B oder D liegt, dann liest Du über einen Ausgang ein. Darüber solltest Du nachdenken.

Hubert.G
17.12.2009, 08:47
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.

horsty
17.12.2009, 09:24
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

oberallgeier
17.12.2009, 09:47
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.

/* >>
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 ================================================== ===
// ================================================== ===============================

Viel Erfolg

sternst
17.12.2009, 11:07
Mit main(); rufi ich am ende des programms wieder diese funktion auf.
Quasi eine Endlosschleife.
Das geht so nicht. Das ist keine Endlosschleife, sondern eine Endlosrekursion, die den Stack überlaufen lässt.
War dir eine normale Schleife nicht cool genug?

horsty
17.12.2009, 19:23
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....



#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;
}
}
}

sternst
17.12.2009, 19:51
Dass das ganze nur einmal richtig funktioniert, liegt daran, dass Ausgänge, die einmal auf 1 gesetzt wurden, nie wieder zurückgesetzt werden.
Denn so was hier "PORTD |= (1<<PD0) | (1<<PD1) | (0<<PD2);" sorgt nicht dafür, dass PD2 auf 0 gesetzt wird.

oberallgeier
17.12.2009, 21:40
Hi horsty,

hier zur Erleichterung für Dich das Bit-Tutorial in C. (http://www.mikrocontroller.net/articles/Bitmanipulation#Bits_l.C3.B6schen)

horsty
18.12.2009, 17:43
okay.... läuft jetzt einwandfrei!!

Danke an euch!!

greetz
horsty