Таймер может быть запущен с использованием системы 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>