#include<avr/io.h>
#include<util/delay.h>
typedef unsigned char byte;
unsigned char data;
volatile unsigned char num[10] = {0xfc, 0x60, 0xda, 0xf2, 0x66, 0xb6, 0x3e, 0xe4, 0xfe, 0xf6};
void control_dip(unsigned int select)
{
DDRF = 0xff;
if(select == 1)PORTF = (0 << 5)|(0 << 6)|(0 << 7);
else if(select == 2)PORTF = (1 << 5)|(0 << 6)|(0 << 7);
else if(select == 3)PORTF = (0 << 5)|(1 << 6)|(0 << 7);
else if(select == 4)PORTF = (1 << 5)|(1 << 6)|(0 << 7);
else if(select == 5)PORTF = (0 << 5)|(0 << 6)|(1 << 7);
else if(select == 6)PORTF = (1 << 5)|(0 << 6)|(1 << 7);
else if(select == 7)PORTF = (0 << 5)|(1 << 6)|(1 << 7);
else if(select == 8)PORTF = (1 << 5)|(1 << 6)|(1 << 7);
}
byte rtc_read( byte reg_data )
{
byte temp_return;
byte temp_ddra;
temp_ddra = DDRA;
DDRG = _BV(2)| _BV(1) | _BV(0);
DDRA = 0xff;
control_dip(4);
PORTG = _BV(2)| _BV(1) | _BV(0);
PORTA = reg_data;
PORTG = PORTG & ~_BV(2);
DDRA = 0x00;
PORTG = PORTG & ~_BV(1);
asm volatile("NOP");
asm volatile("NOP");
data = PINA & 0xff;
temp_return = PINA;
PORTG = _BV(2)| _BV(1) | _BV(0);
control_dip(1);
DDRA = temp_ddra;
return temp_return;
}
void rtc_write( byte reg_data, byte set_data )
{
byte temp_ddra;
temp_ddra = DDRA;
DDRG = _BV(2)| _BV(1) | _BV(0);
DDRA = 0xff;
control_dip(4);
PORTG = _BV(2)| _BV(1) | _BV(0);
PORTA = reg_data;
PORTG = PORTG & ~_BV(2);
PORTG = PORTG & ~_BV(0);
asm volatile("NOP");
asm volatile("NOP");
PORTA = set_data;
PORTG = _BV(2)| _BV(1) | _BV(0);
control_dip(1);
DDRA = temp_ddra;
}
void rtc_init ( void )
{
DDRD = 0xff;
PORTD = 0x00;
DDRA = 0xFF;
DDRC = 0xFF;
DDRB = 0x0F;
DDRG = _BV(2)| _BV(1) | _BV(0);
DDRA = 0xff;
rtc_write(0x0A, 0x20);
rtc_write(0x0B, 0x00);
}
int main( void )
{
int temp, fnd_rear, fnd_front;
rtc_init();
while(1)
{
PORTB = 0x04;
_delay_ms(1000);
PORTB = 0x00;
_delay_ms(1000);
control_dip(2); control_dip(3); control_dip(1);
_delay_us(200);
temp = rtc_read(0x00); //레지스터에서 초를 읽어옴
fnd_rear = 0x0f & temp;
fnd_front = 0x0f & (temp >> 4);
PORTC = 0x20; //초의 뒷자리
PORTA = num[fnd_rear];
control_dip(2); control_dip(3); control_dip(1);
_delay_us(200);
PORTC = 0x10; //초의 앞자리
PORTA = num[fnd_front];
control_dip(2); control_dip(3); control_dip(1);
_delay_us(200);
temp = rtc_read(0x02); //레지스터에서 분을 읽어옴
fnd_rear = 0x0f & temp;
fnd_front = 0x0f & (temp >> 4);
PORTC = 0x08;
PORTA = num[fnd_rear];
control_dip(2); control_dip(3); control_dip(1);
_delay_us(200);
PORTC = 0x04;
PORTA = num[fnd_front];
control_dip(2); control_dip(3); control_dip(1);
_delay_us(200);
temp = rtc_read(0x04); //시를 읽어옴
fnd_rear = 0x0f & temp;
fnd_front = 0x0f & (temp >> 4);
PORTC = 0x02;
PORTA = num[fnd_rear];
control_dip(2); control_dip(3); control_dip(1);
_delay_us(200);
PORTC = 0x01;
PORTA = num[fnd_front];
control_dip(2); control_dip(3); control_dip(1);
_delay_us(200);
if(rtc_read(0x04) < 0x12) //am, pm의 a,p 표시
{
PORTC = 0x40;
PORTA = 0xef;
control_dip(2); control_dip(3); control_dip(1);
_delay_us(200);
}
else
{
PORTC = 0x80;
PORTA = 0xcf;
control_dip(2); control_dip(3); control_dip(1);
_delay_us(200);
}
}
return 0;
}
이게 소스코드 전체인데 이대로 컴파일 해서 실행을 할 경우에 FND에 도트는 깜빡깜빡 거리지만
숫자는 뜨질 않습니다. B포트는 도트만 관여할텐데 왜 다른 숫자들까지 안나오는건지..
_delay_us(200); 이 부분을 _delay_us(2) 나 3으로 주면 숫자 구분이 잘 안되더라구요
앞의 답변을 다시 한번 보시는게 좋을 듯 합니다.~
delay(2)으로 했을 때 숫자 구분이 안되면 3,4,5,6,7,8 이렇게 하나씩 늘려 가면서 적당한 값을 찾아 보세요.
이것은 시스템마다 다 다르고 System Clock 에 따라 달라집니다.
". B포트는 도트만 관여할텐데 왜 다른 숫자들까지 안나오는건지"
=> 소스를 봐서는 PORTB는 FND 의 D0 ~ D6, 그리고 dot 까지 제어를 하는 신호입니다.
앞의 답변에서도 언급했지만 먼저 FND 에 출력이 제대로 되는지를 확인해야 합니다.
일단 RTC 기능을 모두 없애고, FND 에 숫자만 표시해 보세요.
그 다음에 RTC 값을 출력해 보시고요.
하나씩 확인해 보시고 그대로 안되시면 다시 질문 올려 주세요.~~
감사합니다.