Использование C для записи времени, необходимого для изменения света с помощью таймеров? - PullRequest
0 голосов
/ 05 марта 2019

В настоящее время я делаю небольшую встроенную систему, которая бы записывала время реакции пользователя при смене индикатора (с красного на синий) нажатием кнопки.

Я пытаюсь записать время, используяБиблиотека C, но моя проблема заключается в том, что при реализации таймеров (из библиотеки C) светодиодные фонари вообще не хотят включаться (работает без кода таймера).

#include <MKL25Z4.H>
#include <stdbool.h>
#include "SysTick.h"
#include "gpio.h"
#include "Reaction.h"
#include <stdio.h>      /* printf */
#include <time.h>       /* clock_t, clock, CLOCKS_PER_SEC */
#include <math.h>       /* sqrt */
#include <stdlib.h>



/*----------------------------------------------------------------------------
  Turn LEDs on or off 
    onOff can be ON or OFF
*----------------------------------------------------------------------------*/
void setRedLED(int onOff) {
    if (onOff == ON) {
        PTB->PCOR = MASK(RED_LED_POS) ;               
    } 
    if (onOff == OFF) {
        PTB->PSOR =  MASK(RED_LED_POS) ;
    }
    // no change otherwise
}

void setBlueLED(int onOff) {
    if (onOff == ON) {
        PTD->PCOR = MASK(BLUE_LED_POS) ;              
    } 
    if (onOff == OFF) {
        PTD->PSOR = MASK(BLUE_LED_POS) ;
    }
    // no change otherwise
}

void setExternalLED(int onOff) {
    if (onOff == ON) {
        PTE->PSOR = MASK(EXTERNAL_LED_POS) ;              
    } 
    if (onOff == OFF) {
        PTE->PCOR = MASK(EXTERNAL_LED_POS) ;
    }
    // no change otherwise
}

void setExternalBlueLED(int onOff) {
    if (onOff == ON) {
        PTE->PSOR = MASK(EXTERNALBLUE_LED_POS) ;              
    } 
    if (onOff == OFF) {
        PTE->PCOR = MASK(EXTERNALBLUE_LED_POS) ;
    }
    // no change otherwise
}

/*----------------------------------------------------------------------------
  isPressed: test the switch

  Operating the switch connects the input to ground. A non-zero value
  shows the switch is not pressed.
 *----------------------------------------------------------------------------*/
bool isPressed(void) {
    if (PTD->PDIR & MASK(BUTTON_POS)) {
        return false ;
    }
    return true ;
}

/*----------------------------------------------------------------------------
  checkButton

This function checks whether the button has been pressed
*----------------------------------------------------------------------------*/
int buttonState ; // current state of the button
bool pressed ; // signal if button pressed

void initButton() {
    buttonState = BUTTONUP ;
    pressed = false ; 
}

void checkButton() {
    switch (buttonState) {
        case BUTTONUP:
            if (isPressed()) {
                buttonState = BUTTONDOWN ;
                pressed = true ; 
            }
            break ;
        case BUTTONDOWN:
            if (!isPressed()) {
                buttonState = BUTTONUP ;
            }
            break ;
    }                               
}

/*----------------------------------------------------------------------------
  nextFlash 

This function evaluates whether the system should change state. 
The system stays in each state for a number of cycles, counted by 
the 'count' variable. It changes state of the button is pressed.
*----------------------------------------------------------------------------*/
int state ; 
int count ;

void initFlash() {
    count = PERIOD ;        
    state = EXTERNALON ;    
    setExternalBlueLED(OFF);
    setExternalLED(ON);
    start = clock();
}


void nextFlash() {
     if (count > 0) count -- ;
           switch (state) {
           case EXTERNALON:
                if (count == 0){   // The time transition has priority
                   setExternalLED(OFF);
                   setExternalBlueLED(ON);
                   state = EXTERNALBLUEOFF ;
                   count = PERIOD ;
               }
               break ;

           case EXTERNALBLUEOFF: 
              if (count == 0) {
                   setExternalBlueLED(OFF) ;
                   state = OFFState ;
                   count = PERIOD ;
               } else if (pressed) {
                   pressed = false ;
                   state = OFFState ;
               }            
               break ;
           case OFFState:
              {
              end = clock();
              setExternalLED(OFF);
              setExternalBlueLED(OFF);
              }
             break ;
        }
}

/*----------------------------------------------------------------------------
  Configuration 
     The configuration of the GPIO port
     Enabling the clocks.
     Configuring the PORTx peripheral, which controls the use of each pin
*----------------------------------------------------------------------------*/
void configureOutput() {
     // Configuration steps
     //   1. Enable clock to GPIO ports
     //   2. Enable GPIO ports
     //   3. Set GPIO direction to output
     //   4. Ensure LEDs are off

     // Enable clock to ports B and D and E
     SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK;

     // Make 3 pins GPIO
     PORTB->PCR[RED_LED_POS] &= ~PORT_PCR_MUX_MASK;          
     PORTB->PCR[RED_LED_POS] |= PORT_PCR_MUX(1);          
     PORTB->PCR[GREEN_LED_POS] &= ~PORT_PCR_MUX_MASK;          
     PORTB->PCR[GREEN_LED_POS] |= PORT_PCR_MUX(1);          
     PORTD->PCR[BLUE_LED_POS] &= ~PORT_PCR_MUX_MASK; 
     PORTD->PCR[BLUE_LED_POS] |= PORT_PCR_MUX(1);  

     // these lines make another pin of PortD a GPIO
     // define a suitable EXTERNAL_POS in gpio.h then uncomment 
     PORTE->PCR[EXTERNAL_LED_POS] &= ~PORT_PCR_MUX_MASK; 
     PORTE->PCR[EXTERNAL_LED_POS] |= PORT_PCR_MUX(1);   
         PORTE->PCR[EXTERNALBLUE_LED_POS] &= ~PORT_PCR_MUX_MASK; 
     PORTE->PCR[EXTERNALBLUE_LED_POS] |= PORT_PCR_MUX(1);   

     // Set ports to outputs
     PTB->PDDR |= MASK(RED_LED_POS) | MASK(GREEN_LED_POS);
     PTD->PDDR |= MASK(BLUE_LED_POS);
            PTE->PDDR |= MASK(EXTERNAL_LED_POS);
            PTE->PDDR |= MASK(EXTERNALBLUE_LED_POS);
     // Turn off LEDs
     PTB->PSOR = MASK(RED_LED_POS) | MASK(GREEN_LED_POS);
     PTD->PSOR = MASK(BLUE_LED_POS);

}

/*----------------------------------------------------------------------------
  GPIO Input Configuration

  Initialse a GPIO port D pin as an input (GPIO data direction register)
  Bit number given by BUTTON_POS
  Configure PORTD  so that the pin has no interrupt
     and a pull up resistor is enabled.
 *----------------------------------------------------------------------------*/
// 
void configureInput(void) {
    SIM->SCGC5 |=  SIM_SCGC5_PORTD_MASK; /* enable clock for port D */

    /* Select GPIO and enable pull-up resistors and no interrupts */
    PORTD->PCR[BUTTON_POS] |= PORT_PCR_MUX(1) | PORT_PCR_PS_MASK | PORT_PCR_PE_MASK | 
           PORT_PCR_IRQC(0x0);

    /* Set port D switch bit to be an input */
    PTD->PDDR &= ~MASK(BUTTON_POS);

}

/*----------------------------------------------------------------------------
  MAIN function
 *----------------------------------------------------------------------------*/
int  Reactionmain (void) {
    configureInput() ;  // configure the GPIO input for the button
    configureOutput() ;  // configure the GPIO outputs for the LED 
    initButton() ;
    initFlash() ;
    Init_SysTick(1000) ; // initialse SysTick every 1ms
    waitSysTickCounter(10) ; // cycle every 10ms

    while (1) {
        checkButton() ; // check button
        nextFlash() ; // flash LEDs 
        waitSysTickCounter(10) ; // wait to end of cycle
    }

}

Является ли моя реализациянеправильно?Есть ли другой способ / более эффективный способ сделать это, используя циклическую систему, а не потоки.

...