Forum: Mikrocontroller und Digitale Elektronik Tasten gesteuertes Lauflicht


von Jessica K. (h21_j)


Angehängte Dateien:

Lesenswert?

Hallo, ich brauche eure Hilfe.
Ich möchte ein durch Tasten gesteuertes Lauflicht erstellen (LED0 bis 
LED7). Es soll durch Tastendruck auf S0 gestartet und gestoppt werden. 
Der Taster soll mit einer Warteschleife entstellt werden.
Es läuft soweit alles durch, bis auf den Taster. Könnte mir jemand 
helfen, was ich ändern muss damit ich mit dem Taster die LEDs ein und 
ausschalten kann?

Hier das Programm:
#include "stm32f411xe.h"
#include "uart.h"
#include <stdio.h>
/* ------------------------------------ DEFINES 
--------------------------------------- */
#define WAITTIME_WALKING_LIGHT    125            // 125 ms
#define WAITTIME_DEBOUNCE        10            // 10 ms
#define WAITTIME                250            // 250 ms
/* ------------------------------------ PROTOTYPES 
------------------------------------ */
void delay(const uint16_t ms);
int S0_pressed(void);
int main(void)
{
    __disable_irq();
    // Enable port clocks. PA clock on (LEDs) and PB clock on (buttons)
    RCC->AHB1ENR |= (RCC_AHB1ENR_GPIOAEN);
    // uOhm LEDs
    GPIOB->MODER &= ~(3<<0);    //PBO is input (SO), reset state
    GPIOB->PUPDR |=(1<<0);      //Pull up for PB0 on
    GPIOA->MODER |= (1<<0);
    GPIOA->MODER |= (1<<2);
    GPIOA->MODER |= (1<<4);
    GPIOA->MODER |= (1<<6);
    GPIOA->MODER |= (1<<8);
    GPIOA->MODER |= (1<<10);
    GPIOA->MODER |= (1<<12);
    GPIOA->MODER |= (1<<14);
    GPIOA->OTYPER |= 0xFF;      // Set PA0 - PA7 at Open Drain, because 
LEDs are connected to +5V
    GPIOA->ODR |= (0xFF);       // all LEDs off at the beginning
    GPIOB->MODER &= ~(3<<2);    //PB1 is input (S1), reset state
    GPIOB->PUPDR |= (1<<2);     // Pull up for PB1 on

    UART_init();
    UART_send_string("Hello Simulator!\r\n");
    __enable_irq();
int i=0;
while(S0_pressed())
{
    for(i=0;i<8;i++)
    {
            GPIOA->ODR &= ~(1<<i);
            delay(WAITTIME_WALKING_LIGHT);        // wait
            GPIOA->ODR |= (1<<i);    // LED0 off
            delay(WAITTIME_WALKING_LIGHT);        // wait
    }
    for(i=6;i<8;i--)
    {
        GPIOA->ODR &= ~(1<<i);
        delay(WAITTIME_WALKING_LIGHT);        // wait
        GPIOA->ODR |= (1<<i);    // LED0 off
        delay(WAITTIME_WALKING_LIGHT);        // wait
    }
}
    return 1;
}
/* 
------------------------------------------------------------------------ 
------------  *\
 * method:  void delay(const uint16_t ms)
 *
 * It realizes a millisecond delay by very bad busy-wait.
 *
 * requires:    - nothing -
 * parameters:  ms - delay time in milliseconds
 * returns:     - nothing -
\* 
------------------------------------------------------------------------ 
------------  */
void delay(const uint16_t ms)
{
    for (uint16_t i = 0; i < ms; ++i)
    {
        for (uint16_t j = 0; j < 3500; ++j) // clock cycles per loop, 
fixed for simulator
        {
            __asm("NOP");
        }
    }
}
int S0_pressed(void)
{
    if ((GPIOB->IDR & 0x01) !=1)                    //wenn gedrückt dann 
null, wenn es ungleich 1 ist dann kommt eine 1 uns wird in die Schleife 
gegangen
    {
        delay(WAITTIME_DEBOUNCE);                   //waittime damit 
entprellt wird,
                if ((GPIOB->IDR & 0x01) != 1)
                {
                    while ((GPIOB->IDR & 0x01) !=0);   //es geht in die 
schleife bis es nicht mehr eins ist sondern null
                    delay(WAITTIME_DEBOUNCE);
                    return 1;
                }
    }
    return 0;
}

Vielen Dank

von Stefan F. (Gast)


Lesenswert?

Mache erst einmal einen ordentlichen Screenshot (das geht mit der DRUCK 
Taste) und formatiere den Quelltext so, dass er lesbar ist.

> Es läuft soweit alles durch, bis auf den Taster.

Das ist keine klare Fehlerbeschreibung. Wen du den Verdacht hast, dass 
die Tasterabfrage nicht funktioniert, dann schreibe mal ein minimales 
Programm dass den Zustand des Tasters einliest und an einer LED (kein 
Lauflicht) ausgibt. Außerdem solltest du den Debugger nutzen, um 
herauszufinden, wo es hakt.

Danach kannst du viel konkretere Fragen stellen, wo wir wiederum besser 
helfen können.

Ein Schaltplan wäre dazu auch noch sehr hilfreich. Vielleicht hast du ja 
ganz banal den Schalter falsch angeschlossen.

Noch ein Hinweis zum Programmierstil: Diese magischen Zahlen wie 
"(1<<14)" sind vollkommen überflüssig. In den Header Dateien ist für 
jedes Bit ein aussagekräftiger Name definiert. Wenn du diese Konstanten 
stattdessen benutzt, wird der Quelltext viel besser lesbar. Dadurch 
vermeidest du viele mögliche Fehler.

von Stefan F. (Gast)


Lesenswert?

Die Entprell-Routine hat einen Logigfehler. Ich lese sie so:
1
Wenn Taste gedrückt wurde, dann
2
  warte 10ms
3
  nur wenn Taste dann immer noch gedrückt ist, dann
4
    warte solange die Taste nicht gedrückt ist <<<<< ???
5
    warte 10ms
6
    return 1
7
return 0

Letztendlich wird der Tastendruck schon erkannt, aber nicht korrekt 
entprellt. Ich nehme an, dass du noch woanders einen gravierenderen 
Fehler hast.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.