Sd_alt (Diskussion | Beiträge) |
Edvpc2 (Diskussion | Beiträge) |
||
Zeile 41: | Zeile 41: | ||
eingefügt. | eingefügt. | ||
+ | |||
+ | |||
+ | == Neuer Abschnitt == | ||
+ | |||
+ | Zum letzten Abschnitt: Stimmt! | ||
+ | |||
+ | Mir ist aufgefallen, dass das Basic Beispieltestprogramm für die Tastenabfrage am Porta.7 den Pull-Up Widerstand verwendet, um bei nicht gedrückter Taste einen definierten Spannungspegel am AD Wandlereingang zu haben | ||
+ | |||
+ | <pre> | ||
+ | |||
+ | ... | ||
+ | |||
+ | Config Adc = Single , Prescaler = Auto 'Für Tastenabfrage und Spannungsmessung | ||
+ | |||
+ | Config Pina.7 = Input 'Für Tastenabfrage | ||
+ | Porta.7 = 1 'Pullup Widerstand ein | ||
+ | |||
+ | ... | ||
+ | |||
+ | </pre> | ||
+ | |||
+ | Dies ist im C-Programm nicht so realisiert und der Pin hängt bei nicht gedrückter Taste in der Luft, was möglicher Weise zu dem im C-Programm beschriebenen Effekt führt | ||
+ | |||
+ | <pre> | ||
+ | |||
+ | ..... | ||
+ | |||
+ | setportaon(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); | ||
+ | setportaoff(7); | ||
+ | .... | ||
+ | |||
+ | </pre> | ||
+ | |||
+ | |||
+ | |||
+ | Meine Lösung: | ||
+ | |||
+ | <pre> | ||
+ | |||
+ | ......... | ||
+ | |||
+ | /*### Hauptschleife ###*/ | ||
+ | |||
+ | int main(void) | ||
+ | { | ||
+ | |||
+ | /*###Initialisierungsphase###*/ | ||
+ | |||
+ | //Pins bzw. Ports als Ein-/Ausgänge konfigurieren | ||
+ | |||
+ | //Initialisierungen | ||
+ | |||
+ | setportdoff(7); //Speaker aus | ||
+ | |||
+ | init_USART(); //USART konfigurieren | ||
+ | |||
+ | DDRA = 0x00; //00000000 -> alle Analogports als Eingänge | ||
+ | |||
+ | SFIOR &= ~(1<<PUD); // Pull-UP enable (nicht unbedingt nötig, aber zur Klarheit!) | ||
+ | PORTA |= (1<<PA7); // internen Pull-Up an PA5 aktivieren | ||
+ | |||
+ | ...... | ||
+ | |||
+ | </pre> | ||
+ | |||
+ | Dann muss die Buttonabfrage wegen des Pull-Up Widerstandes entsprechend angepasst werden, denn er liegt nun parallel zu dem 10k Widerstand + 1 bis 4 1k Widerständen (je nach gedrückter Taste). Dann stimmen die Ergebnisse der AD Wandlung auch mit dem des Basic-Programms überein und könne übernommen werden | ||
+ | |||
+ | |||
+ | <pre> | ||
+ | |||
+ | ... | ||
+ | |||
+ | /*### Buttonabfrage ###*/ | ||
+ | |||
+ | uint8_t button(void) | ||
+ | { | ||
+ | uint8_t taste = 0; //Variable für Nummer des Tasters | ||
+ | uint16_t analog7 = adcwert(7); //Wert des Ports | ||
+ | |||
+ | // setportaon(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); | ||
+ | // setportaoff(7); | ||
+ | / Die folgende Zeile ist nur zur Überprüfung aller gelesenen Werte und kann auskommentiert werden | ||
+ | utoa(analog7, wort, 10),sendUSART("ADC-Wert=");sendUSART(wort);sendUSART("\r\n"); | ||
+ | |||
+ | //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>=400) && (analog7<=450)) {taste = 1;utoa(analog7, wort, 10),sendUSART("Wert=");sendUSART(wort);} | ||
+ | else if((analog7>=330) && (analog7<=380)) {taste = 2;utoa(analog7, wort, 10),sendUSART("ADC-Wert=");sendUSART(wort);} | ||
+ | else if((analog7>=260) && (analog7<=305)) {taste = 3;utoa(analog7, wort, 10),sendUSART("ADC-Wert=");sendUSART(wort);} | ||
+ | else if((analog7>=180) && (analog7<=230)) {taste = 4;utoa(analog7, wort, 10),sendUSART("ADC-Wert=");sendUSART(wort);} | ||
+ | else if((analog7>=90) && (analog7<=130)) {taste = 5;utoa(analog7, wort, 10),sendUSART("ADC-Wert=");sendUSART(wort);} | ||
+ | else {} | ||
+ | |||
+ | return taste; | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | </pre> | ||
+ | |||
+ | Hier mal die bei mir gemessenen AD Werte: | ||
+ | |||
+ | {| border= 1 | ||
+ | |Taste | ||
+ | |ohne PW | ||
+ | |mit internem PW | ||
+ | |mit ext. PW (22k) | ||
+ | |- | ||
+ | |1 | ||
+ | |341 | ||
+ | |408 | ||
+ | |432 | ||
+ | |- | ||
+ | |2 | ||
+ | |272 | ||
+ | |340 | ||
+ | |363 | ||
+ | |- | ||
+ | |3 | ||
+ | |204 | ||
+ | |268 | ||
+ | |286 | ||
+ | |- | ||
+ | |4 | ||
+ | |135 | ||
+ | |190 | ||
+ | |202 | ||
+ | |- | ||
+ | |5 | ||
+ | |67 | ||
+ | |106 | ||
+ | |106 | ||
+ | |} |
Version vom 27. Januar 2008, 15:21 Uhr
Das Programm erzeugt beim kompilieren mit AVRStudio 4.13.528 Fehler bei den For-Schleifen. Das rührt daher, dass in rncontrol.h Variablen in C++-Manier in den for-Anweisung selbst deklariert werden.
Bsp.:
void sound(uint8_t hoehe, uint16_t laenge) { for(uint16_t i=0; i<laenge*15; i=i+(2*hoehe)) { setportdon(7); _delay_ms(hoehe); setportdoff(7); _delay_ms(hoehe); } }
Fehler:
"error: 'for' loop initial declaration used outside C99 mode"
Werde das jetzt an den relevanten Stellen so ändern :
void sound(uint8_t hoehe, uint16_t laenge) { uint16_t i; for(i=0; i<laenge*15; i=i+(2*hoehe)) { setportdon(7); _delay_ms(hoehe); setportdoff(7); _delay_ms(hoehe); } }
Wäre schön, wenn es dann zur Sicherheit mal jemand testen könnte.
Habe zur Sicherheit bei allen Änderungen mal
"initial declaration error" fix
eingefügt.
Neuer Abschnitt
Zum letzten Abschnitt: Stimmt!
Mir ist aufgefallen, dass das Basic Beispieltestprogramm für die Tastenabfrage am Porta.7 den Pull-Up Widerstand verwendet, um bei nicht gedrückter Taste einen definierten Spannungspegel am AD Wandlereingang zu haben
... Config Adc = Single , Prescaler = Auto 'Für Tastenabfrage und Spannungsmessung Config Pina.7 = Input 'Für Tastenabfrage Porta.7 = 1 'Pullup Widerstand ein ...
Dies ist im C-Programm nicht so realisiert und der Pin hängt bei nicht gedrückter Taste in der Luft, was möglicher Weise zu dem im C-Programm beschriebenen Effekt führt
..... setportaon(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); setportaoff(7); ....
Meine Lösung:
......... /*### Hauptschleife ###*/ int main(void) { /*###Initialisierungsphase###*/ //Pins bzw. Ports als Ein-/Ausgänge konfigurieren //Initialisierungen setportdoff(7); //Speaker aus init_USART(); //USART konfigurieren DDRA = 0x00; //00000000 -> alle Analogports als Eingänge SFIOR &= ~(1<<PUD); // Pull-UP enable (nicht unbedingt nötig, aber zur Klarheit!) PORTA |= (1<<PA7); // internen Pull-Up an PA5 aktivieren ......
Dann muss die Buttonabfrage wegen des Pull-Up Widerstandes entsprechend angepasst werden, denn er liegt nun parallel zu dem 10k Widerstand + 1 bis 4 1k Widerständen (je nach gedrückter Taste). Dann stimmen die Ergebnisse der AD Wandlung auch mit dem des Basic-Programms überein und könne übernommen werden
... /*### Buttonabfrage ###*/ uint8_t button(void) { uint8_t taste = 0; //Variable für Nummer des Tasters uint16_t analog7 = adcwert(7); //Wert des Ports // setportaon(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); // setportaoff(7); / Die folgende Zeile ist nur zur Überprüfung aller gelesenen Werte und kann auskommentiert werden utoa(analog7, wort, 10),sendUSART("ADC-Wert=");sendUSART(wort);sendUSART("\r\n"); //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>=400) && (analog7<=450)) {taste = 1;utoa(analog7, wort, 10),sendUSART("Wert=");sendUSART(wort);} else if((analog7>=330) && (analog7<=380)) {taste = 2;utoa(analog7, wort, 10),sendUSART("ADC-Wert=");sendUSART(wort);} else if((analog7>=260) && (analog7<=305)) {taste = 3;utoa(analog7, wort, 10),sendUSART("ADC-Wert=");sendUSART(wort);} else if((analog7>=180) && (analog7<=230)) {taste = 4;utoa(analog7, wort, 10),sendUSART("ADC-Wert=");sendUSART(wort);} else if((analog7>=90) && (analog7<=130)) {taste = 5;utoa(analog7, wort, 10),sendUSART("ADC-Wert=");sendUSART(wort);} else {} return taste; }
Hier mal die bei mir gemessenen AD Werte:
Taste | ohne PW | mit internem PW | mit ext. PW (22k) |
1 | 341 | 408 | 432 |
2 | 272 | 340 | 363 |
3 | 204 | 268 | 286 |
4 | 135 | 190 | 202 |
5 | 67 | 106 | 106 |