Witam. Potrzebny mi jest zegar wyświetlający równocześnie czas lokalny i czas Greenwich. W tym celu próbuje napisać odpowiedni program ale mam problem z multipleksowaniem dwu wyświetlaczy LED każdy po sześć cyfr. Podstawą czasu jest PCF8583 a że mam akurat atmegę32 więc ją wykorzystam. Od razu mówię że orłem w programowaniu nie jestem i bardzo możliwe że źle się do tego zabrałem. Poszukiwania podobnego programu który mógłby posłużyć za pomoc dydaktyczna to istna mordęga bo w C znaleźć cokolwiek nie jest łatwo a jak jest to kod jest wyższych lotów w 70% dla mnie nie zrozumiały z powodu zastosowania funkcji których nie rozumie. Segmenty podłączone do portu A, pierwsze 6-cyfr podłączyłem do portu B a drugie 6-cyfr do C, klawisze na porcie D. Wkleję cały kod aby było to w pełni dla was czytelne;
#include <stdint.h>
#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>
//********** funcje obsługi TWI dla PCF
#define zegar 0xA2 // A0 PCF do plusa
#define ACK 1
#define NOACK 0
static void TWI_start(void)
{
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
}
static void TWI_stop(void)
{
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
}
void TWI_write(unsigned char scalak,unsigned char adres_rejestru,unsigned char liczba)
{
TWCR =(1 << TWINT) | (1 << TWSTA) | ( 1 << TWEN );
while(!(TWCR & (1 << TWINT)));
TWDR =scalak;
TWCR =(1 << TWINT) | (1 << TWEN);
while(!(TWCR & (1 << TWINT)));
TWDR =adres_rejestru;
TWCR =(1 << TWINT) | (1 << TWEN);
while(!(TWCR & (1 << TWINT)));
TWDR =liczba;
TWCR =(1 << TWINT) | (1 << TWEN);
while(!(TWCR & (1 << TWINT)));
TWCR =(1 << TWINT) | (1<<TWEN) | (1<<TWSTO);
}
unsigned char TWI_read(unsigned char scalak,unsigned char adres_rejestru)
{
unsigned char odczyt;
TWCR =(1 << TWINT) | (1 << TWSTA) | ( 1 << TWEN );
while(!(TWCR & (1 << TWINT)));
TWDR =scalak;
TWCR =(1 << TWINT) | (1 << TWEN);
while(!(TWCR & (1 << TWINT)));
TWDR =adres_rejestru;
TWCR =(1 << TWINT) | (1 << TWEN);
while(!(TWCR & (1 << TWINT)));
TWCR =(1 << TWINT) | (1 << TWSTA) | ( 1 << TWEN );
while(!(TWCR & (1 << TWINT)));
TWDR =scalak | 0x01;
TWCR =(1 << TWINT) | (1 << TWEN);
while(!(TWCR & (1 << TWINT)));
TWCR =(1 << TWINT) | (1 << TWEN);
while(!(TWCR & (1 << TWINT)));
odczyt =TWDR;
TWCR =(1 << TWINT) | (1<<TWEN) | (1<<TWSTO);
return(odczyt);
}
//********** funkcje konwersji
char dec_na_bcd(char num) {return ((num/10 * 16) + (num % 10));} //set = dec_na_bcd(set);
char bcd_na_dec(char num) {return ((num/16 * 10) + (num % 16));} //set = bcd_na_dec(set);
//********** definicje zmiennych dla zegara
unsigned char PCF,PCF_dzien,dec_dzien,m,d,y;
unsigned char buffer_t[16];
unsigned char PCF_dmc,PCF_jmc,PCF_ddni,PCF_jdni; //odczyt daty
unsigned char PCF_dg,PCF_jg,PCF_dm,PCF_jm,PCF_ds,PCF_js,PCF_sds,PCF_sjs;//odczyt czasu
unsigned char dec_dg,dec_jg,dec_dm,dec_jm,dec_ds,dec_js; //czas bierzący po konwersji na dec
//********** definicje zmiennych dla menu
unsigned char led_display;
unsigned char set_g1,set_m1,set_g2,set_m2,set_g3,set_m3,set_g4,set_m4;
//********** define segmentów wyświetlacza
unsigned char nr_wysw;
const unsigned char cyfra[10]={
0x3F,/*cyfra 0 A */
0x06,/*cyfra 1 --- */
0x5B,/*cyfra 2 | | */
0x4F,/*cyfra 3 F | | B */
0x66,/*cyfra 4 | | */
0x6D,/*cyfra 5 G --- */
0x7D,/*cyfra 6 | | */
0x07,/*cyfra 7 E | | C */
0x7F,/*cyfra 8 | | */
0x6F,/*cyfra 9 --- */
0x80 /*kropka D # H */
};
//***** MAIN
int main()
{
DDRA=0xFF; //wyjścia - segmenty wyświetlaczy wyś_1 oraz wyś_2
DDRB=0xFF; //wyjścia - cyfry wyświetlacza czasu lokalnego
DDRC=0xFC; //wyjścia - cyfry wyświetlacza daty oraz wejścia - SCL SDA układu PCF8583
PORTC=0x03; //pull-up - dla SCL SDA INT1 układu PCF8583
DDRD=0x00; //wejścia - klawiatura
PORTD=0xF8; //pull-up - klawiatura
//----- TWI init
TWSR=0x00;
TWBR=0x48; //preskaler I2C - ((F_CPU / 100000UL - 16) - inicjacja przerwań
sei();
//-----pętla główna progranu
while(1)
{ //odczyt czasu i daty
//-----
PCF=TWI_read(zegar,0x06); PCF_dmc=PCF >>4; PCF_jmc=PCF & 0x0F;
PCF=TWI_read(zegar,0x05); PCF_ddni=PCF >>4; PCF_jdni=PCF & 0x0F;
PCF=TWI_read(zegar,0x04); PCF_dg=PCF >>4; PCF_jg=PCF & 0x0F;
PCF=TWI_read(zegar,0x03); PCF_dm=PCF >>4; PCF_jm=PCF & 0x0F;
PCF=TWI_read(zegar,0x02); PCF_ds=PCF >>4; PCF_js=PCF & 0x0F;
//-----
dec_dg=bcd_na_dec(PCF_dg); dec_jg=bcd_na_dec(PCF_jg);//konwersja na dec godziny
dec_dm=bcd_na_dec(PCF_dm); dec_jm=bcd_na_dec(PCF_jm);//konwersja na dec minuty
for( nr_wysw=0; nr_wysw<12; nr_wysw++)
{
switch(nr_wysw)
{
case 0://wyśw_1_dziesiątki godzin
PORTB &=~ _BV(1);
cyfra[dec_dg];
PORTB |= _BV(1);
break;
case 1://wyśw_1_jednostki godzin
PORTB &=~ _BV(2);
cyfra[dec_jg];
PORTB |= _BV(2);
break;
case 2://wyśw_1_dziesiątki minut
PORTB &=~ _BV(3);
cyfra[dec_dm];
PORTB |= _BV(3);
break;
case 3://wyśw_1_jednostk minut
PORTB &=~ _BV(4);
cyfra[dec_jm];
PORTB |= _BV(4);
break;
case 5://wyśw_1_dziesiątki sekund
PORTB &=~ _BV(5);
cyfra[dec_ds];
PORTB |= _BV(5);
break;
case 6://wyśw_1_jednostk sekund
PORTB &=~ _BV(6);
cyfra[dec_js];
PORTB |= _BV(6);
break;
//----------------czas 2 GMT
case 7://wyśw_2_dziesiątki godzin
PORTC &=~ _BV(1);
cyfra[dec_dg];
PORTC |= _BV(1);
break;
case 8://wyśw_2_jednostki godzin
PORTC &=~ _BV(2);
cyfra[dec_jg];
PORTC |= _BV(2);
break;
case 9://wyśw_2_dziesiątki minut
PORTC &=~ _BV(3);
cyfra[dec_dm];
PORTC |= _BV(3);
break;
case 10://wyśw_2_jednostk minut
PORTC &=~ _BV(4);
cyfra[dec_jm];
PORTC |= _BV(4);
break;
case 11://wyśw_2_dziesiątki sekund
PORTC &=~ _BV(5);
cyfra[dec_ds];
PORTC |= _BV(5);
break;
case 12://wyśw_2_jednostk sekund
PORTC &=~ _BV(6);
cyfra[dec_js];
PORTC |= _BV(6);
break;
default:
break;
}
}
}
return;
}
//********** END MAIN **********