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

/*

03.04.2017


Program: 1930 bytes (23.6% Full)

Data: 14 bytes (1.4% Full)


Have to solve a problem with switching off alarm signal

by 3rd button when (time == alarm_time)


*/


#define F_CPU 8000000L

#define DEVICE (__AVR_ATmega8__)


#include <avr/io.h>

#include <avr/interrupt.h>

//#include <stdint.h>


#include "definitions.h"

#include "functionz.c"


#ifndef __DEFINITIONS_H__

#define __DEFINITIONS_H__


#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) //PORTC 1

#define SEGM2_ON SEGM |= (1<<2) //PORTC 2

#define SEGM3_ON SEGM |= (1<<3) //PORTC 3

#define SEGM4_ON SEGM |= (1<<4) //PORTC 4

#define SEGM_OFF SEGM &= CATHODE_MASK

#define SEGM_DDR_OFF SEGM_DDR &= CATHODE_MASK


#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) //PORTC 1

#define SEGM2_ON SEGM |= (1<<2) //PORTC 2

#define SEGM3_ON SEGM |= (1<<3) //PORTC 3

#define SEGM4_ON SEGM |= (1<<4) //PORTC 4

#define SEGM_OFF SEGM &= CATHODE_MASK

#define SEGM_DDR_OFF SEGM_DDR &= CATHODE_MASK


#define HC595 PORTB

#define DS 0 //data

#define ST 2 //locking

#define SH 1 //clock


//PORTD

#define MR 7 //for 74HC595

#define BUTT1 6 //PORTD6 - button #1 //change for pin2 and do interrupt INT0

#define BUTT2 5 //PORTD5 - button #2

#define BUTT3 4 //PORTD4 - button #3 //change for pin6

#define BUTT_MASK 0x70 //0111.0000 //change it after making INT0 interrupt

#define BUTTONS_STATE ((PIND) & (BUTT_MASK))

//BUTTONS_MASK

// 0111.0000

// |||button_3

// ||button_2

// |button_1

// MR (74HC595)


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

#if 0

#define SYM_SPACE 0x08;

#define SYM_o 0x5C;

#define SYM_n 0x54;

#define SYM_f 0x71;

#endif


#define CHECKBIT(BYTE,BIT) (BYTE & (1<<BIT)) //check bit setting

#define INVERTBIT(BYTE,BIT) (BYTE ^= (1<<BIT)) //invert first bit

//#define CHECKBUTTS(BYTE) (BYTE = PIND & BUTT_MASK)


//configuration modes:

#define MOFF 0 //cfg mode turned off (default)

#define MHOUR_H 1 //changing 1st hour digit

#define MHOUR_L 2 //changing 2nd hour digit

#define MMINUTE_H 3 //changing 1st minute digit

#define MMINUTE_L 4 //changing 2nd minute digit

#define MDAY_H 5 //changing day

#define MDAY_L 6 //changing 2nd digit of the day

#define MMONTH_H 7 //changing month

#define MMONTH_L 8 //changing 2nd digit of the month

#define MYEAR_4 9 //changing year

#define MYEAR_3 10 //changing year

#define MYEAR_2 11 //changing year

#define MYEAR_1 12 //changing year

#define MBACK_OFF 13 //end of first configuration list

#define MALARM_H_H 14 //changing 1st alarm hour

#define MALARM_H_L 15 //changing 2nd alarm hour

#define MALARM_M_H 16 //changing 1st alarm minute

#define MALARM_M_L 17 //changing 2nd alarm minute

#define MEND 18 //end of second configuration list

#define TIME_FOR_CONFIG 5 //cfg mode will have been working for 6 second after last button pressing


//timers

#define ONE_SECOND 0x7A12

#define HALF_SECOND 0x3D09

#define SEC_FOR_TIME 25 //how long will be displayed clock

#define SEC_FOR_DATE 5 //how long will be displayed date


//EEPROM addresses for variables

#define DAY_ADR 0x00

#define MON_ADR 0x01

#define YEARH_ADR 0x02

#define YEARL_ADR 0x03

#define ALRM_H_ADR 0x04 //alarm hours

#define ALRM_M_ADR 0x05 //alarm minutes

#define ALRM_ST_ADR 0x06 //address for state


//ALARM PREFERENCES

#define ALARM_REPEATS 3

#define ALARM_REPEAT0 0 //bit for checking pause between alarm signals

#define ALARM_REPEAT 2 //bit for checking pause between alarm signals

#define ALARM_STATE 4 //bit of global alarm state (alarm on/off)

#define ALARM_SIGNAL 5 //is it time for wake up?

#define ALARM_NO_REPEAT 6 //if alarm triggered


//INDICATORS

//#define INDICATION PORTD

#define INDICATION indic

#define TIME_INDICAT 1 //current display - time

#define DATE_INDICAT 2 //current display - date

#define YEAR_INDICAT 3 //current display - year

#define ALARM_INDICAT 0 //alarm is turned on

#define INDICATION_MASK 0xF0 //1111.0000

//#define INDICATION_OFF (INDICATION &= INDICATION_MASK)

//#define TIME_INDICAT_ON (INDICATION |= (1 << TIME_INDICAT))

//#define DATE_INDICAT_ON (INDICATION |= (1 << DATE_INDICAT))

//#define YEAR_INDICAT_ON (INDICATION |= (1 << YEAR_INDICAT))

//#define ALARM_INDICAT_ON (INDICATION |= (1 << ALARM_INDICAT))


#define TIME_INDICAT_ON (INDICATION |= (1 << TIME_INDICAT))

#define DATE_INDICAT_ON (INDICATION |= (1 << DATE_INDICAT))

#define YEAR_INDICAT_ON (INDICATION |= (1 << YEAR_INDICAT))

#define ALARM_INDICAT_ON (INDICATION |= (1 << ALARM_INDICAT))

//#define ALARM_INDICAT_OFF (INDICATION &= ~(1 << ALARM_INDICAT))


//bits of register of changes (for EEPROM writing)

#define CH_DAY 0 //day

#define CH_MONTH 1 //month

#define CH_YEARH 2 //years (high)

#define CH_YEARL 3 //years (low)

#define CH_ALRM_H 4 //alarm hours

#define CH_ALRM_M 5 //alarm minutes

#define CH_ALRM_ST 6 //alarm state


#define NIGHT_ON 0


#define LIGHT_PIN PINC

#define LIGHT_SENSOR 0

#define EN_DDR_LIGHT_SENSOR (DDRC &= ~(1 << LIGHT_SENSOR))

#define EN_PORT_LIGHT_SENSOR (PORTC &= ~(1 << LIGHT_SENSOR))

#define SENSOR_POWER 3

#define SENSOR_POWER_PORT PORTD


//#define RAZR16

#ifndef RAZR16

#define RAZR 8

#else

#define RAZR 16

#endif



#endif




#ifndef __FUNCTIONZ_H__

#define __FUNCTIONZ_H__




void clearRegState(void);

void sendRegData(const uint8_t data);

uint8_t assignDigit(const uint8_t val);

uint8_t assignSegment(const uint8_t segNu, const uint8_t, const uint8_t, const uint8_t, const uint8_t);

uint8_t calcRemainder(uint8_t val, uint8_t * const rem);

uint8_t incrValue(uint8_t val, const uint8_t limit, const uint8_t amount);

void EEPROM_write(uint16_t uiAddress, uint8_t ucData);

uint8_t EEPROM_read(uint16_t uiAddress);

uint8_t leapYearFoo(const uint8_t year_h, const uint8_t year_l);

uint8_t findMaxDay(const uint8_t month, const uint8_t leapYear);


#endif


// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

// GLOBALVARIABLES

// ------------------------------------------------------------------


volatile uint16_t TCNT = 0; //timer overflow


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

// INTERNAL INTERRUPTS SECTION

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


ISR(TIMER0_OVF_vect)

{

++TCNT;

}


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

// FUNCTION SECTION

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


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 &= ~(BUTT_MASK); //set 0 in DDRD for buttons

PORTD |= BUTT_MASK; //PullUp for buttons

DDRD |= 0x0F; //4 pins for LED indication

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


SEGM = 0x00; //PORTC off


EN_DDR_LIGHT_SENSOR;

EN_PORT_LIGHT_SENSOR;



CLK_LOW;

LOCK_LOW;


clearRegState();


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

// END of INIT SECTION

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


uint8_t dotsBlink = 1; //dots state and blinking (1 = dots're active)

uint8_t seconds = 55; //seconds counter

uint8_t minutes = 54;

uint8_t hours = 18;

uint8_t day = EEPROM_read(DAY_ADR);

uint8_t month = EEPROM_read(MON_ADR);

uint8_t year_h = EEPROM_read(YEARH_ADR); //first two digits of year

uint8_t year_l = EEPROM_read(YEARL_ADR); //last two digits of year

uint8_t maxDay = 31; //maximum of days in month (limited by 31 or 32 !)

uint8_t leapYear; //1 - leap, 0 - NOT leap

uint8_t alarm = EEPROM_read(ALRM_ST_ADR); //alarm state

uint8_t alarm_minutes = EEPROM_read(ALRM_M_ADR); //minutes for alarm

uint8_t alarm_hours = EEPROM_read(ALRM_H_ADR); //hours for alarm

uint8_t alarmSignalRepeat = 0; //counter of repeats

uint8_t displayTimer = 0; //timer for switching between clock and date displaying

uint8_t currentDisplay = 0; //0 = HH:MM, 1 = DD.MM, 2 = YYYY

uint8_t buttonPressed = 0; //set if any button pressed

uint8_t buttonState = 0; //0 = no one button is pressed, 1 - pressed

uint8_t cfgMode = 0; //for configuration (1..9)

uint8_t cfgModeTime = 0; //Auto exit from cfg mode after .. seconds

uint8_t cfgChanges = 0; //bits for checking date and time changes

uint8_t segmentBlinking = 1; //1 - digit is turned on

uint8_t nightMode = 0x01; //last bit for mode activation


if(month > 12 || month < 1) month = 1;

if(year_h > 99) year_h = 0;

if(year_l > 99) year_l = 0;

leapYear = leapYearFoo(year_h, year_l);

maxDay = findMaxDay(month, leapYear);

if(day > maxDay || day < 1) day = 1;

if(alarm_hours > 24) alarm_hours = 0;

if(alarm_minutes > 59) alarm_minutes = 0;


SEI;


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

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

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

for(;;)

{

//###########==========------------TO DO EVERY SECOND

if(TCNT >= ONE_SECOND)

{

TCNT -= ONE_SECOND; //main counter

++seconds; //main clock time

++displayTimer; //

++cfgModeTime; //time of active configuration mode


INVERTBIT(dotsBlink, 0);

//###########==========------------CHECK LIGHT SENSOR FIRST TIME

SENSOR_POWER_PORT |= 1 << SENSOR_POWER;

// if( !CHECKBIT(alarm, ALARM_SIGNAL) && alarmSignalRepeat )

// INVERTBIT(INDICATION, ALARM_INDICAT);


//###########==========------------IF CONFIGURATION IS TURNED ON

if(cfgMode) //if clck in configuration mode

{

if(cfgModeTime > TIME_FOR_CONFIG)

{

cfgMode = MOFF; //turn off cfg mode after X seconds

cfgModeTime = 0;

displayTimer = 0;

currentDisplay = 0;

//write date and time in EEPROM if it's changed:

}

else segmentBlinking = 0;

}

//###########==========------------IF SOMETHING WAS CHANGED AFTER CONFIGURATION

else if(cfgChanges) //if time or date were changed and there is no cfgMode

{

clearRegState();

//if alarm hours or minutes are changed:

if( CHECKBIT(cfgChanges, CH_ALRM_H) ) EEPROM_write(ALRM_H_ADR, alarm_hours);

if( CHECKBIT(cfgChanges, CH_ALRM_M) ) EEPROM_write(ALRM_M_ADR, alarm_minutes);

//if alarm state is changed:

if( CHECKBIT(cfgChanges, CH_ALRM_ST) ) EEPROM_write(ALRM_ST_ADR, CHECKBIT(alarm, ALARM_STATE) );

//if year is changed:

if( CHECKBIT(cfgChanges, CH_YEARL) ) EEPROM_write(YEARL_ADR, year_l);

if( CHECKBIT(cfgChanges, CH_YEARH) ) EEPROM_write(YEARH_ADR, year_h);

if( CHECKBIT(cfgChanges, CH_YEARL) || CHECKBIT(cfgChanges, CH_YEARH) )

leapYear = leapYearFoo(year_h, year_l); //check for leap year

//if month is changed:

if( CHECKBIT(cfgChanges, CH_MONTH) )

{

maxDay = findMaxDay(month, leapYear); //calculate maximum days in month

EEPROM_write(MON_ADR, month);

}

//if day is changed:

if( CHECKBIT(cfgChanges, CH_DAY) )

{

if(day > maxDay) day = 1; //need to check after month changes by user

EEPROM_write(DAY_ADR, day);

}


cfgChanges = 0;

}


//###########==========------------MAIN TIME COUNTING

if(seconds == 60)

{

// +++++++++++++++-------------

// repeat alarm 3 times every 5 seconds or while it's not switched off

alarm &= ~(1 << ALARM_SIGNAL);

if(alarmSignalRepeat)

{

++alarm;

// if alarm == xxxx.0101 == 5

if( CHECKBIT(alarm, ALARM_REPEAT) && CHECKBIT(alarm, ALARM_REPEAT0) )

{

--alarmSignalRepeat;

alarm |= 1 << ALARM_SIGNAL;

alarm &= 0xF0;

}

if( CHECKBIT(alarm, ALARM_NO_REPEAT) )

{

alarm &= ~(1 << ALARM_NO_REPEAT);

}

}


seconds = 0;

++minutes;

if(minutes == 60)

{

minutes = 0;

++hours;

if(hours == 24)

{

hours = 0;

++day;

if(day > maxDay)

{

day = 1;

++month;

if(month == 13)

{

month = 1;

++year_l;

if(year_l > 0x63) // 0x63 = 99

{

year_l = 0;

++year_h;

if(year_h > 0x63)

{

year_h = 0;

}

cfgChanges |= 1 << CH_YEARH; //save year_h in EEPROM

}

cfgChanges |= 1 << CH_YEARL; //save year_l in EEPROM

}

cfgChanges |= 1 << CH_MONTH; //save month in EEPROM

}

cfgChanges |= 1 << CH_DAY; //save day in EEPROM

}

}

}

//###########==========------------CHECK LIGHT SENSOR AGAIN

if( CHECKBIT(LIGHT_PIN, LIGHT_SENSOR) )

{

nightMode = 1;

}

else nightMode = 0;

SENSOR_POWER_PORT &= ~(1 << SENSOR_POWER);

}


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

if( CHECKBIT(alarm, ALARM_STATE) &&

!CHECKBIT(alarm, ALARM_NO_REPEAT) &&

minutes == alarm_minutes &&

hours == alarm_hours )

{

alarm |= 1 << ALARM_NO_REPEAT;

alarm |= 1 << ALARM_SIGNAL; //switch on alarm signals

alarmSignalRepeat = ALARM_REPEATS;

}


//switch on blinking if

if( CHECKBIT(alarm, ALARM_SIGNAL) ) //if it's alarm

{

currentDisplay = 0; //show time display

displayTimer = 0; //don't switch to other displays

segmentBlinking = 0; //switch on blinking

cfgMode = 0; //disable configuration mode

}


//###########==========------------IF BUTTON IS PRESSED

buttonState = BUTTONS_STATE; // check buttons


if( buttonState < BUTT_MASK && buttonPressed == 0 ) // if any button is pressed

{

cfgModeTime = 0; //clear time after any button pressing

displayTimer = 0; //reset timer for changing display

buttonPressed = 1; //set flag of pressed button


if(cfgMode == MOFF)

currentDisplay = 0; //back to screen with time


//###########==========------------1st BUTTON

// first button works only if there is no alarm signal

if( CHECKBIT(buttonState,BUTT1) == 0 && !CHECKBIT(alarm, ALARM_SIGNAL))

{

++cfgMode; //if BUTTON 1 - change mode

if(cfgMode == MDAY_H || cfgMode == MYEAR_4)

{

++currentDisplay; //go to the next display

}

else if(cfgMode == MBACK_OFF || cfgMode == MEND ) //set default display

{

currentDisplay = 0;

cfgMode = MOFF;

//cfgModeTime = 0;

}

}

//###########==========------------2nd BUTTON

else if( CHECKBIT(buttonState,BUTT2) == 0 && cfgMode) //if BUTTON 2 - depends on mode

{

uint8_t factor = 1;

switch(cfgMode)

{

case 1: factor = 10; //incr hour_h

case 2: hours = incrValue(hours, 24, factor); break; //incr hour_l (depends on hour_h)

case 3: factor = 10; //incr minute_h

case 4: minutes = incrValue(minutes, 60, factor); break; //incr minute_l

case 5: factor = 10;

case 6: day = incrValue(day, maxDay, factor); cfgChanges |= 1 << CH_DAY; break; //incr day

case 7: factor = 10;

case 8: month = incrValue(month, 13, factor); cfgChanges |= 1 << CH_MONTH; break; //incr month

case 9: factor = 10;

case 10: year_h = incrValue(year_h, 100, factor); cfgChanges |= 1 << CH_YEARH; break; //

case 11: factor = 10;

case 12: year_l = incrValue(year_l, 100, factor); cfgChanges |= 1 << CH_YEARL; break; //

case 14: factor = 10; //incr alarm hour_h

case 15: alarm_hours = incrValue(alarm_hours, 24, factor); cfgChanges |= 1 << CH_ALRM_H; break;

case 16: factor = 10; //incr alarm minute_h

case 17: alarm_minutes = incrValue(alarm_minutes, 60, factor); cfgChanges |= 1 << CH_ALRM_M; break;

default: break;

}

if(day == 0) day = 1;

if(month == 0) month = 1;

}

//###########==========------------3rd BUTTON

else if( CHECKBIT(buttonState,BUTT3) == 0)

{

if(cfgMode)

{

currentDisplay = 3; //show time for alarm

cfgMode = MALARM_H_H; //turn on mode for changing alarm time

}

else if(alarmSignalRepeat)

{

if( !CHECKBIT(alarm, ALARM_SIGNAL) )

alarmSignalRepeat = 0; //switch off alarm signals

alarm &= ~(1 << ALARM_SIGNAL);

}

else

{

INVERTBIT(alarm,ALARM_STATE); //turn on or off alarm

alarm &= ~(1 << ALARM_NO_REPEAT);

cfgChanges |= 1 << CH_ALRM_ST; //save the state in EEPROM

}

}

}

else if( buttonPressed && buttonState == BUTT_MASK ) // if all buttons are NOT pressed

{

buttonPressed = 0;

}


//###########==========------------CHECK LIGHT SENSOR

// need to realase checking this sensor not every cycle

// but every few seconds

// if( CHECKBIT(LIGHT_PIN, LIGHT_SENSOR) )

// {

// nightMode |= 1 << NIGHT_ON;

// }

// else nightMode &= ~(1 << NIGHT_ON);


//###########==========------------SHOW BLINKING

//in CONFIGURATION MODE or WHILE ALARM IS WORKING

if( (cfgMode || CHECKBIT(alarm, ALARM_SIGNAL) ) &&

segmentBlinking == 0 &&

TCNT > HALF_SECOND

)

{

segmentBlinking = 1;

}


//###########==========------------CHANGE DISPLAY

//between TIME, DATE and YEAR if display time has gone

if(currentDisplay == 0 && displayTimer > SEC_FOR_TIME && !alarmSignalRepeat)

{

++currentDisplay;

displayTimer = 0;

}

else if(currentDisplay && displayTimer > SEC_FOR_DATE)

{

if(currentDisplay < 2) ++currentDisplay;

else currentDisplay = 0;

displayTimer = 0;

}





//###########==========------------SHOW TIME OR DATE

// 0x01 --> night mode activated

// and indication is skipped while

// nightmode > 0x01

if( nightMode < 0x03 )

{

//cycle for selecting data and same digital segment:

for(register uint8_t segmentNumber = 4; segmentNumber > 0; --segmentNumber)

{

uint8_t data = 0; //74HC595 pins state

uint8_t indic = 0;

uint8_t temp = 0;

uint8_t segment_1 = 0;

uint8_t segment_2;

uint8_t * const pSegm2 = &segment_2;

uint8_t segment_3 = 0;

uint8_t segment_4;

uint8_t * const pSegm4 = &segment_4;


//SHOW TIME

if(currentDisplay == 0)

{

TIME_INDICAT_ON;

segment_1 = calcRemainder(hours, pSegm2);

segment_3 = calcRemainder(minutes, pSegm4);

}

//SHOW DAY AND MONTH

else if(currentDisplay == 1)

{

DATE_INDICAT_ON;

segment_1 = calcRemainder(day, pSegm2);

segment_3 = calcRemainder(month, pSegm4);

}

//SHOW YEAR

else if(currentDisplay == 2)

{

YEAR_INDICAT_ON;

segment_1 = calcRemainder(year_h, pSegm2);

segment_3 = calcRemainder(year_l, pSegm4);

}

//SHOW ALARM TIME

else if(currentDisplay == 3)

{

ALARM_INDICAT_ON;

segment_1 = calcRemainder(alarm_hours, pSegm2);

segment_3 = calcRemainder(alarm_minutes, pSegm4);

}


if( CHECKBIT(alarm, ALARM_SIGNAL) ||

(alarmSignalRepeat && dotsBlink) ||

(!alarmSignalRepeat && CHECKBIT(alarm, ALARM_STATE) )

)

{

ALARM_INDICAT_ON;

}


temp = assignSegment(segmentNumber, segment_1, segment_2, segment_3, segment_4);

data = assignDigit(temp);


// dont show configurable digit for 0.5 seconds

// while segmentBlinking == 0:

if(

segmentBlinking == 0

&&

(

cfgMode == segmentNumber ||

cfgMode == segmentNumber + 4 ||

cfgMode == segmentNumber + 8 ||

cfgMode == segmentNumber + 13 ||

CHECKBIT(alarm, ALARM_SIGNAL) //if alarm is working

)

)

{

data = 0;

}


//if needed to turn on two central dots, 7th bit will be added:

if

(

(dotsBlink == 1 && currentDisplay == 0) || //2 dots for time

(segmentNumber == 4 && currentDisplay == 1) || //1 dot for date

CHECKBIT(alarm, ALARM_SIGNAL) //always show 2 dots while alarm

)

{

data |= 1 << 7;

}


clearRegState();

SEGM_OFF; //turn off all cathodes

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

sendRegData(indic); //data for switching LED indicators

sendRegData(data); //sending of all 8 bites of data for 74HC595N:

LOCK_HI;

LOCK_LOW;

}

}

//###########==========------------SKIP INDICATION in NIGHT MODE

else

{

clearRegState();

}

// check night mode value to set pause between indication

// if last bit is set

if( nightMode > 0x01 )//&& CHECKBIT(nightMode, NIGHT_ON) )

--nightMode;

else if(nightMode == 0x01)

nightMode = 0xFF;


}

return 0;


}


#ifndef __FUNCTIONZ_C__

#define __FUNCTIONZ_C__


//#include "functionz.h"


void clearRegState(void)

{

CLEAR_ON;

LOCK_HI;

CLEAR_OFF;

LOCK_LOW;

}


void sendRegData(const uint8_t data)

{

uint8_t bit_counter = RAZR;

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;

}


uint8_t assignDigit(const uint8_t val)

{

//_____________________________________________

//START of CODE SELECTING block for number:

switch(val)

{

case 0: return DIG0;

case 1: return DIG1;

case 2: return DIG2;

case 3: return DIG3;

case 4: return DIG4;

case 5: return DIG5;

case 6: return DIG6;

case 7: return DIG7;

case 8: return DIG8;

case 9: return DIG9;

default: return val;

}

//END of CODE SELECTING block for number

}


//Assign LED segment with the right data

uint8_t assignSegment(const uint8_t segNu, const uint8_t v1, const uint8_t v2, const uint8_t v3, const uint8_t v4)

{

switch(segNu)

{

case 1: return v1;

case 2: return v2;

case 3: return v3;

case 4: return v4;

default: return 0;

}


}


/*

remainder will be returned through the pointer

integer part returns normaly

*/

uint8_t calcRemainder(uint8_t val, uint8_t * const rem)

{

uint8_t temp = 0;


while(val > 9)

{

val -= 10;

++temp;

}

*rem = val;

return temp;

}


/*

Increment for high or low part of the value

amount must be 10 for high part

or 1 for low part

*/

uint8_t incrValue(uint8_t val, const uint8_t limit, const uint8_t amount)

{

uint8_t remaind = 0; //remainder

uint8_t * const pRemaind = &remaind;

uint8_t result; //integer part


val = calcRemainder(val, pRemaind);


if(amount == 10)

{

result = (((++val) * 10) + remaind);

if( result >= limit )

return (0 + remaind);

else return result;

}

else// if(amount == 1)

{

result = ((val * 10) + (++remaind));

if( result >= limit || remaind == 10 )

return (val * 10);

else return result;

}

// else return 0;

}


void EEPROM_write(uint16_t uiAddress, uint8_t ucData)

{

while(EECR & (1<<EEWE)) // Wait for completion of previous write

{}

EEAR = uiAddress; //Set up address register

EEDR = ucData; //Set up data register

EECR |= (1<<EEMWE); //Write logical one to EEMWE

CLI;

EECR |= (1<<EEWE); //Start eeprom write by setting EEWE

SEI;

}


uint8_t EEPROM_read(uint16_t uiAddress)

{

while(EECR & (1<<EEWE)) // Wait for completion of previous write

{}

EEAR = uiAddress; //Set up address register

CLI;

EECR |= (1<<EERE); //Start eeprom read by writing EERE

SEI;

return EEDR; //Return data from data register

}


//365 or 366 days in current year?

uint8_t leapYearFoo(const uint8_t year_h, const uint8_t year_l)

{

uint16_t yr = (year_h << 8) + year_l;

if(yr % 400 == 0) return 1; //yes, it's a leap year

else if(yr % 100 == 0) return 0; //no, it's not a leap year

else if(yr % 4 == 0) return 1; //yes, it's a leap year

else return 0;

}


uint8_t findMaxDay(const uint8_t month, const uint8_t leapYear)

{

if(month == 2)

{

if(leapYear) return 29;

else return 28;

}

else

{

switch(month)

{

case 1:

case 3:

case 5:

case 7:

case 8:

case 10:

case 12: return 31;

case 4:

case 6:

case 9:

case 11:

default: return 30;

}

}

}


#endif

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