-         

Ergebnis 1 bis 9 von 9

Thema: Einfaches, kurzes selbst geschriebenes Programm überprüfen

  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    03.12.2008
    Alter
    23
    Beiträge
    438

    Einfaches, kurzes selbst geschriebenes Programm überprüfen

    Anzeige

    Hi,
    Ich hab jetzt mal kurz ein Programm für einen ATmega8 geschrieben...
    Ich will, dass sobald Spannung auf PA1 liegt, PA2 aktiviert wird... auf dem Datenblatt steht neben PA1 (ADC), was auch immer ADC bedeuten wird...
    Code:
    include <avr/io.h>
    
    int main (void)
    {
    DDRA = 0x00
    }
    
    if (PINA & ( 0x02)) 
    {
    DDRA = 0x04
    PORTA = 0x04
    }
    return 0;
    Würde das so aufgehen?

    Grüsse!
    Wer keine Illusionen mehr hat, wird weiterhin existieren, aber aufgefhört haben zu leben.
    (Leonard da Vinci)

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.11.2005
    Alter
    42
    Beiträge
    1.140
    Im Ansatz richtig, in der Ausführung nicht ganz.
    1. In Deiner main-Funktion steht nur
    DDRA = 0x00;
    Die if Schleife steht völlig außerhalb jeder Funktion, da würde der Compiler meckern.
    2. Die DDR-Register werden normalerweise nur einmal beim initialisieren des Controllers gesetzt. Einen Port zur Laufzeit von Eingang zu Ausgang zu wechseln oder umgekehrt macht man eigentlich nicht.
    3. So wie Du's jetzt hast, würde PA1 nur ein einziges mal abgefragt, danach steht der Controller still. Da müsste noch eine Endlosschleife hin.
    4. Du hast ein paar Semikola vergessen...

    Hier mal das Programm, wie's korrekt aussehen würde:
    Code:
    include <avr/io.h>
    
    int main (void)
    {
    DDRA = 0x04;
    
    while(1)
    {
    if (PINA & 0x02)
    {
    PORTA = 0x04;
    }
    }
    return 0;
    Allerdings würde so PA2 angehen, wenn PA1 auf High geht - aber nie wieder aus. Da müsste dann noch was dazu, aber da lasse ich Dich erst mal basteln....

    Ach ja: ADC = Analog-Digital-Wandler = Eingang, um analoge Spannungen zu messen.

    Gruß,
    askazo

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Kandel
    Alter
    29
    Beiträge
    1.220
    Schön wäre jetzt noch die Verwendung von Konstanten anstelle von 0x04 ...
    Bsp:
    Code:
    include <avr/io.h>
    
    int main (void)
    {
    DDRA |= (1 << DDA2); //A2 auf Ausgang konfigurieren
    
    for(;;) //effektivste endlosschleife *g*
    {
    if (PINA & (1 << PINA1))
    {
    PORTA |= (1 << PA2); //Ausgang auf 1 setzen, ohne die anderen Werte "kaputt" zu machen - wenn direkt überschrieben werden soll wird anstelle von |= einfach nur = geschrieben.
    }
    return 0;
    }
    mfG
    Markus

    Edit: Im Nachfolgepost erwähnte Fehler behoben, danke johns!
    Edit: PB2 durch PA2 ersetzt - ich werd' auch immer wacher^^.

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    11.08.2005
    Beiträge
    178
    hallo,

    bin zwar ein alter copy'n'paster, aber das return sollte innerhalb der main funktion sein (letzte beiden zeilen vertauschen).
    (anmerkung: je nach compiler kann man das return statement auch weglassen, denn es wird ohnehin nie erreicht.)

    ausserdem passt in zeile 4 das kommentar nicht zur semantik des statements:
    DDRA = (1 << DDA2); //A2 auf Ausgang konfigurieren
    hier werden in wirklichkeit zusätzlich alle anderen pins von port A als eingang konfiguriert.

    und da markus die bitweisen operatoren eingebracht hat, hier weiter information zu diesem wichtigen thema:

    &, |, ^ und ~ operatoren:
    http://de.wikipedia.org/wiki/Bitweis...ise_Operatoren
    << und >> operatoren (für vorzeichenlose ganze zahlen):
    http://de.wikipedia.org/wiki/Bitweis...e_Verschiebung
    und hier nochmal für C speziell:
    http://home.fhtw-berlin.de/~junghans...T/bitwise.html

    und die (grösse der) in C verfügbaren elementaren datentypen:
    http://www.roboternetz.de/wissen/ind...are_Datentypen

    ausserdem wurde im gezeigten code die kuzschreibweise für arithmetische und logische operatoren verwendet (i.e. |=), eine erklärung ist hier in der tabelle "Kurzschreibweisen" zu finden:
    http://www.roboternetz.de/wissen/ind...der_Operatoren

    lg


    ps. zu erwähnen dass es sich bei 0x04 auch um eine konstante handelt würde wohl nur unnötig verwirrung stiften
    "A robot with guns for arms shooting a plane made out of guns that fires guns" - Nelson Muntz

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.11.2005
    Alter
    42
    Beiträge
    1.140
    Zitat Zitat von johns
    hallo,

    bin zwar ein alter copy'n'paster, aber das return sollte innerhalb der main funktion sein (letzte beiden zeilen vertauschen).
    Uups, natürlich....mein Fehler....

    @Markus:
    Wieso ist for( ; ; ) effektiver als while(1) ?

    Was man doch über ein so simples kleines Programm philosophieren kann....

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Kandel
    Alter
    29
    Beiträge
    1.220
    Danke johns, ich war so frei den Post oben entsprechend zu editieren ...

    Randbemerkung zu dem 0x04: Natürlich ist das auch eine Konstante, aber der sieht man nicht auf den ersten Blick an, was sie tut - bei:
    DDRA |= (1 << DDA2);
    weiß man sofort, dass hier der Pin A2 auf Ausgang konfiguriert wird.

    @askanzo: Sagt Atmel in der Application Note 35 (Efficient C-Code), dass for(; {} für Endlosschleifen am effektivsten ist ... komische Welt.

    mfG
    Markus

    PS: Ich würde dem Threadersteller die beiden AVR-C-Einführungen aus dem RN-Wissen und von mikrocontroller.net empfehlen!

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    03.12.2008
    Alter
    23
    Beiträge
    438
    Hi!
    Danke für die vielen Antworten!
    @askazo:
    Du hast gefragt wie man es machen könnte, damit der Roboter irgendwann wieder etwas anders macht:
    Könnte man vielleicht das "if" durch ein "while" ersetzen? In meinem Buch steht:
    Solange Anweisung, Ausdruck:
    while (PINA & (1 << PINA1))
    PORTA |= (1 << PORTA2)
    Danach könnte man einen neuen Block machen, welcher dann ausgeführt wird sobald (PINA & (1 << PINA1)) False ist...

    @markusj:
    Bei deinem Programm steht:
    PORTA |= (1 << PB2)
    Warum PB?
    Müsste da nicht PORTA2 stehen?

    Stimmt das ist die übersichtlichere Schreibweise... wenn ich z.B. PORTA |= (1 << PORTA3) schreibe, sind dann die restlichen PORTs von PORTA 0? bzw. Eingänge?

    Grüsse!


    Denn solange
    Wer keine Illusionen mehr hat, wird weiterhin existieren, aber aufgefhört haben zu leben.
    (Leonard da Vinci)

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Kandel
    Alter
    29
    Beiträge
    1.220
    Zitat Zitat von Da_Vinci13
    @markusj:
    Bei deinem Programm steht:
    PORTA |= (1 << PA2)
    Warum PB?
    Müsste da nicht PORTA2 stehen?

    Stimmt das ist die übersichtlichere Schreibweise... wenn ich z.B. PORTA |= (1 << PORTA3) schreibe, sind dann die restlichen PORTs von PORTA 0? bzw. Eingänge?
    Ich verweise jetzt einfach einmal auf mikrocontroller.net. Die Konstanten korrespondieren mit dem jeweiligen Register (X = Pinnummer):
    DDR? => DD?X
    PIN? => PIN?X
    PORT? => P?X

    mfG
    Markus

    Edit: PB2 durch PA2 ersetzt - ich werd' auch immer wacher^^.

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    11.08.2005
    Beiträge
    178
    Zitat Zitat von Da_Vinci13
    PORTA |= (1 << PB2)
    Warum PB?
    Müsste da nicht PORTA2 stehen?
    es sollte PA2 sein, würde aber so das selbe ergebnis liefern, da PA2 den selben wert darstellt wie PB2 (und PC2, ...), nämlich 2, den index des pins eben.

    Zitat Zitat von Da_Vinci13
    Stimmt das ist die übersichtlichere Schreibweise... wenn ich z.B. PORTA |= (1 << PORTA3) schreibe, sind dann die restlichen PORTs von PORTA 0? bzw. Eingänge?
    du hast einen port A an dem gewisse pins für andere dinge konfiguriert sind, und der pin mit nummer 3 ist 0. das konnte in binärdarstellung so aussehen:

    PORTA: 01100011

    als nächstes wird die klammer ausgewertet, also werden die bits des wertes 1 um 3 (wert von PA3) stellen nach rechts verschoben:

    00000001 << 3 ergibt 00001000

    dieser wert wird nun mit PORTA oder-verknüpft und das ergebnis wird in PORTA gespeichert:

    01100011 ODER
    00001000
    ------------
    01101011

    wie du siehst bleiben die restlichen pins unverändert.


    lg
    "A robot with guns for arms shooting a plane made out of guns that fires guns" - Nelson Muntz

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •