/***************************************************** This program was produced by the CodeWizardAVR V1.25.7a Standard Automatic Program Generator © Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com Project : Version : Date : 8/11/2007 Author : Theodore Johnson Company : 225 e. 36th st 17B NY Comments: Chip type : ATmega48 Clock frequency : 10.000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 128 *****************************************************/ #include // I2C Bus functions #asm .equ __i2c_port=0x0B ;PORTD .equ __sda_bit=3 .equ __scl_bit=2 #endasm #include #include #include #define LED1 PORTB.1 #define LED2 PORTB.2 #define XLAT5490 PORTD.5 #define SCK5490 PORTD.6 #define SIN5490 PORTD.7 #define VPRG5490 PORTB.0 #define BLANK5490 PORTD.4 #define SIN6810 PORTB.5 #define CLK6810 PORTB.4 #define STROBE6810 PORTB.3 #define ENCA PINC.5 #define ENCB PINC.4 #define BTN PINC.3 #define SW1 PINC.2 #define SW2 PINC.1 #define SW3 PINC.0 // ------------------------------------------------------------ // DS3231 RTC functions #define DS3231_ADDR 0xD0 void read_time(unsigned char *h, unsigned char *m, unsigned char *s){ unsigned char c1, c2, c3; i2c_start(); i2c_write(DS3231_ADDR ); i2c_write(0); i2c_stop(); i2c_start(); i2c_write(DS3231_ADDR | 1); c1=i2c_read(1); c2=i2c_read(1); c3=i2c_read(0); i2c_stop(); *s=10*((c1&0x70)>>4) + (c1 & 0x0f); *m=10*((c2&0x70)>>4) + (c2 & 0x0f); *h=10*((c3&0x30)>>4) + (c3 & 0x0f); } void write_time(unsigned char h, unsigned char m, unsigned char s){ unsigned char c1,c2,c3; c1=(s%10)+((s/10)<<4); c2=(m%10)+((m/10)<<4); c3=(h%10)+((h/10)<<4); i2c_start(); i2c_write(DS3231_ADDR ); i2c_write(0); i2c_write(c1); i2c_write(c2); i2c_write(c3); i2c_stop(); } //////////////////////////////////////////////////// // Timer 0 output compare A interrupt service routine interrupt [TIM0_COMPA] void timer0_compa_isr(void){ BLANK5490 = 1; BLANK5490 = 0; } /////////////////////////////////////////////////// // TI TLC5490 drivers void init_5490(){ unsigned char i; XLAT5490 = 0; SCK5490 = 0; VPRG5490 = 1; SIN5490 = 1; for(i=0;i<96;i++){ SCK5490 = 1; SCK5490 = 0; } XLAT5490 = 1; XLAT5490 = 0; VPRG5490 = 0; SIN5490 = 0; for(i=0;i<192;i++){ SCK5490 = 1; SCK5490 = 0; } XLAT5490 = 1; XLAT5490 = 0; // Extra clock pulse after setting Dot Correction SCK5490 = 1; SCK5490 = 0; } unsigned int led_lvl[18] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; void load_5490(){ unsigned char i, j; unsigned int b; VPRG5490 = 0; for(i=0;i<16;i++){ j=15-i; for(b=0x800;b>0;b=b>>1){ if((led_lvl[j] & b) > 0) SIN5490 = 1; else SIN5490 = 0; SCK5490 = 1; SCK5490 = 0; } } XLAT5490 = 1; XLAT5490 = 0; } void set_color(unsigned int lvl, unsigned char phase){ unsigned char i; unsigned int r_lvl, b_lvl, g_lvl; switch(phase){ case 0: r_lvl = 4095 - lvl; g_lvl = lvl; b_lvl = 0; break; case 1: g_lvl = 4095 - lvl; b_lvl = lvl; r_lvl = 0; break; case 2: b_lvl = 4095 - lvl; r_lvl = lvl; g_lvl = 0; break; } for(i=0;i<16;i+=3){ led_lvl[i] = r_lvl; led_lvl[i+1] = b_lvl; led_lvl[i+2] = g_lvl; } load_5490(); } /////////////////////////////// unsigned char led_st[5] = {0,0,0,0,0}; void init6810(){ STROBE6810 = 0; CLK6810 = 0; } void load6810(){ unsigned char i,b; CLK6810 = 0; for(i=0;i<5;i++){ for(b=1;b!=0;b=b<<1){ if(b&led_st[i]) SIN6810=1; else SIN6810=0; CLK6810=1; CLK6810=0; } } STROBE6810=1; STROBE6810=0; } void set_disp_bit(unsigned char d){ unsigned char b,p; p=d >> 3; b = d & 7; led_st[p] = led_st[p] | (1 << b); } void set_hm(unsigned char h, unsigned char m){ unsigned char i; for(i=0;i<5;i++) led_st[i] = 0; if(h>=12) h-=12; set_disp_bit(11-h); set_disp_bit(12+(5-(m/10))); set_disp_bit(18+(9-(m%10))); } void set_face(unsigned char i){ if(i>1) i++; i++; i+=28; set_disp_bit(i); } //////////////////////////////////////////// // Utility unsigned char button_pressed(unsigned char b, unsigned char *s){ unsigned char retval; if(b == 1 && *s == 0) retval = 1; else retval = 0; *s = ((*s) << 1) + b; return(retval); } #define NIL 0 #define ZERO 1 #define PLUS 2 #define MINUS 3 flash char enc_val[16] = { ZERO, MINUS, PLUS, NIL, PLUS, ZERO, NIL, MINUS, MINUS, NIL, ZERO, PLUS, NIL, PLUS, MINUS, ZERO }; char enc_state = 0; void get_enc_state(){ enc_state = ENCA + (ENCB << 1); } int get_enc_update(){ char old_state, trans_state; old_state = enc_state; get_enc_state(); trans_state = (old_state << 2) + enc_state; switch(enc_val[trans_state]){ case PLUS: return 1; case MINUS: return -1; default: return 0; } } eeprom unsigned int seed = 1; void main(void){ unsigned int sd; unsigned char btn=0; unsigned char i,b=1,p=0,state=0,cnt,phase; unsigned int r_lvl,b_lvl,g_lvl,lvl; int d; unsigned char h,m,s,oh,om,os; unsigned long int tick = 0; // Crystal Oscillator division factor: 1 #pragma optsize- CLKPR=0x80; CLKPR=0x00; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif // Input/Output Ports initialization // Port B 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 PORTB=0x00; DDRB=0x3F; // Port C initialization // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x00; // Port D initialization // Func7=Out Func6=Out Func5=Out Func4=Out Func3=In Func2=Out Func1=In Func0=In // State7=0 State6=0 State5=0 State4=0 State3=T State2=0 State1=T State0=T PORTD=0x00; DDRD=0xF4; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 39.063 kHz // Mode: CTC top=OCR0A // OC0A output: Disconnected // OC0B output: Disconnected TCCR0A=0x02; TCCR0B=0x04; TCNT0=0x00; OCR0A=0x10; OCR0B=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // 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: Off // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer 2 Stopped // Mode: Normal top=FFh // OC2A output: Disconnected // OC2B output: Disconnected ASSR=0x00; TCCR2A=0x00; TCCR2B=0x00; TCNT2=0x00; OCR2A=0x00; OCR2B=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off // Interrupt on any change on pins PCINT0-7: Off // Interrupt on any change on pins PCINT8-14: Off // Interrupt on any change on pins PCINT16-23: Off EICRA=0x00; EIMSK=0x00; PCICR=0x00; // Timer/Counter 0 Interrupt(s) initialization TIMSK0=0x02; // Timer/Counter 1 Interrupt(s) initialization TIMSK1=0x00; // Timer/Counter 2 Interrupt(s) initialization TIMSK2=0x00; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; ADCSRB=0x00; // I2C Bus initialization i2c_init(); // Global enable interrupts #asm("sei") init_5490(); init6810(); load6810(); get_enc_state(); // Randomize initial settings sd=seed; if(!sd) sd=1; srand(sd); sd++; if(sd>32760) sd=1; seed=sd; tick = rand(); lvl = (rand() >> 2) & 0x0fff; phase = rand() % 3; set_color(lvl,phase); // for(i=0;i<16;i++) // led_lvl[i] = 2048; load_5490(); r_lvl=2048; b_lvl=2048; g_lvl=2048; read_time(&h,&m,&s); if(h>23) h=0; if(m>59) m=0; if(s>59) s=0; write_time(h,m,s); set_hm(h,m); load6810(); state = 0; LED1=0; LED2=0; cnt = 0; while(1){ cnt++; if(cnt>50){ read_time(&h,&m,&s); cnt=0; // LED1 = s&1; } if(s != os){ lvl++; if(lvl > 4095){ lvl = 0; phase++; if(phase>2) phase = 0; } set_color(lvl,phase); } if(om != m || oh != h){ tick++; set_hm(h,m); set_face(tick%10); load6810(); } oh=h; om=m; os=s; if(button_pressed(BTN,&btn)){ state++; if(state>2) state=0; LED1 = state & 1; LED2 = state & 2; } d += get_enc_update(); if((d>1 || d<-1)){ if(state){ switch(state){ case 1: if(d>0){ m++; if(m>=60) m=0; }else{ if(m==0) m=60; m--; } break; case 2: if(d>0){ h++; if(h>=12) h=0; }else{ if(h==0) h=12; h--; } break; } write_time(h,m,s); oh=h; om=m; os=s; set_hm(h,m); set_face(tick); /* i=(h+m)%10; if(i>2) i++; if(i>3) i++; i+=28; set_disp_bit(i); */ load6810(); } d=0; } } /* //--------------------------------- s = 0; set_hm(state,s); load6810(); while(1){ if(button_pressed(BTN,&btn)){ state++; if(state>1) state = 0; } d += get_enc_update(); if((d>1 || d<-1)){ if(state){ if(d>0){ s++; if(s>11) s=0; }else{ if(s==0) s=12; s--; } set_hm(state,s); set_disp_bit(s+28); load6810(); }else{ if(d>0){ s++; if(s>9) s=0; }else{ if(s==0) s=10; s--; } set_hm(state,s); set_face(s); load6810(); } d=0; } delay_ms(1); } //--------------------------------- state = 0; while(1){ if(button_pressed(BTN,&btn)){ state++; if(state>3) state=0; LED1 = state & 1; LED2 = state & 2; } d += get_enc_update(); if(d>1 || d<-1){ switch(state){ case 0: led_st[p] = 0; if(d>0){ b=b<<1; if(!b){ b=1; p++; if(p>4) p=0; } }else{ b=b>>1; if(!b){ b=128; if(p==0) p=4; p--; } } led_st[p]=b; LED1= (b&0xAA)>0; LED2= p&1; load6810(); break; case 1: if(d>0){ r_lvl += 256; if(r_lvl >= 4096) r_lvl = 0; }else{ if(r_lvl == 0) r_lvl = 4096; r_lvl -= 256; } for(i=0;i<16;i+=3) led_lvl[i] = r_lvl; load_5490(); break; case 2: if(d>0){ g_lvl += 256; if(g_lvl >= 4096) g_lvl = 0; }else{ if(g_lvl == 0) g_lvl = 4096; g_lvl -= 256; } for(i=2;i<16;i+=3) led_lvl[i] = g_lvl; load_5490(); break; case 3: if(d>0){ b_lvl += 256; if(b_lvl >= 4096) b_lvl = 0; }else{ if(b_lvl == 0) b_lvl = 4096; b_lvl -= 256; } for(i=1;i<16;i+=3) led_lvl[i] = b_lvl; load_5490(); break; } d=0; } delay_ms(1); } while(1){ d += get_enc_update(); if(d>1 || d<-1){ led_st[p] = 0; if(d>0){ b=b<<1; if(!b){ b=1; p++; if(p>4) p=0; } }else{ b=b>>1; if(!b){ b=128; if(p==0) p=5; p--; } } d=0; led_st[p]=b; LED1= (b&0xAA)>0; LED2= p&1; load6810(); } delay_ms(1); } while (1){ if(button_pressed(BTN,&btn)){ led_st[p] = 0; b=b<<1; if(!b){ b=1; p++; if(p>4) p=0; } led_st[p]=b; LED1= (b&0xAA)>0; LED2= p&1; load6810(); } }; */ }