Code:
/*****************************************************
Project : DCF77_Stoppuhr
Version : 1.2
Date : 06.01.2009
Author : Wilhelm Krug
Company : 92345 Dietfurt, Germany
Comments:
Chip type : ATmega16L
Program type : Application
Clock frequency : 8,000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 256
*****************************************************/
#include <mega16.h>
#include <delay.h>
#include <stdlib.h>
#include <string.h>
// Zeichentabelle für 7 Segment Display
//0,1,2,3,4,5,6,7,8,9,A,b,c,d,E,F,h,J,L,n,o,P,r,u,[]
volatile unsigned char uc_chartable[25]={
0b00111111,/*0*/
0b00001100,
0b01011011,
0b01011110,
0b01101100,
0b01110110,
0b01110111,
0b00011100,
0b01111111,
0b01111110,/*9*/
0b01111101,/*A*/
0b01100111,/*b*/
0b01000011,/*c*/
0b01001111,/*d*/
0b01110011,/*E*/
0b01110001,/*F*/
0b01101101,/*H*/
0b00011110,/*J*/
0b00100011,/*L*/
0b01000101,/*n*/
0b01000111,/*o*/
0b01111001,/*p*/
0b01000001,/*r*/
0b00000111,/*u*/
0b00000000};/*Leerzeichen*/
// Segmentbuffer
volatile unsigned char uc_segment[6]={0,0,0,0,0,0};
volatile unsigned char uc_segmentcounter=0;
// Displaysteuerung
volatile unsigned char uc_dispmode=0;
// Stoppuhr Zähler Steuerung
bit ub_counting=0; /* Flag Stoppuhr läuft */
bit ub_stopdelay=0; /* Flag Stopauslöseverzögerung aktiv */
bit ub_autoreset=0; /* Flag Autoreset der Stoppuhr aktiv */
volatile unsigned int ui_stopdelay; /* Wert für das Stopdelay */
volatile unsigned int ui_stopcounter=0; /* Counter für das Stopdelay */
eeprom unsigned int ee_stopdelay=600; /* EEPROM SPeicherplatz für das Stopdelay */
volatile unsigned int ui_autoresetcount=0; /* Downcounter für den Autoreset */
volatile unsigned int ui_autoreset; /* Wert für den Autoreset */
eeprom unsigned int ee_autoreset=500; /* EEPROM Speicherplatz für den Autoreset */
// Stoppuhr UP Zähler
volatile unsigned char uc_countmsek=0;
volatile unsigned char uc_countsek=0;
volatile unsigned char uc_countmin=0;
volatile unsigned char uc_countstd=0;
// Stoppuhr Down Zähler
volatile unsigned char uc_downmsek=0;
volatile unsigned char uc_downsek=0;
volatile unsigned char uc_downmin=0;
volatile unsigned char uc_downstd=0;
eeprom unsigned char ee_downmsek=0;
eeprom unsigned char ee_downsek=0;
eeprom unsigned char ee_downmin=1;
eeprom unsigned char ee_downstd=1;
// DCF Uhr
unsigned int MS_Count = 0,old_ms_count = 0,MeasureBit = 0;
volatile unsigned char cnt_okay = 0;
volatile char sek_count = 0;
volatile unsigned char TimeHours = 0, TimeMinutes = 0, TimeSeconds = 0, DateMonth = 0, DateDay = 0,Weekday = 0;
volatile unsigned int HiLoTimeAverage = 10;
volatile unsigned int TimeMilliseconds = 0;
volatile unsigned char DCF77Bit = 0,NewBit = 0;
volatile unsigned char value = 0;
volatile char startbit,parity;
volatile unsigned char dcf77_hour = 88, dcf77_minute = 88, dcf77_day = 88, dcf77_month = 88, dcf77_wday = 88, dcf77_year = 88;
// Tastaturabfrage zum Setup
volatile unsigned char uc_readtast=0;
volatile unsigned char uc_oldtast=0;
#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
// USART Transmitter buffer
#define TX_BUFFER_SIZE 40
char tx_buffer[TX_BUFFER_SIZE];
#if TX_BUFFER_SIZE<256
unsigned char tx_wr_index,tx_rd_index,tx_counter;
#else
unsigned int tx_wr_index,tx_rd_index,tx_counter;
#endif
// USART Transmitter interrupt service routine
interrupt [USART_TXC] void usart_tx_isr(void)
{
if (tx_counter)
{
--tx_counter;
UDR=tx_buffer[tx_rd_index];
if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
};
}
#ifndef _DEBUG_TERMINAL_IO_
// Write a character to the USART Transmitter buffer
#define _ALTERNATE_PUTCHAR_
#pragma used+
void putchar(char c)
{
while (tx_counter == TX_BUFFER_SIZE);
#asm("cli")
if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))
{
tx_buffer[tx_wr_index]=c;
if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
++tx_counter;
}
else
UDR=c;
#asm("sei")
}
#pragma used-
#endif
// External Interrupt 0 service routine -> Starten der Stoppuhr
interrupt [EXT_INT0] void ext_int0_isr(void)
{
ub_counting=1;
GICR&=0b00111111;
GIFR|=0b11000000;
ui_stopcounter=0;
ub_stopdelay=1;
};
// External Interrupt 1 service routine -> Stoppen der Stopuhr
interrupt [EXT_INT1] void ext_int1_isr(void)
{
unsigned char uc_i,uc_stringlengh;
unsigned char uc_stringbuffer[4];
unsigned char uc_sendstring [40];
ub_counting=0;
ui_stopcounter=0;
GICR&=0b00111111;
// Aktivierung des Autoreset bei Resetzeiten größer 1 Sekunde
if(ui_autoreset>99)
{
ui_autoresetcount=ui_autoreset+100;
ub_autoreset=1;
};
// Nur bei Stoppuhr Betrieb übertragung per seriell zum PC
if(uc_dispmode==0)
{
itoa(uc_countstd,uc_stringbuffer);
if(uc_countstd<10)
{
strcpyf(uc_sendstring,"0");
strcat(uc_sendstring,uc_stringbuffer);
}
else
{
strcpy(uc_sendstring,uc_stringbuffer);
};
strcatf(uc_sendstring,";");
itoa(uc_countmin,uc_stringbuffer);
if(uc_countmin<10){strcatf(uc_sendstring,"0");};
strcat(uc_sendstring,uc_stringbuffer);
strcatf(uc_sendstring,";");
itoa(uc_countsek,uc_stringbuffer);
if(uc_countsek<10){strcatf(uc_sendstring,"0");};
strcat(uc_sendstring,uc_stringbuffer);
strcatf(uc_sendstring,";");
itoa(uc_countmsek,uc_stringbuffer);
if(uc_countmsek<10){strcatf(uc_sendstring,"0");};
strcat(uc_sendstring,uc_stringbuffer);
// Steuerzeichen anfügen
uc_stringlengh=strlen(uc_sendstring);
uc_sendstring[uc_stringlengh]=13; /* Carriage Return 13*/
uc_sendstring[uc_stringlengh+1]=10; /* Line Feed 10 */
uc_sendstring[uc_stringlengh+2]=0; /* Stringende anfügen */
uc_stringlengh=strlen(uc_sendstring);
for(uc_i=0;uc_i<uc_stringlengh;uc_i++)
{
putchar(uc_sendstring[uc_i]);
};
};
// Nur bei Stoppuhr Countdown betrieb übertragung per seriell zum PC
if(uc_dispmode==1)
{
itoa(uc_downstd,uc_stringbuffer);
if(uc_downstd<10)
{
strcpyf(uc_sendstring,"0");
strcat(uc_sendstring,uc_stringbuffer);
}
else
{
strcpy(uc_sendstring,uc_stringbuffer);
};
strcpy(uc_sendstring,uc_stringbuffer);
strcatf(uc_sendstring,";");
itoa(uc_downmin,uc_stringbuffer);
if(uc_downmin<10){strcatf(uc_sendstring,"0");};
strcat(uc_sendstring,uc_stringbuffer);
strcatf(uc_sendstring,";");
itoa(uc_downsek,uc_stringbuffer);
if(uc_downsek<10){strcatf(uc_sendstring,"0");};
strcat(uc_sendstring,uc_stringbuffer);
strcatf(uc_sendstring,";");
itoa(uc_downmsek,uc_stringbuffer);
if(uc_downmsek<10){strcatf(uc_sendstring,"0");};
strcat(uc_sendstring,uc_stringbuffer);
// Steuerzeichen anfügen
uc_stringlengh=strlen(uc_sendstring);
uc_sendstring[uc_stringlengh]=13; /* Carriage Return 13*/
uc_sendstring[uc_stringlengh+1]=10; /* Line Feed 10 */
uc_sendstring[uc_stringlengh+2]=0; /* Stringende anfügen */
uc_stringlengh=strlen(uc_sendstring);
for(uc_i=0;uc_i<uc_stringlengh;uc_i++)
{
putchar(uc_sendstring[uc_i]);
};
};
}
// External Interrupt 2 service routine
interrupt [EXT_INT2] void ext_int2_isr(void)
{
if((MCUCSR&0b01000000)>0)
{
MCUCSR&=0b10111111;
MeasureBit=MS_Count-old_ms_count; // Pausenzeitmessung
old_ms_count=MS_Count;
if(MeasureBit > 160) // Rücksetzen der Sekunden auf 0
{
TimeMilliseconds=0;
sek_count = 0;
};
}
else
{
MCUCSR|=0b01000000;
MeasureBit = MS_Count - old_ms_count; // Impulszeitmessung
if(MeasureBit < 50)
{
if(MeasureBit > HiLoTimeAverage + 3) DCF77Bit = 1;
else DCF77Bit = 0;
}
}
}
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
#asm("SEI"); /* Interrupts für Stoppuhr freigeben !*/
switch (uc_segmentcounter)
{
case 0:
PORTC=0;
PORTA.5=0;
delay_us(20);
PORTA.0=1;
PORTC=uc_segment[uc_segmentcounter];
if(PINB.2>0)
{
PORTC.7=1;
};
break;
case 1:
PORTC=0;
PORTA.0=0;
delay_us(20);
PORTA.1=1;
PORTC=uc_segment[uc_segmentcounter];
break;
case 2:
PORTC=0;
PORTA.1=0;
delay_us(20);
PORTA.2=1;
PORTC=uc_segment[uc_segmentcounter];
break;
case 3:
PORTC=0;
PORTA.2=0;
delay_us(20);
PORTA.3=1;
PORTC=uc_segment[uc_segmentcounter];
break;
case 4:
PORTC=0;
PORTA.3=0;
delay_us(20);
PORTA.4=1;
PORTC=uc_segment[uc_segmentcounter];
break;
case 5:
PORTC=0;
PORTA.4=0;
delay_us(20);
PORTA.5=1;
PORTC=uc_segment[uc_segmentcounter];
break;
};
uc_segmentcounter++;
if(uc_segmentcounter>5){uc_segmentcounter=0;};
}
// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
// Stopdelay aktiviert ?
if(ub_stopdelay>0)
{
ui_stopcounter++;
};
// Autoreset aktiv ?
if(ub_autoreset>0&&ui_autoresetcount>0)
{
ui_autoresetcount--;
if((ui_autoresetcount+1)==0){ui_autoresetcount=0;};
};
// Stoppuhr
if(ub_counting>0)
{
uc_countmsek++;
if (uc_countmsek>99)
{
uc_countmsek=0;
uc_countsek++;
if (uc_countsek>59)
{
uc_countsek=0;
uc_countmin++;
if(uc_countmin>59)
{
uc_countmin=0;
uc_countstd++;
if(uc_countstd>99)
{
uc_countstd=0;
};
};
};
};
// Countdown
if(uc_downmsek==0&&uc_downsek==0&&uc_downmin==0&&uc_downstd==0)
{
// Aktivierung des Autoreset
if(ui_autoreset>99&&ub_autoreset==0&&uc_dispmode==1)
{
ui_autoresetcount=ui_autoreset+100;
ub_autoreset=1;
};
}
else
{
uc_downmsek--;
if(uc_downmsek+1==0)
{
uc_downmsek=99;
uc_downsek--;
if(uc_downsek+1==0)
{
uc_downsek=59;
uc_downmin--;
if(uc_downmin+1==0)
{
uc_downmin=59;
uc_downstd--;
};
};
};
};
};
// static char startbit,parity;
MS_Count++;
TimeMilliseconds++;
if(TimeMilliseconds > 99) // one second
{
NewBit = 1;
TimeMilliseconds = 0;
if(++TimeSeconds >59)
{
TimeSeconds = 0;
if(++TimeMinutes > 59)
{
TimeMinutes = 0;
if(++TimeHours > 23)
{
TimeHours = 0;
}
}
}
switch (sek_count++)
{
case 20: /* startbit */
startbit = DCF77Bit;
if(startbit) cnt_okay++;
break;
/* decode numbers */
case 21: /* minute */
case 29: /* hour */
case 36: /* day */
parity = value = DCF77Bit;
break;
case 22: /* minute */
case 30: /* hour */
case 37: /* day */
case 43: /* weekday */
case 46: /* month */
case 51: /* year */
parity ^= DCF77Bit;
value += (DCF77Bit << 1);
break;
case 23: /* minute */
case 31: /* hour */
case 38: /* day */
case 44: /* weekday */
case 47: /* month */
case 52: /* year */
parity ^= DCF77Bit;
value += (DCF77Bit<<2);
break;
case 24: /* minute */
case 32: /* hour */
case 39: /* day */
case 48: /* month */
case 53: /* year */
parity ^= DCF77Bit;
value += (DCF77Bit << 3);
break;
case 25: /* minute */
case 33: /* hour */
case 40: /* day */
case 49: /* month */
case 54: /* year */
parity ^= DCF77Bit;
if(DCF77Bit == 1) value += 10;
break;
case 26: /* minute */
case 34: /* hour */
case 41: /* day */
case 55: /* year */
parity ^= DCF77Bit;
if(DCF77Bit == 1) value += 20;
break;
case 27: /* minute */
case 56: /* year */
parity ^= DCF77Bit;
if(DCF77Bit) value += 40;
break;
case 57: /* year */
parity ^= DCF77Bit;
if(DCF77Bit) value += 80;
break;
case 28: /* minute */
if(DCF77Bit == parity)
{
dcf77_minute = value;
cnt_okay++;
}
else dcf77_minute = 99;
break;
case 35: /* hour */
if(DCF77Bit == parity)
{
dcf77_hour = value;
cnt_okay++;
}
else dcf77_hour = 99;
break;
case 42: /* weekday */
dcf77_day = value;
parity ^= DCF77Bit;
value = DCF77Bit;
break;
case 45: /* month */
dcf77_wday = value;
parity ^= DCF77Bit;
value = DCF77Bit;
break;
case 50: /* year */
dcf77_month = value;
parity ^= DCF77Bit;
value = DCF77Bit;
break;
case 59:
sek_count = 0;
break;
case 58: /* Take all values */
dcf77_year = value;
if(DCF77Bit == parity) cnt_okay++;
startbit = 0;
break;
case 1: /* Take all values */
if(cnt_okay == 4)
{
TimeHours = dcf77_hour;
TimeMinutes = dcf77_minute;
DateMonth = dcf77_month;
DateDay = dcf77_day;
TimeSeconds = 1;
}
cnt_okay = 0;
break;
}
}
};
void show_display(void)
{
unsigned char uc_buffer,uc_buffer1;
switch (uc_dispmode)
{
case 0:
if(uc_countstd>0)
{
uc_segment[0]=uc_chartable[(uc_countsek%10)];
uc_segment[1]=uc_chartable[(uc_countsek/10)];
uc_segment[2]=uc_chartable[(uc_countmin%10)];
uc_segment[3]=uc_chartable[(uc_countmin/10)];
uc_buffer=uc_chartable[(uc_countstd%10)];
uc_buffer|=0b10000000;
uc_segment[4]=uc_buffer;
uc_segment[5]=uc_chartable[(uc_countstd/10)];
}
else
{
uc_segment[0]=uc_chartable[(uc_countmsek%10)];
uc_segment[1]=uc_chartable[(uc_countmsek/10)];
uc_segment[2]=uc_chartable[(uc_countsek%10)];
uc_segment[3]=uc_chartable[(uc_countsek/10)];
uc_segment[4]=uc_chartable[(uc_countmin%10)];
uc_segment[5]=uc_chartable[(uc_countmin/10)];
};
break;
case 1:
if(uc_downstd>0)
{
uc_segment[0]=uc_chartable[(uc_downsek%10)];
uc_segment[1]=uc_chartable[(uc_downsek/10)];
uc_segment[2]=uc_chartable[(uc_downmin%10)];
uc_segment[3]=uc_chartable[(uc_downmin/10)];
uc_buffer=uc_chartable[(uc_downstd%10)];
uc_buffer|=0b10000000;
uc_segment[4]=uc_buffer;
uc_segment[5]=uc_chartable[(uc_downstd/10)];
}
else
{
uc_segment[0]=uc_chartable[(uc_downmsek%10)];
uc_segment[1]=uc_chartable[(uc_downmsek/10)];
uc_segment[2]=uc_chartable[(uc_downsek%10)];
uc_segment[3]=uc_chartable[(uc_downsek/10)];
uc_segment[4]=uc_chartable[(uc_downmin%10)];
uc_segment[5]=uc_chartable[(uc_downmin/10)];
};
break;
// DCF 77 Funktion
case 2:
uc_segment[0]=uc_chartable[(TimeSeconds%10)];
uc_segment[1]=uc_chartable[(TimeSeconds/10)];
uc_segment[2]=uc_chartable[(TimeMinutes%10)];
uc_segment[3]=uc_chartable[(TimeMinutes/10)];
uc_buffer=uc_chartable[(TimeHours%10)];
uc_buffer|=0b10000000;
uc_segment[4]=uc_buffer;
uc_segment[5]=uc_chartable[(TimeHours/10)];
break;
// DCF 77 Countdown
case 3:
uc_buffer1=59-TimeSeconds;
uc_segment[0]=uc_chartable[(uc_buffer1%10)];
uc_segment[1]=uc_chartable[(uc_buffer1/10)];
uc_buffer1=59-TimeMinutes;
uc_segment[2]=uc_chartable[(uc_buffer1%10)];
uc_segment[3]=uc_chartable[(uc_buffer1/10)];
uc_buffer1=23-TimeHours;
uc_buffer=uc_chartable[(uc_buffer1%10)];
uc_buffer|=0b10000000;
uc_segment[4]=uc_buffer;
uc_segment[5]=uc_chartable[(uc_buffer1/10)];
};
};
unsigned char readtast(void)
{
unsigned char uc_buffer[2];
uc_buffer[0]=PIND&0b00011100; /* Port B einlesen und Tasten separieren */
delay_ms(10); /* 10ms warten */
uc_buffer[1]=PIND&0b00011100; /* Port B nochmals einlesen und Tasten separieren */
if(uc_buffer[0]==uc_buffer[1]) /* Sind beide Tasten gleich -> Werte zurückgeben */
{
return(uc_buffer[0]);
}
else
{
return (0); /* Verschieden = Fehler = 0 zurückgeben */
}
}
void setup(void)
{
unsigned int ui_buffer=0;
#asm("SEI")
uc_readtast=readtast();
uc_oldtast=uc_readtast;
while(uc_readtast==uc_oldtast)
{
uc_readtast=readtast(); // Warten auf loslassen der Taste
uc_segment[0]=uc_chartable[24];
uc_segment[1]=uc_chartable[24];
uc_segment[2]=uc_chartable[21]; /*P*/
uc_segment[3]=uc_chartable[24]; /* Leerzeichen */
uc_segment[4]=uc_chartable[14]; /*E*/
uc_segment[5]=uc_chartable[5]; /*S*/
};
delay_ms(100);
// Einstellung delay der Stoppfunktion
while(uc_readtast!=0b00001100)
{
uc_readtast=readtast();
if(uc_readtast!=uc_oldtast)
{
if (uc_readtast==0b00011000)
{
ui_stopdelay=ui_stopdelay+10;
if(ui_stopdelay>990){ui_stopdelay=0;};
}
if (uc_readtast==0b00010100)
{
ui_stopdelay=ui_stopdelay-10;
if(ui_stopdelay>990){ui_stopdelay=990;};
}
uc_oldtast=uc_readtast;
}
ui_buffer=ui_stopdelay/10;
uc_segment[0]=uc_chartable[(ui_buffer%10)];
uc_segment[1]=uc_chartable[(ui_buffer/10)];
uc_segment[1]|=0b10000000;
uc_segment[2]=uc_chartable[18]; /*L*/
uc_segment[3]=uc_chartable[14]; /*E*/
uc_segment[4]=uc_chartable[13]; /*d*/
uc_segment[5]=uc_chartable[5]; /*S*/
};
if (ui_stopdelay!=ee_stopdelay){ee_stopdelay=ui_stopdelay;};
while(uc_readtast==uc_oldtast)
{
uc_readtast=readtast(); // Warten auf loslassen der Taste
};
delay_ms(100);
// Einstellen des Autoreset wertes
while(uc_readtast!=0b00001100)
{
uc_readtast=readtast();
if(uc_readtast!=uc_oldtast)
{
if (uc_readtast==0b00011000)
{
ui_autoreset=ui_autoreset+100;
if(ui_autoreset>2000){ui_autoreset=2000;};
}
if (uc_readtast==0b00010100)
{
ui_autoreset=ui_autoreset-100;
if(ui_autoreset>32767){ui_autoreset=0;};
}
uc_oldtast=uc_readtast;
}
ui_buffer=ui_autoreset/100;
uc_segment[0]=uc_chartable[(ui_buffer%10)];
uc_segment[1]=uc_chartable[(ui_buffer/10)];
uc_segment[2]=uc_chartable[5]; /*S*/
uc_segment[3]=uc_chartable[14]; /*E*/
uc_segment[4]=uc_chartable[22]; /*r*/
uc_segment[5]=uc_chartable[10]; /*A*/
};
ui_autoreset=ui_buffer*100;
if (ui_autoreset!=ee_autoreset){ee_autoreset=ui_autoreset;};
while(uc_readtast==uc_oldtast)
{
uc_readtast=readtast(); // Warten auf loslassen der Taste
};
delay_ms(100);
// Einstellung Stunden Down Counter
while(uc_readtast!=0b00001100)
{
uc_readtast=readtast();
if(uc_readtast!=uc_oldtast)
{
if (uc_readtast==0b00011000)
{
uc_downstd++;
if(uc_downstd>99){uc_downstd=0;};
}
if (uc_readtast==0b00010100)
{
uc_downstd--;
if(uc_downstd+1==0){uc_downstd=99;};
}
uc_oldtast=uc_readtast;
}
uc_segment[0]=uc_chartable[(uc_downstd%10)];
uc_segment[1]=uc_chartable[(uc_downstd/10)];
uc_segment[2]=uc_chartable[22]; /*r*/
uc_segment[3]=uc_chartable[16]; /*H*/
uc_segment[4]=uc_chartable[24];
uc_segment[5]=uc_chartable[13]; /*d*/
};
if (uc_downstd!=ee_downstd){ee_downstd=uc_downstd;};
while(uc_readtast==uc_oldtast)
{
uc_readtast=readtast(); // Warten auf loslassen der Taste
};
delay_ms(100);
// Einstellung Minuten Down Counter
while(uc_readtast!=0b00001100)
{
uc_readtast=readtast();
if(uc_readtast!=uc_oldtast)
{
if (uc_readtast==0b00011000)
{
uc_downmin++;
if(uc_downmin>59){uc_downmin=0;};
}
if (uc_readtast==0b00010100)
{
uc_downmin--;
if(uc_downmin+1==0){uc_downstd=59;};
}
uc_oldtast=uc_readtast;
}
uc_segment[0]=uc_chartable[(uc_downmin%10)];
uc_segment[1]=uc_chartable[(uc_downmin/10)];
uc_segment[2]=uc_chartable[19]; /*n*/
uc_segment[3]=uc_chartable[19]; /*n*/
uc_segment[4]=uc_chartable[24]; /* */
uc_segment[5]=uc_chartable[13]; /*d*/
};
if (uc_downmin!=ee_downmin){ee_downmin=uc_downmin;};
while(uc_readtast==uc_oldtast)
{
uc_readtast=readtast(); // Warten auf loslassen der Taste
};
delay_ms(100);
// Einstellung Sekunden Down Counter
while(uc_readtast!=0b00001100)
{
uc_readtast=readtast();
if(uc_readtast!=uc_oldtast)
{
if (uc_readtast==0b00011000)
{
uc_downsek++;
if(uc_downsek>59){uc_downsek=0;};
}
if (uc_readtast==0b00010100)
{
uc_downsek--;
if(uc_downsek+1==0){uc_downsek=59;};
}
uc_oldtast=uc_readtast;
}
uc_segment[0]=uc_chartable[(uc_downsek%10)];
uc_segment[1]=uc_chartable[(uc_downsek/10)];
uc_segment[2]=uc_chartable[14]; /*E*/
uc_segment[3]=uc_chartable[5]; /*S*/
uc_segment[4]=uc_chartable[24];
uc_segment[5]=uc_chartable[13]; /*d*/
};
if (uc_downsek!=ee_downsek)
{
ee_downsek=uc_downsek;
ee_downmsek=uc_downmsek;
};
#asm("CLI")
GIFR|=0b11100000; /*Eventuell anstehende Interrupt Flags löschen */
}
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=T State6=T State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTA=0x00;
DDRA=0x3F;
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;
// Port C initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTC=0x00;
DDRC=0xFF;
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x03;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 1000,000 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
// CTC Mode: On
TCCR1A=0x00;
TCCR1B=0x0A;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x27;
OCR1AL=0x0F;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x11;
ui_autoreset=ee_autoreset;
ui_stopdelay=ee_stopdelay;
uc_downmsek=ee_downmsek;
uc_downsek=ee_downsek;
uc_downmin=ee_downmin;
uc_downstd=ee_downstd;
if(PIND.4==0)
{
setup();
};
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Falling Edge
// INT1: Off
// INT1 Mode: Falling Edge
// INT2: On
// INT2 Mode: Rising Edge
GICR|=0xE0;
MCUCR=0x02;
MCUCSR=0x40;
GIFR=0xE0;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: Off
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 38400
UCSRA=0x00;
UCSRB=0x48;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x0C;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
//****** Testroutines
/*uc_dispmode=0;*/
//****** End of Testroutines
// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/1024k
#pragma optsize-
WDTCR=0x1E;
WDTCR=0x0E;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
// Global enable interrupts
#asm("sei")
while (1)
{
#asm("wdr");
if (ui_stopcounter>=ui_stopdelay)
{
GIFR|=0b11000000; /* Anstehende Interrupts löschen */
GICR|=0b10000000; /* INT1 = Stopp die Stoppuhr freigeben */
ub_stopdelay=0; /* Stopcounter Flag zurücksetzen */
ui_stopcounter=0; /* Stop Delay Zähler wieder auf 0 zurücksetzen */
};
if(PINB.0>0)
{
uc_dispmode=0; /* Pin B.0 mit Pullup =1 -> Stoppuhrbetrieb */
}
else
{
uc_dispmode=2; /* Pin B.0 mit Schalter auf GND -> DCF 77 Betrieb */
};
if(PINB.1>0)
{
uc_dispmode++; /* Pin B.1 mit Pullup =1 -> Reversebetrieb der Uhren */
};
// Pin D.4 = 0 -> Reset der Stoppuhren
if(PIND.4>0)
{
// Tue nichs
}
else
{
ub_autoreset=0;
ui_autoresetcount=0;
ub_stopdelay=0;
ui_stopcounter=0;
ub_counting=0;
uc_countmsek=0;
uc_countsek=0;
uc_countmin=0;
uc_countstd=0;
uc_downmsek=ee_downmsek;
uc_downsek=ee_downsek;
uc_downmin=ee_downmin;
uc_downstd=ee_downstd;
GIFR|=0b11000000;
GICR&=0b00111111;
GICR|=0b01000000;
};
// Automatischer Reset der Stoppuhr
if(ui_autoresetcount<100&&ub_autoreset>0)
{
ub_autoreset=0;
ui_autoresetcount=0;
ub_stopdelay=0;
ui_stopcounter=0;
ub_counting=0;
uc_countmsek=0;
uc_countsek=0;
uc_countmin=0;
uc_countstd=0;
uc_downmsek=ee_downmsek;
uc_downsek=ee_downsek;
uc_downmin=ee_downmin;
uc_downstd=ee_downstd;
GIFR|=0b11000000;
GICR&=0b00111111;
GICR|=0b01000000;
};
show_display();
};
}
Eventuell kannst Du ja Teile davon gebrauchen...
Lesezeichen