//********************************************************************************
//
// Файл			: dc_timer.c
//
// Автор		: DruidCat
//
// МК			: ATmega8 и ATmega328P
//
// Toolchain	: WinAVR|AVRToolchain
//
// Назначение	: Настройка таймера Т/С0, работает в микросекундах (1/1000000)
//
// Дата			: 24.02.2014
//
// Версия		: 1.1
//
//********************************************************************************

#include <avr/io.h>
#include <avr/interrupt.h>									//Подгружаем библиотеку прерываний
#include "dc_timer0.h"										//Подгружаем заголовочный файл драйвера

#if TC0_MKS == 0											/*Проверка, если время TC0_MKS заданно 0 мкс, то...*/
#error "TC0_MKS = 0, ERROR!!! TC0_MKS to Small."			/*TC0_MKS == 0, ОШИБКА!!!, TC0_MKS слишком маленькое значение*/
#endif

#define	TC0					(TC0_F_CPU/1024)*TC0_MKS		/*Расчет временного коэффициента*/
const static unsigned char	csuchTimer0 = (255 - TC0/1000000);//Расчет счетчика таймера Т/С0 по заданному времени TC0_MKS в мкс
static volatile	size_t		svuntCounterTimer0	= 0;		//Счетчик таймера T/C0

ISR (TIMER0_OVF_vect)										//Прерывание по переполнению Т/С0
/////////////////////////////////////////////////////////////////////////////////////////
//----------------------------П Р Е Р Ы В А Н И Е   Т / С 0----------------------------//
/////////////////////////////////////////////////////////////////////////////////////////
{
    TCNT0 = csuchTimer0;									//Выставляем счетчик на прервывание по выставленному времени.
    ++svuntCounterTimer0;
}

void initTimer0(void)										//Иннициализация таймера T/C0, как параметр принимает значение настройки таймера в миллисекундах
/////////////////////////////////////////////////////////////////////////////////////////
//--------------------------------I N I T   T I M E R 0--------------------------------//
/////////////////////////////////////////////////////////////////////////////////////////
{
    TCCR0A					= 0;							//T/C0 отсоединен от вывода ОС0, режим ШИМ отключен
    TCCR0B 					= (1 << CS02) | (1 << CS00);	//Коэффициент деления частоты системной синхронизации = 1024 (0b00000101)
    TCNT0					= csuchTimer0;					//Выставляем счетчик на прервывание по выставленному времени.
#if TC0_ATmega8				== 1							/*Выбор модели МК*/
	TIFR					= 0;							//Сбрасываем все флаги прерывания от Т/С0
	TIMSK					= (1 << TOIE0);					//Разрешаем прерывание при переполнении Т/С0 (0b00000100)
#endif
#if TC0_ATmega328P			== 1							/*Выбор модели МК*/
	TIFR0					= 0;							//Сбрасываем все флаги прерывания от Т/С0
	TIMSK0					= (1 << TOIE0);					//Разрешаем прерывание при переполнении Т/С0 (0b00000100)
#endif

    sei ();													//Запускаем прерывания
}

size_t getTimer0(void)										//Получение значения счетчика таймера (от 0 до 65535)
/////////////////////////////////////////////////////////////////////////////////////////
//---------------------------------G E T   T I M E R 0---------------------------------//
/////////////////////////////////////////////////////////////////////////////////////////
{
	return svuntCounterTimer0;								//Возвращаем значение счетчика таймера T/C0
}

void setTimer0zero(void)									//Функция установки счетчика таймера T/C0 в 0
/////////////////////////////////////////////////////////////////////////////////////////
//----------------------------S E T   T I M E R 0   Z E R O----------------------------//
/////////////////////////////////////////////////////////////////////////////////////////
{
	svuntCounterTimer0		= 0;							//Выставляем нулевое значение счетчика таймера
}
