В настоящее время я делаю небольшую встроенную систему, которая бы записывала время реакции пользователя при смене индикатора (с красного на синий) нажатием кнопки.
Я пытаюсь записать время, используяБиблиотека 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
}
}
Является ли моя реализациянеправильно?Есть ли другой способ / более эффективный способ сделать это, используя циклическую систему, а не потоки.