Marcazzan_M
Published © GPL3+

Timer with Arduino

A way to build a robust Timer with Arduino Uno.

IntermediateFull instructions provided5,224
Timer with Arduino

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1

Software apps and online services

Microchip Studio
Microchip Studio

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Custom parts and enclosures

Bom

BOM file

Schematics

Complete schematic

Code

main

C/C++
This code contains all the significant functions for the timer
/*
 * Timer.c
 *
 * Created: 
 * Author : Marcazzan_M
 */ 


#include <avr/io.h>
#include <avr/interrupt.h>
#include "myFunction.h"

//PIN
#define D2 PORTD6		/*Pin of the transistor of tens*/
#define D1 PORTD5		/*Pin of the transistor of tens*/
#define U2 PORTD4		/*Pin of the transistor of tens of seconds*/
#define U1 PORTD3		/*Pin of the transistor of unit of seconds*/

#define BUZZER PORTC0	/*Pin of Buzzer*/

#define DISPLAY_SECONDS
#define DISPLAY_MINUTES

/*VARIABLES*/
uint16_t timer=0;				/*Global Time of the system res:0.01s*/
uint8_t sec=0,m=5;				/*Time in seconds, start point is 5 minutes*/
uint8_t copySec=0,copyM=0;		/*Copy value of sec and m before count*/
uint8_t time_multiplex=0;		/*Timer for multiplexing the display*/
uint8_t dec,uni;				/*Decomposition of the value to visualize*/
uint8_t enableCountdown=0x00;	/*Flag that enable the countdown*/
uint8_t enableBuzzer=0x00;		/*Flag that enable the Buzzer*/
uint8_t timeBuzzer=0x00;		/*Time for the frequency of buzzer*/

uint8_t minuti=5,secondi=0;	/*Time to count*/

uint8_t INT1_served=0x00;		/*Flag if 0x00 INT1 not served, 0xff INT1 served*/
uint8_t timeDelay_INT1=0x00;
uint8_t INT0_served=0x00;
uint8_t timeDelay_INT0=0x00;

void computeVal(uint8_t v);
void displayVal(uint8_t v);

int main(void)
{
	initIO();			/*Init IO ports*/
	Timer0Init_IT();	/*Init Timer*/
	enablePrescaler();	/*Launch the timer*/	
	ExtIntInit();		/*Init the external interrupt*/
	
    while (1) 
    {
    }
	
}

/*Compute tens and units of v*/
void computeVal(uint8_t v){
	/*Compute tens*/
	if(v > MAX_VAL) return;
	/*There are problems of rounding so I use also UN_DEC_1*/
	if(v==69 || v==79 || v==89 || v==99) dec=(v*UN_DEC_1)>>8;
	else dec=(v*UN_DEC)>>8;
	uni=v-(uint8_t)(dec*DEC);
	return;
}

/*Display the number at PORTB and PORTD*/
void displayVal(uint8_t v){
	if(v>0x09 || v<0) return;
	uint8_t tmp=disp[v];
	uint8_t tmp1=tmp & MSB7;
	PORTB=(tmp1>>1);
	tmp1=tmp & BIT0;
	if(tmp1>0)PORTD=PORTD|0b10000000;
	else PORTD=PORTD & 0b01111111;
	return;
}

/*Service for timer0*/
ISR(TIMER0_COMPA_vect)
{
	time_multiplex++;	
	timer++;
	
	//Re Ability of INT1
	if(INT1_served){
		timeDelay_INT1++;
		if(timeDelay_INT1>=150){
			 EIMSK|=(1<<INT1); /*Enable interrupt on INT1*/	
			 INT1_served=0x00;
		}
		
	}
	//#################
	
	//Re Ability of INT0
	if(INT0_served){
		timeDelay_INT0++;
		if(timeDelay_INT0>=150){
			 EIMSK|=(1<<INT0); /*Enable interrupt on INT0*/
			 INT0_served=0x00;
		}
		
	}
	//#################
	
	PORTC = PORTC & 0b11010000;			/*Disable all transistors*/
	
	/*This code make the sound with the buzzer*/
	if(enableBuzzer){
		timeBuzzer++;
		if(timeBuzzer>=50) PORTC=PORTC|0b00010000;
		if(timeBuzzer>=100){
			 PORTC=PORTC&0b11101111;
			 timeBuzzer=0;
		}	
	}
	//############################################
	
	/*Every 1 second*/
	if(timer==200)
	{
		timer=0;
		/*Countdown*/
		if(enableCountdown){
			if(sec>0){
				sec--;
			}
			else{
				if(m>0){
					m--;
					sec=59;
				}
			}
			
			if(sec==0 && m==0) {
				enableCountdown=0x00;							/*Disable the countdown*/
				if(copySec>0||copyM>0) enableBuzzer=0xff;		/*Enable the Buzzer*/
				timeBuzzer=0;
			}
		}
	}
	
	
	computeVal(sec);					/*Compute the 2 number to display*/
	/*Display seconds*/
	if(time_multiplex==1){				/*Display tens of seconds*/
		PORTC = PORTC | 0b00000010;		/*Enable PORTC1*/
		displayVal(dec);				/*Display val*/
	}
		
	if(time_multiplex==2){				/*Display units of seconds*/
		PORTC = PORTC | 0b00000001;		/*Enable PORTC0*/
		displayVal(uni);				/*Display val*/			
	}

	computeVal(m);
	/*Display minuets*/
	if(time_multiplex==3 && (uni>0 || dec>0)){			/*Display units of minutes*/
		PORTC = PORTC | 0b00100100;						/*Enable PORTC2*/
		displayVal(uni);								/*Display val*/
	}

	if(time_multiplex==4){					/*Display tens of minutes*/
		if(dec>0){
			PORTC = PORTC | 0b00001000;		/*Enable PORTC3*/
			displayVal(dec);				/*Display val*/
		}
		time_multiplex=0;
	}

}

/*Handler for the external interrupt on INT0*/
ISR(INT0_vect){
	EIMSK=EIMSK&0xfe;		/*Disable interrupt on INT0*/
	INT0_served=0xff;
	timeDelay_INT0=0;
	
	
	if(enableCountdown==0x00){
		m++;					/*Increases the minutes by one*/
	}
	
	
	
	if(enableBuzzer==0xff){
		m=copyM;				/*The initial value of minutes and seconds*/
		sec=copySec;
	}
	if(enableBuzzer==0x00 && enableCountdown==0xff){
		m=0;					/*Reset the countdown*/
		sec=0;
	}
	
	PORTC=PORTC&0b11101111;		/*Force the buzzer to stop*/
	
	enableCountdown=0x00;		/*pause for the countdown*/
	
	/*Disable the buzzer*/
	enableBuzzer=0x00;
}

/*Handler for the external interrupt on INT1*/
ISR(INT1_vect){
	EIMSK=EIMSK&0xb11111101;	/*Disable interrupt on INT1 in order to eliminate the ringing on the button*/
	INT1_served=0xff;
	timeDelay_INT1=0;
	
	enableCountdown=0xff;		/*Enable the countdown*/
	copyM=m;					/*Make a copy of the initial value*/
	copySec=sec;
	
}

myFunction.h

C Header File
This is an header file for the main
/*
 *  myFunction.h
 *
 *  Created: 
 *  Author: Marcazzan_M
 *	This file contains some functions and constants that are used in main.c
 */ 

#include <avr/interrupt.h>

#ifndef MYFUNCTION_H_
#define MYFUNCTION_H_

/*CONSTANTS*/
#define UN_DEC 0x1A				/*1/10 in Q8*/
#define UN_DEC_1 (uint8_t)0x19	/*1/10 in Q8*/
#define DEC 0x0A				/*10*/
#define MAX_VAL 0x64			/*MAX VAL OF TIMER*/
const uint8_t disp[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7c,0x07,0x7f,0x6f};	/*Hex value for the numbers*/

/*MASK*/
#define MSB7 0b11111110	/*The first 7 MSB*/
#define BIT0 0b00000001 /*The bit number 1*/

/*Init of external interrupt*/
void ExtIntInit(void){
	EICRA=EICRA | 0b00000011;	/*The rising edge on INT0 generates an interrupt request*/
	EICRA=EICRA | 0b00001100;	/*The rising edge on INT1 generates an interrupt request*/
	EIMSK|=(1<<INT0);			/*Enable interrupt on INT0*/
	EIMSK|=(1<<INT1);			/*Enable interrupt on INT1*/
	sei();
}

/*Init of Timer0*/
void Timer0Init_IT(void) {
  /*Config Timer0*/
  TCCR0A = (1 << WGM01);    /*Set the CTC mode*/
  OCR0A = 0x4E;             /*Value for ORC0A for 0.005s*/

  TIMSK0 |= (1 << OCIE0A);  /*Set the interrupt request*/
  sei();                    /*Enable interrupt*/
  return;
}

/*Enable the prescaler*/
void enablePrescaler(void){
	TCCR0B |= (1 << CS02);    /*Set the prescaler 1/1024 clock*/
	TCCR0B |= (1 << CS00);
}

/*Disable the prescaler*/
void disablePrescaler(void){
	TCCR0B=TCCR0B & 0b11111000;
}

/*Init the I/O ports*/
void initIO(void){
	DDRD=0b11110000;
	DDRB=0b11111111;
	DDRC=0xff;
}


#endif /* MYFUNCTION_H_ */

Credits

Marcazzan_M

Marcazzan_M

6 projects • 67 followers
I'm an Italian student, I'm studying electronic engineering. Sufficiently advanced technology is indistinguishable from magic.

Comments