#define F_CPU 8000000L
#define DEVICE (__AVR_ATmega8__)
#include <avr/io.h>
#include <avr/interrupt.h>
//#include "my_init.h"
#define NOP asm volatile("NOP"::) //NOP
#define SEI asm volatile("sei"::) //enable interrupts
#define CLI asm volatile("cli"::) //disable interrupts
#define SEGM PORTC //PC1..PC4 - 1..4 segment cathodes
#define CATHODE_MASK 0xE1 //1110.0001 - mask for turning off pins 1..4
#define SEGM1_ON SEGM |= (1<<1)
#define SEGM2_ON SEGM |= (1<<2)
#define SEGM3_ON SEGM |= (1<<3)
#define SEGM4_ON SEGM |= (1<<4)
#define HC595 PORTB
#define DS 0
#define ST 2
#define SH 1
#define DATA_HI HC595 |= (1<<DS)
#define DATA_LOW HC595 &= ~(1<<DS)
#define CLK_HI HC595 |= (1<<SH)
#define CLK_LOW HC595 &= ~(1<<SH)
#define LOCK_HI HC595 |= (1<<ST)
#define LOCK_LOW HC595 &= ~(1<<ST)
//for indicator with common cathode
//D0..D7 == A,B,C,D,F,G,DP
#define DIG1 0x06;
#define DIG2 0x5B;
#define DIG3 0x4F;
#define DIG4 0x66;
#define DIG5 0x6D;
#define DIG6 0x7D;
#define DIG7 0x07;
#define DIG8 0x7F;
#define DIG9 0x6F;
#define DIG0 0x3F;
#define CHECKBIT(BYTE,BIT) (BYTE & (1<<BIT)) //check bit setting
//#define RAZR16
#ifndef RAZR16
#define RAZR 8
#else
#define RAZR 16
#endif
#define ONE_SECOND 0x0327
//#define ONE_SECOND 0x1A27
//#if 0
volatile unsigned int TCNT = 0; //timer overflow
//================================================================================
// INTERNAL INT SECTION
//================================================================================
ISR(TIMER0_OVF_vect)
{
++TCNT;
}
//#endif
//================================================================================
// FUNCTION SECTION
//================================================================================
unsigned char fMod10(const unsigned char val)
{
unsigned char temp = ((val*(256/10)) >> 8);
return (val - (temp << 2) + temp);
}
int main(void)
{
//====================
// INIT SECTION
//====================
//Timer0_START
TCCR0 = (TCCR0 | 0<<CS00) | (TCCR0 | 1<<CS01) | (TCCR0 | 0<<CS02); //NO Prescaler
TIMSK |= 1<<TOIE0; //Enable TIMER0 interrupts
//Timer0_END
DDRB = 0x07; //0000.0111 DDRB
DDRC = 0x1E; //0001.1110
SEGM = 0x00;
//SEGM &= CATHODE_MASK;
//====================
// END of INIT SECTION
//====================
CLK_LOW;
LOCK_LOW;
unsigned char data = DIG0; //74HC595 pins state
unsigned char bit_counter = RAZR; //number of pins (8 for one or 16 for two 74HC595)
unsigned char seconds = 0; //seconds counter
unsigned char minutes = 34; //minutes counter
unsigned char hours = 12;
unsigned char segmentNumber = 0; //number of segment
SEI;
TCNT = 0; // +8 bytes to programm size!!!!!!!
for(;;)
{
segmentNumber = 4;
bit_counter = RAZR;
//time calculating
if(TCNT > ONE_SECOND)
{
TCNT = 0;
++seconds;
if(seconds >= 60)
{
seconds = 0;
++minutes;
if(minutes >= 60)
{
minutes = 0;
++hours;
if(hours >= 24)
{
hours = 0;
}
}
}
}
//end of time calculating
do
{
// SEGM &= CATHODE_MASK; //0x1110.0001 - turn off all cathodes
SEGM &= ~(1 << 4);
SEGM &= ~(1 << 3);
SEGM &= ~(1 << 2);
SEGM &= ~(1 << 1);
unsigned char temp = 0;
if(segmentNumber == 4) //minutes 1st digit
{
unsigned char trash = minutes / 10;
temp = minutes - trash * 10;
// SEGM4_ON;
//temp = fMod10(minutes); // minutes % 10
// ++ vklu4it' nujniy segment
}
else if(segmentNumber == 3) //minutes 2nd digit
{
temp = minutes / 10;
// SEGM3_ON;
// ++ vklu4it' nujniy segment
}
else if(segmentNumber == 2) //hours 1st digit
{
unsigned char trash = hours / 10;
temp = hours - trash * 10;
// SEGM2_ON;
//temp = fMod10(hours); // hours % 10
// ++ vklu4it' nujniy segment
}
else if(segmentNumber == 1) //hours 2nd digit
{
temp = hours / 10;
// SEGM1_ON;
// ++ vklu4it' nujniy segment
}
SEGM |= (1 << segmentNumber); //turn on one cathode
//what digit is next:
switch(temp) {
case 0: data = DIG0; break;
case 1: data = DIG1; break;
case 2: data = DIG2; break;
case 3: data = DIG3; break;
case 4: data = DIG4; break;
case 5: data = DIG5; break;
case 6: data = DIG6; break;
case 7: data = DIG7; break;
case 8: data = DIG8; break;
case 9: data = DIG9; break;
}
//CLI;
do //send all 8 bites of data
{
DATA_LOW;
CLK_LOW;
if( CHECKBIT(data, --bit_counter) ) //if bit in data == 1
DATA_HI;
CLK_HI;
} while(bit_counter);
CLK_LOW;
LOCK_HI;
LOCK_LOW;
//SEI;
} while(--segmentNumber);
#if 0
//what digit is next:
switch(seconds) {
case 0: data = DIG0; break;
case 1: data = DIG1; break;
case 2: data = DIG2; break;
case 3: data = DIG3; break;
case 4: data = DIG4; break;
case 5: data = DIG5; break;
case 6: data = DIG6; break;
case 7: data = DIG7; break;
case 8: data = DIG8; break;
case 9: data = DIG9; break;
}
do //send all 8 bites of data
{
DATA_LOW;
CLK_LOW;
if( CHECKBIT(data, --bit_counter) ) //if bit in data == 1
DATA_HI;
CLK_HI;
} while(bit_counter);
CLK_LOW;
LOCK_HI;
LOCK_LOW;
#endif
}
return 0;
}