MyTetra Share
Делитесь знаниями!
Clock with 7-segments ver.2
Время создания: 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 <stdint.h>


//#include "my_init.h"


//typedef unsigned char uint8_t;


#define NOP asm volatile("NOP"::) //NOP

#define SEI asm volatile("sei"::) //enable interrupts

#define CLI asm volatile("cli"::) //disable interrupts


#define SEGM_DDR DDRC

#define SEGM PORTC //PC1..PC4 - 1..4 segment cathodes

#define CATHODE_MASK 0xE1 //1110.0001 - mask for turning off pins [1..4]

#define SEC_DOTS 0x80 //'mask' for switching on central dots on indicator panel

#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 SEGM_OFF SEGM &= CATHODE_MASK

#define SEGM_DDR_OFF SEGM_DDR &= CATHODE_MASK


#define HC595 PORTB

#define DS 0

#define ST 2

#define SH 1


#define MR 7

#define BUTT1 6


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

#define CLEAR_OFF PORTD |= (1<<MR)

#define CLEAR_ON PORTD &= ~(1<<MR)


//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 0x7A12


volatile unsigned int TCNT = 0; //timer overflow


//================================================================================

// INTERNAL INT SECTION

//================================================================================


ISR(TIMER0_OVF_vect)

{

++TCNT;

}


void clearRegState(void);


//================================================================================

// 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

//====================------------------------------------------------

ACSR |= 1<<ACD; //Disable analog comparator

//Timer0_START

TCCR0 = (TCCR0 | 1<<CS00) | (TCCR0 | 0<<CS01) | (TCCR0 | 0<<CS02); //NO Prescaler

TIMSK |= 1<<TOIE0; //Enable TIMER0 interrupts

//Timer0_END

DDRB = 0x07; //0000.0111 DDRB

DDRC = 0x1E; //0001.1110


DDRD |= 1 << MR; //pin D7 output for MR bit

DDRD &= ~(1 << BUTT1); //for button PullUp

PORTD |= 1 << BUTT1; //for button PullUp


SEGM = 0x00; //PORTC off

//SEGM &= CATHODE_MASK;

CLK_LOW;

LOCK_LOW;


clearRegState();


// CLEAR_MR;

// LOCK_HI;

// START_MR;


//====================------------------------------------------------

// END of INIT SECTION

//====================------------------------------------------------


unsigned char secBlink = 0; //dots state and blinking

unsigned char second_h = 3; //seconds counter

unsigned char second_l = 4; //have to convert in one var 'seconds' [1..60]

unsigned char minute_h = 1; //minutes counter

unsigned char minute_l = 2;

unsigned char hour_h = 0; //hours counter

unsigned char hour_l = 0;

// unsigned char button_state = 0;


SEI;


TCNT = 0; // +8 bytes to programm size!!!!!!!

//############================================---------------------------------------

// ---------------------------------= LOOPED CYCLE =---------------------------------

//############================================---------------------------------------

for(;;)

{

//button_state = PIND;

// if( (CHECKBIT(PIND, BUTT1)) == 0 && button_state == 0 && minute_l < 10)

// {

// button_state = 1;

// ++minute_l;

// }


//time calculating

if(TCNT > ONE_SECOND)

{

TCNT = 0;

button_state = 0;

++second_l;

if(secBlink == 0) secBlink = 1;

else {secBlink = 0;}

if(second_l == 10)

{

second_l = 0;

++second_h;

if(second_h == 6)

{

second_h = 0;

++minute_l;

if(minute_l == 10)

{

minute_l = 0;

++minute_h;

if(minute_h == 6)

{

minute_h = 0;

++hour_l;

if(hour_h < 2 && hour_l == 10)

{

hour_l = 0;

++hour_h;

}

else if(hour_h == 2 && hour_l == 4)

{

hour_l = 0;

hour_h = 0;

}

}

}

}

}

}

//end of time calculating


for(unsigned char segmentNumber = 4; segmentNumber > 0; --segmentNumber) //cycle for selecting data and same digital segment

{

unsigned char temp = 0;

unsigned char data = 0; //74HC595 pins state

unsigned char bit_counter = RAZR; //number of pins (8 for one or 16 for two 74HC595)


clearRegState();

switch(segmentNumber)

{

case 1: temp = hour_h; break;

case 2: temp = hour_l; break;

case 3: temp = minute_h; break;

case 4: temp = minute_l; break;

default: break;

}


//START of CODE SELECTING block for number:

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;

}

//END of CODE SELECTING block for number

if(secBlink == 1) data |= 1 << 7;


SEGM_OFF;

SEGM |= 1 << segmentNumber; //turn on one cathode


//sending of all 8 bites of data for 74HC595N:

do

{

DATA_LOW;

CLK_LOW;

if( CHECKBIT(data, --bit_counter) ) //if bit in data == 1

DATA_HI;

CLK_HI;

} while(bit_counter > 0);


CLK_LOW;

LOCK_HI;

LOCK_LOW;


//SEGM &= ~(1 << segmentNumber);

//SEGM_OFF;

}

#if 0

//WANT TO TRY WITH FOR(;;)

do //cycle for selecting data and same digital segment

{

bit_counter = RAZR;

// SEGM &= CATHODE_MASK; //0x1110.0001 - turn off all cathodes

PORTD &= ~(1 << 4);

PORTD &= ~(1 << 3);

SEGM &= ~(1 << 2);

SEGM &= ~(1 << 1);

unsigned char temp = 0;

if(segmentNumber == 4) //minutes 1st digit

{

temp = second_l;

// if(secBlink == 1) temp += SEC_DOTS;

// temp = second_h;

SEGM4_ON;

//temp = fMod10(minutes); // minutes % 10

}

else if(segmentNumber == 3) //minutes 2nd digit

{

temp = second_h;

// if(secBlink == 1) temp += SEC_DOTS;

// temp = minute_l;

SEGM3_ON;

}

else if(segmentNumber == 2) //hours 1st digit

{

temp = minute_l;

// temp = minute_h;

SEGM2_ON;

//temp = fMod10(hours); // hours % 10

}

else if(segmentNumber == 1) //hours 2nd digit

{

temp = minute_h;

// temp = second_l;

SEGM1_ON;

}

// Next code is bad, becouse uses more FLASH,

// then 4 comands SEGMx_ON. IDK why:

// SEGM |= (1 << segmentNumber); //turn on one cathode


//START of CODE SELECTING block for number:

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;

}

//END of CODE SELECTING block for number


//CLI;


//sending of all 8 bites of data for 74HC595N:

do

{

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;


--segmentNumber;

} while(segmentNumber);

#endif

}

return 0;

}


void clearRegState(void)

{

CLEAR_ON;

LOCK_HI;

CLEAR_OFF;

LOCK_LOW;

}

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