#include <avr/io.h>
#define F_CPU 8000000
#define CYCLES_PER_US ((F_CPU+500000)/1000000)
void delay(unsigned int us)
{
unsigned int delay_loops;
register unsigned int i;
delay_loops = (us+3)/5*CYCLES_PER_US;
for (i=0; i < delay_loops; i++) {};
}
void delayms(unsigned int ms)
{
unsigned int i;
for (i=0;i<ms;i++)
{
delay(999);
asm volatile (
"WDR"::);
}
}
#define SEG_D 2
#define SEG_KR 8
#define SEG_P_D 4
#define SEG_SR 32
#define SEG_L_D 1
#define SEG_L_G 128
#define SEG_P_G 16
#define SEG_G 64
unsigned int l[3];
unsigned int km=0,impkm=0,kll=0;
unsigned char dlim=0,blok=0,t3=0;
unsigned char cyfra(unsigned char wej){
unsigned char wyj=0;
switch(wej){
case 0: wyj = SEG_G + SEG_L_G + SEG_P_G + SEG_L_D + SEG_P_D + SEG_D; break;
case 1: wyj = SEG_P_G + SEG_P_D; break;
case 2: wyj = SEG_G + SEG_P_G + SEG_SR + SEG_L_D + SEG_D; break;
case 3: wyj = SEG_G + SEG_P_G + SEG_SR + SEG_P_D + SEG_D; break;
case 4: wyj = SEG_P_G + SEG_L_G + SEG_SR + SEG_P_D; break;
case 5: wyj = SEG_G + SEG_P_D + SEG_SR + SEG_L_G + SEG_D; break;
case 6: wyj = SEG_G + SEG_L_G + SEG_SR + SEG_L_D + SEG_P_D + SEG_D; break;
case 7: wyj = SEG_G + SEG_P_G + SEG_P_D; break;
case 8: wyj = SEG_G + SEG_L_G + SEG_P_G + SEG_L_D + SEG_P_D + SEG_D + SEG_SR; break;
case 9: wyj = SEG_G + SEG_P_G + SEG_L_G + SEG_P_D + SEG_D + SEG_SR; break;
case 10: wyj += SEG_KR; break;
case 12: wyj = SEG_D + SEG_L_D + SEG_L_G + SEG_SR; break;
case 13: wyj = SEG_D + SEG_P_D + SEG_L_D + SEG_SR + SEG_P_G; break;
case 14: wyj = SEG_L_D + SEG_L_G + SEG_SR + SEG_G + SEG_P_G; break;
}
return(~wyj);
}
unsigned int i;
unsigned char alg=0,tryb=0;
void wyswietl(unsigned char dl){
PORTB |= 2;
PORTD = cyfra(l[0]);
for(i=0;i<dl;i++) asm volatile ( "NOP" );
if(blok>0){
PORTD = ~SEG_KR;
for(i=0;i<dl;i++) asm volatile ( "NOP" );
}
PORTD = 0xff;
PORTB &= ~2;
PORTB |= 1;
PORTD = cyfra(l[1]);
for(i=0;i<dl;i++) asm volatile ( "NOP" );
PORTD = 0xff;
PORTB &= ~1;
PORTB |= 4;
PORTD = cyfra(l[2]);
for(i=0;i<dl;i++) asm volatile ( "NOP" );
if((l[2]<12)&&((tryb==3&&t3==0)||tryb==1)){
PORTD = ~SEG_KR;
for(i=0;i<dl;i++) asm volatile ( "NOP" );
}
PORTD = 0xff;
PORTB &= ~4;
}
unsigned int czas=1000,licznik_gl=0;
unsigned char nw=1;
unsigned int przyc=0;
signed char kmdp=-1;
unsigned char sprawdz_przyc(void){
unsigned char wyj=0;
nw=1;
if(~(PINC)%2){
if(++przyc==550) wyj=1; else nw=0;
} else if(~(PINC>>1)%2){
if(++przyc==550) wyj=2; else nw=0;
} else if(~(PINC>>2)%2){
if(++przyc==550) wyj=4; else nw=0;
}
if(nw==1) przyc=0;
return(wyj);
}
unsigned char losuj(void){
unsigned char przyc_wart, wyj=0;
for(;;){
wyswietl(23);
przyc_wart = sprawdz_przyc();
switch(przyc_wart){
case 2: if(wyj<9)wyj++; else wyj=0; break;
case 1: return wyj; break;
}
l[0]=(wyj)%10;
l[1]=100;
l[2]=14;
}
}
/* unsigned char wyj=0;
for(;;){
if(++i>1000){
if(++wyj>9)wyj=0;
i=0;
}
PORTB |= 2;
switch(wyj){
case 2: PORTD = ~SEG_G; break;
case 3: PORTD = ~(SEG_G + SEG_P_G); break;
case 4: PORTD = ~(SEG_P_G + SEG_P_D); break;
case 5: PORTD = ~(SEG_P_D + SEG_D); break;
case 6: PORTD = ~SEG_D;
}
delay(3);
PORTD = 0xff;
PORTB &= ~2;
PORTB |= 1;
switch(wyj){
case 1: case 2: PORTD = ~(SEG_G); break;
case 6: case 7: PORTD = ~SEG_D;
}
delay(3);
PORTD = 0xff;
PORTB &= ~1;
PORTB |= 4;
switch(wyj){
case 0: PORTD = ~(SEG_L_G + SEG_G); break;
case 1: PORTD = ~SEG_G; break;
case 7: PORTD = ~SEG_D; break;
case 8: PORTD = ~(SEG_D + SEG_L_D); break;
case 9: PORTD = ~(SEG_L_D + SEG_L_G);
}
delay(3);
PORTD = 0xff;
PORTB &= ~4;
if(PINC%2==0) return(wyj);
}*/
void ust_km(void){
unsigned char przyc_wart;
for(;;){
wyswietl(23);
przyc_wart = sprawdz_przyc();
switch(przyc_wart){
case 4: return; break;
case 1: if(kmdp<99)kmdp++; break;
case 2: if(kmdp>-1)kmdp--; break;
}
l[0]=(kmdp+1)%10;
l[1]=((kmdp+1)/10)%10;
l[2]=13;
}
}
void konf(void){
unsigned char przyc_wart;
for(;;){
wyswietl(23);
przyc_wart = sprawdz_przyc();
switch(przyc_wart){
case 4: ust_km(); alg = losuj(); czas=75; return; break;
case 1: if(tryb<1)tryb++; break;
case 2: if(tryb>0)tryb--; break;
}
l[0]=tryb;
l[1]=11;
l[2]=12;
}
}
unsigned char tp=0;
void ps(void){
if(tryb==0) {
czas=1000;
} else if(tryb==1||(tryb==3&&t3==0)) {/* miasto */
if(czas>155) czas=93;
if(blok==0){
if((impkm*(kll+3)*(alg/2))%9==2) blok=1;
if(((impkm/2)*(kll+1)*alg*5)%7==0) {
if((czas+3)>116){
czas=116;
} else {
czas +=3;
}
} else if(--czas<28)czas=28;
if(czas==28){
if(impkm%24==0)czas=25;
if(impkm%24==10)czas=27;
if(dlim++>3){ czas=30; dlim=0; }
} else dlim = 0;
} else {
if(++blok==(alg*5)%20)blok=0;
if(((impkm/2)*(kll+1)*alg*5)%7==0) {
if(--czas<24)czas=26;
} else if(((impkm/2)*(kll+1)*alg*5)%7==3) if(++czas>47)czas=45;
}
}
}
int main(void){
DDRD = 0xff;
DDRB = 0xff;
PORTD = 0xff;
PORTB = 0x00;
DDRC = 0x00;
PORTC = 0xff;
register unsigned char przyc_wart = 0;
register unsigned char przyc=0,nw=1;
for(;;){
przyc_wart = 0;
if(++licznik_gl>(2*czas)/*2*/){
licznik_gl=0;
PORTB &= ~8;
if(++impkm>8380){
impkm=0;
if(++km>99)km=0;
if(kll%2==0) {
if(t3==0)t3=1;
} else t3=0;
if(kmdp!=-1) if(--kmdp==-1) tryb=0;
}
if((impkm%530)==0)ps();
if(impkm%262==0&&czas>20)ps();
if(impkm%130==0&&czas>40)ps();
if(czas<8)czas=15;
if(impkm%131==0) if(++kll>80)kll=0;
}
if(licznik_gl==czas/*1*/) PORTB |= 8;
////////// PRZYC
nw=1;
przyc_wart = 0;
if(~(PINC)%2){
if(++przyc==220) przyc_wart=1; else nw=0;
} else if(~(PINC>>1)%2){
if(++przyc==220) przyc_wart=2; else nw=0;
} else if(~(PINC>>2)%2){
if(++przyc==220) przyc_wart=4; else nw=0;
}
if(nw==1) przyc=0;
////////////// /przyc
switch(przyc_wart){
case 1: if(czas<70)czas++; break;
case 2: if(czas>15)czas--; break;
case 4: konf();
}
l[0] = km%10;
l[1] = (km/10)%10;
l[2] = 11;
if(tryb!=0)wyswietl(5); else wyswietl(23);
}
}