MyTetra Share
Делитесь знаниями!
Clock with 7-segments
Время создания: 30.11.2017 14:56
Раздел: Electronics - Microcontrollers - AVR8 - AVR GCC - C_PROJ - Clock 7sgm (blue)

#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;

}


 
MyTetra Share v.0.53
Яндекс индекс цитирования