Yunus64
03.04.2012, 19:22
Hallo kann mir mal jemand sagen warum das hier nicht Funktioniert. Arbeite schon seit etwa 17 Uhr dran... ich weiss nicht ob es Softwarebedingt oder Hardwarebedingt ist. Es scheint mir aber fast als ob nur Taster 2 und 3 Reagieren würden, egal wie ich den Code verändere.
Nochwas zum Code, ich habe mir die Sachen die benötigt werden aus der rn-control.h datai kopiert und wollte nun einfach eine LED durch Taster ansteuerung realisieren.
#include <avr/io.h>
uint16_t adcwert(uint8_t kanal)
{
uint16_t wert = 0; //Variable für Ergebnis deklarieren
ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //ADEN aktiviert überhaupt erst den internen ADC-Wandler, ADPS2 bis ADPS0 stellen den verwendeten Prescaler ein, denn die Wandlerfrequenz muss immer zwischen 50 und 200 kHz liegen! Der Prescaler muss bei 16MHz also zwischen 80 und 320 eingestellt werden, als einzige Möglichkeit bleibt hier 128 (=alle auf 1).
ADMUX = kanal;
//ADMUX = (1<<REFS1)|(1<<REFS0); //Einstellen der Referenzspannung auf "extern", also REFS1 und REFS0 auf "0" - daher auskommentierte Zeile
ADCSRA |= (1<<ADSC); //nach Aktivierung des ADC wird ein "Dummy-Readout" empfohlen, man liest also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen"
while(ADCSRA & (1<<ADSC)) {} //auf Abschluss der Konvertierung warten
wert = ADCW; //ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten Wandlung nicht übernommen.
/* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */
wert = 0;
uint8_t i;
for(i=0; i<4; i++)
{
ADCSRA |= (1<<ADSC); //eine Wandlung "single conversion" starten
while(ADCSRA & (1<<ADSC)) {} //auf Abschluss der Konvertierung warten
wert = wert + ADCW; //Wandlungsergebnisse aufaddieren
}
ADCSRA &= ~(1<<ADEN); //ADC deaktivieren
wert = wert/4; //Durchschnittswert bilden
return wert;
}
/*### waitms - Programm pausieren lassen ###*/
/*Die Funktion lässt circa so viele Millisekunden verstreichen, wie angegeben werden.
Angepasst auf das RN-Control 1.4 mit 16 MHz-Quarz!
Vorsicht, Wert ist nur experimentell angenähert, nicht exakt berechnet!*/
void waitms(uint16_t ms)
{
for(; ms>0; ms--)
{
uint16_t __c = 4000;
__asm__ volatile (
"1: sbiw %0,1" "\n\t"
"brne 1b"
: "=w" (__c)
: "0" (__c)
);
}
}
/*### Buttonabfrage ###*/
uint8_t button(void)
{
uint8_t taste = 0; //Variable für Nummer des Tasters
uint16_t analog7 = adcwert(7); //Wert des Ports
PORTA |= (1<<7); //Ohne das hier "flackern" die Werte aus irgend einem Grund -> es werden mitunter Tasten erkannt, die gar nicht gedrückt wurden oder das Programm bleibt für einige Sekunden "hängen"
waitms(1);
PORTA &= ~(0<<7);
//Abfrage des gedrückten Tasters - um Störungen zu vermeiden wurden die Bereiche sehr eng gefasst, sollten bei Bedarf an jedes Board extra angepasst werden.
if((analog7>=337) && (analog7<=343)) {taste = 1;}
else if((analog7>=268) && (analog7<=274)) {taste = 2;}
else if((analog7>=200) && (analog7<=206)) {taste = 3;}
else if((analog7>=132) && (analog7<=138)) {taste = 4;}
else if((analog7>=64) && (analog7<=70)) {taste = 5;}
else {}
return taste;
}
int main (void) {
DDRA |= 0x00;
DDRC |= 0xFF;
PORTC |= 0xFF;
while (1)
{
switch(button())
{
case 1: PORTC = 0b11111110; waitms(1000); PORTC = 0xFF; break;
case 2: PORTC = 0b11111101; waitms(1000); PORTC = 0xFF; break;
case 3: PORTC = 0b11111011; waitms(1000); PORTC = 0xFF; break;
case 4: PORTC = 0b11110111; waitms(1000); PORTC = 0xFF; break;
case 5: PORTC = 0b11101111; waitms(1000); PORTC = 0xFF; break;
default: break;
}
}
return (0);
}
Nochwas zum Code, ich habe mir die Sachen die benötigt werden aus der rn-control.h datai kopiert und wollte nun einfach eine LED durch Taster ansteuerung realisieren.
#include <avr/io.h>
uint16_t adcwert(uint8_t kanal)
{
uint16_t wert = 0; //Variable für Ergebnis deklarieren
ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //ADEN aktiviert überhaupt erst den internen ADC-Wandler, ADPS2 bis ADPS0 stellen den verwendeten Prescaler ein, denn die Wandlerfrequenz muss immer zwischen 50 und 200 kHz liegen! Der Prescaler muss bei 16MHz also zwischen 80 und 320 eingestellt werden, als einzige Möglichkeit bleibt hier 128 (=alle auf 1).
ADMUX = kanal;
//ADMUX = (1<<REFS1)|(1<<REFS0); //Einstellen der Referenzspannung auf "extern", also REFS1 und REFS0 auf "0" - daher auskommentierte Zeile
ADCSRA |= (1<<ADSC); //nach Aktivierung des ADC wird ein "Dummy-Readout" empfohlen, man liest also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen"
while(ADCSRA & (1<<ADSC)) {} //auf Abschluss der Konvertierung warten
wert = ADCW; //ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten Wandlung nicht übernommen.
/* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */
wert = 0;
uint8_t i;
for(i=0; i<4; i++)
{
ADCSRA |= (1<<ADSC); //eine Wandlung "single conversion" starten
while(ADCSRA & (1<<ADSC)) {} //auf Abschluss der Konvertierung warten
wert = wert + ADCW; //Wandlungsergebnisse aufaddieren
}
ADCSRA &= ~(1<<ADEN); //ADC deaktivieren
wert = wert/4; //Durchschnittswert bilden
return wert;
}
/*### waitms - Programm pausieren lassen ###*/
/*Die Funktion lässt circa so viele Millisekunden verstreichen, wie angegeben werden.
Angepasst auf das RN-Control 1.4 mit 16 MHz-Quarz!
Vorsicht, Wert ist nur experimentell angenähert, nicht exakt berechnet!*/
void waitms(uint16_t ms)
{
for(; ms>0; ms--)
{
uint16_t __c = 4000;
__asm__ volatile (
"1: sbiw %0,1" "\n\t"
"brne 1b"
: "=w" (__c)
: "0" (__c)
);
}
}
/*### Buttonabfrage ###*/
uint8_t button(void)
{
uint8_t taste = 0; //Variable für Nummer des Tasters
uint16_t analog7 = adcwert(7); //Wert des Ports
PORTA |= (1<<7); //Ohne das hier "flackern" die Werte aus irgend einem Grund -> es werden mitunter Tasten erkannt, die gar nicht gedrückt wurden oder das Programm bleibt für einige Sekunden "hängen"
waitms(1);
PORTA &= ~(0<<7);
//Abfrage des gedrückten Tasters - um Störungen zu vermeiden wurden die Bereiche sehr eng gefasst, sollten bei Bedarf an jedes Board extra angepasst werden.
if((analog7>=337) && (analog7<=343)) {taste = 1;}
else if((analog7>=268) && (analog7<=274)) {taste = 2;}
else if((analog7>=200) && (analog7<=206)) {taste = 3;}
else if((analog7>=132) && (analog7<=138)) {taste = 4;}
else if((analog7>=64) && (analog7<=70)) {taste = 5;}
else {}
return taste;
}
int main (void) {
DDRA |= 0x00;
DDRC |= 0xFF;
PORTC |= 0xFF;
while (1)
{
switch(button())
{
case 1: PORTC = 0b11111110; waitms(1000); PORTC = 0xFF; break;
case 2: PORTC = 0b11111101; waitms(1000); PORTC = 0xFF; break;
case 3: PORTC = 0b11111011; waitms(1000); PORTC = 0xFF; break;
case 4: PORTC = 0b11110111; waitms(1000); PORTC = 0xFF; break;
case 5: PORTC = 0b11101111; waitms(1000); PORTC = 0xFF; break;
default: break;
}
}
return (0);
}