Мм: сс таймер с - PullRequest
       34

Мм: сс таймер с

0 голосов
/ 29 августа 2018

Пытаясь создать таймер на C, который считает в формате mm: ss, мне не обязательно печатать значение, просто оно существует для ссылки.

Идея состоит в том, что на устройстве, предназначенном для подростков, проходят часы с истекшим временем: каждую секунду по истечении таймера увеличивается на 1 секунду, через 60 секунд, таймер минут увеличивается на 1, а таймер секунд сбрасывается на 0. Таймер работает в фоновом режиме, обновляя себя каждую секунду, чтобы действовать как своего рода непрерывный секундомер.

Подобно изображению ниже, однако таймер не запускается и не останавливается по желанию, он запускается при инициализации программы и просто увеличивает счетчик каждую секунду, минуты не нужно преобразовывать и могут доходить до 99, как к этому времени программа должна была закончиться.

enter image description here

Примером являются часы, показывающие время, прошедшее с начала уровня игры, показывающее пользователю, сколько времени им потребовалось для завершения уровня.

Я попробовал это сделать ниже, но из-за того, что я не знаком с тем, как работают языки на основе C и C, я не уверен, что я даже иду в правильном направлении.

int minutes = 0;
int seconds = 0, trigger = 1000;
clock_t start = clock();
do {
  if(seconds == 60) {
    seconds = 0;
    minutes += 1;
  }
  clock_t difference = clock() - start;
  seconds = difference * 1000 / CLOCKS_PER_SEC;
  i++;
} while ( seconds < trigger );

Например, скажем, прошло x секунд;

  • 89 секунд (1 мин 9 сек)

    Time: 01:19
    
  • 360 секунд (6 минут 0 секунд)

    Time: 06:00
    
  • 27 секунд (0 минут 27 секунд)

    Time: 00:27
    
  • 4893 секунды (81 мин 33 с)

    Time: 81:33
    

таймер должен вернуться, как указано выше.

Система Windows.

Может кто-нибудь помочь с этим? Вы можете составить любые переменные, какие захотите или что угодно, потому что все, что я знаю, что я сделал, даже ни к чему не приведет. Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 02 апреля 2019

Таймер может быть запущен с использованием системы Teensy с использованием его переполнений и прерываний. Приведенный ниже код установит и запустит таймер, который будет отсчитывать в. Структура используется для инициации логического значения (среди прочих возможных вещей в программе), которое можно использовать для контроля того, имеет ли место переполнение таймера, эффективно останавливая таймер.

Функция для рисования строки

 // Render a string of printable ASCII characters into the screen buffer.
 // Parameters:
 // x - The horizontal position of the top-left corner of the displayed text.
 // y - The vertical position of the top-left corner of the displayed text.
 // character - The ASCII code of the character to render. Valid values range from 
 0x20 == 32 to 0x7f == 127.
 // colour - The colour, FG_COLOUR or BG_COLOUR. If colour is BG_COLOUR,
 the text is rendered as an inverse video block.

void draw_string(int top_left_x, int top_left_y, char *text, colour_t colour) {
    // Draw each character until the null terminator is reached
    for ( uint8_t x = top_left_x, i = 0; text[i] != 0; x += CHAR_WIDTH, i++ ) {
        draw_char(x, top_left_y, text[i], colour);
        // Add a column of spaces here if you want to space out the lettering.
        // (see lcd.c for a hint on how to do this)
    }
}

Ниже приведена функция форматирования с использованием вышеуказанной функции для рисования строки, функция форматирования используется для получения разметки mm: ss

// a formatting function to assist with printing to the screen
void draw_formatted(int x, int y, const char * format, ...) {
    va_list args;
    va_start(args, format);
    char buffer[1000];
    vsprintf(buffer, format, args);
    draw_string(x, y, buffer, FG_COLOUR);
}

С отсортированным форматированием должна быть создана структура для инициации значений, необходимых для работы таймера, и таймер инициирован

// initiates a struct for the timer, which includes a minute, second and 
// validator accessed using tim
struct val_store {
    bool timer_validator;
    uint8_t time_passed
    uint8_t min;
    uint8_t sec;
} tim;

// initiates timer parameters, essentially setting up the timer to be able to function, 
// sets timer to begin, this should be included in the initial setup of a program
TCCR1A = 0;
TCCR1B = 2; 
TIMSK1 = 1;
sei();
tim.timer_validator = true;

Ниже скрытая часть таймера, это сердце, оно создает значения, которые являются основой всего этого вопроса, это очень важно и не будет работать, если только TCCR1A, TCCR1B, TIMSK1 и sei () инициируются заранее, значения могут варьироваться от 0, 2, 1 соответственно, однако значения, используемые в приведенном ниже таймере, должны быть соответствующим образом скорректированы с использованием битовой диаграммы

// Create a volatile global variable called over_flow_count
volatile unsigned int over_flow_count = 0;
//  interrupt service routine to process timer overflow
//  interrupts for Timer 1.
ISR(TIMER1_OVF_vect) {
    // checks if timer is active or not
    if (tim.timer_validator) {
    over_flow_count++;
    }
}
// elapsed time since program start
// use float instead of double to save memory
float elapsed_time(void) {
    float current_time = (float)
        ( ( over_flow_count * 65536.0 + TCNT1 ) * 8.0  / 8000000 );
    return current_time;
}

Наконец, код, который работает с указанным выше таймером для получения вывода в формате mm: ss, прост из-за того, что таймер выше выполняет всю работу, остается только форматирование. прошедшее время вызывает ранее созданную функцию, которая представляет собой общий пройденный период времени, мин и секунда затем определяются с использованием деления и по модулю и форматируются с использованием ранее сделанной функции форматирования

tim.time_passed = elapsed_time();
tim.min = time_passed / 60;
tim.sec = time_passed % 60;
draw_formatted(x, y, "Time: %02d:%02d", tim.min, tim.sec);

Паузу можно создать, используя аналогичный

if (BIT_VALUE(PINB, 0)) {
    // buffer before and after to prevent a single press activating
    // multiple instances of a joystick press, cheap interrupt
    _delay_ms(250);

    // pauses timer by setting the boolean to false, preventing the if statement passing
    tim.timer_validator = false;

    while(true) {
        clear_screen();
        #Put processes to occur while paused here

        // checks to see if the pause should resume
        if (BIT_VALUE(PINB, 0)) {
            break;
        }

    // continue timer
    tim.timer_validator = true;

    // once again a buffer for good measure
    _delay_ms(250);
    }

Если программа создана правильно, таймер должен обновиться задним числом! Надеюсь, это поможет!

Соответствующие включения, могут использоваться не все включения.

// includes
#include <assert.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <cpu_speed.h>
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <util/delay.h>
0 голосов
/ 29 августа 2018

Не уверен насчет вашей цели: просто считать секунды, пока не дойдете до триггера, а затем преобразовать в мм: сс? Вы можете просто считать секунды до достижения триггера и выражать триггер в виде mm: ss, это в основном одно и то же.

Просто догадываясь, что-то вроде этого вы ищете?

unsigned int minutes = 0;
unsigned int seconds = 0;

unsigned int trigger = 360;
unsigned int elapsed_seconds = 0;

/* Count the seconds until #trigger seconds are reached (?)*/
clock_t start = clock();

do {

  clock_t difference = clock() - start;
  elapsed_seconds = difference * 1000 / CLOCKS_PER_SEC;

  /* Stop at trigger (?)*/
} while ( elapsed_seconds < trigger );

/* Express in minutes and seconds */
minutes = elapsed_seconds / 60;
seconds = elapsed_seconds % 60;

printf("Time: %02d:%02d\n", minutes, seconds);
...