clcd 시계
#include <mega128.h>
#include <delay.h>
#define ENABLE PORTA.2=1
#define DISABLE PORTA.2=0
#define LINE1 0x80
#define LINE2 0xc0
void rg_set(void)
{
DDRC=0xff;
DDRA=0xff;
}
void lcd_cmd(unsigned char cmd)
{
PORTA.0=0;
PORTA.1=0;
PORTC=cmd;
ENABLE;
DISABLE;
delay_ms(2);
}
void lcd_clr(void)
{
delay_ms(30);
lcd_cmd(0x30);
delay_ms(5);
lcd_cmd(0x30);
delay_us(100);
lcd_cmd(0x30);
lcd_cmd(0x38);
// lcd_cmd(0x01);
lcd_cmd(0x0c);
lcd_cmd(0x06);
}
void lcd_write(unsigned char data)
{
PORTC=data;
PORTA.0=1;
ENABLE;
DISABLE;
delay_us(40);
}
void lcd_str(unsigned char flash *str)
{
int i=0;
while(str[i])
{
lcd_write(str[i]);
i++;
}
}
////////////////////////////////////////////////
/* RTC */
///////////////////////////////////////////////
typedef unsigned char u08; // 0 ~ 255 1바이트
typedef unsigned short u16; // 0 ~ 65535 2바이트
void RTC_Write (u08 addr, u08 data);
u08 RTC_Read (u08 addr);
void RTC_Set_Time (void);
void RTC_Get_Time (void);
u08 hour, hour2; // 몇 시인지 저장할 변수
u08 min, min2; // 몇 분인지 저장할 변수
u08 sec, sec2; // 몇 초인지 저장할 변수
u08 RTC_Get_Hour (void)
{
return hour;
}
u08 RTC_Get_Hour2 (void)
{
return hour2;
}
u08 RTC_Get_Min (void)
{
return min;
}
u08 RTC_Get_Min2 (void)
{
return min2;
}
u08 RTC_Get_Sec (void)
{
return sec;
}
u08 RTC_Get_Sec2 (void)
{
return sec2;
}
///////////////////////////////////////////////////////////////////////////
///////// RTC시작 //////////
///////////////////////////////////////////////////////////////////////////
void RTC_Write (u08 addr, u08 data)
{
DDRB = 0xff; // 포트B를 출력으로 설정
PORTA.3=1; // RD = high
PORTA.4=1; // WR = high
PORTA.6=0; // CS = low
PORTA.5=1; // ALE = high
PORTB = addr; // RTC에 Address 전송
delay_us(2);
PORTA.5=0; // ALE = low
PORTA.4=0; // WR = low
PORTB = data; // RTC에 데이터 전송
delay_us(2);
PORTA.4=1; // WR = high
PORTA.5=1; // ALE = high
PORTA.6=1; // CS = high
}
u08 RTC_Read (u08 addr)
{
u08 data;
DDRB = 0xff; // 포트B를 출력으로 설정
PORTA.3=1; // RD = high
PORTA.4=1; // WR = high
PORTA.6=0; // CS = low
delay_us(2);
PORTB = addr; // RTC에 Address 전송
PORTA.5=1; // ALE = high
delay_us(2);
PORTA.5=0; // ALE = low
DDRB = 0x00; // 포트B를 입력으로 설정
PORTA.3=0; // RD = low
delay_us(2);
data = PINB; // RTC로부터 데이터 수신
delay_us(2);
PORTA.4=1; //WR = high
PORTA.3=1; // RD = high
PORTA.5=1; // ALE = high
PORTA.6=1; // CS = high
return data;
}
void RTC_Set_Time (void)
{
RTC_Write(0x0A, 0x2f); // A 레지스터 선택
// A 레지스터에 데이터 전송, 오실레이터를 ON 시키고,
// RTC가 시간을 유지하도록 설정, 주기적 인터럽트를 발생시킴(500ms)
// 이 코드가 실행되면서부터 RTC의 시간이 흘러가기 시작한다.
RTC_Write(0x0B, 0x80); // B 레지스터 선택
// 업데이트를 금지시킴
// 현재시각 설정하기
RTC_Write(0x09, 0x08); // 몇 년 2008년
RTC_Write(0x08, 0x06); // 몇 월 5월
RTC_Write(0x07, 0x09); // 몇 일 22일
RTC_Write(0x06, 0x02); // 몇 요일 목요일
RTC_Write(0x04, 0x91); // 몇 시 3시
RTC_Write(0x02, 0x06); // 몇 분 20분
RTC_Write(0x00, 0x10); // 몇 초 10초
RTC_Write(0x0B, 0x40); // B 레지스터 선택 , 저장완료코드
// 업데이트 정상동작, 주기적 인터럽트 인에이블 시킴
// (C 레지스터에 있는 주기적 인터럽트 플래그(PF)가 IRQ 핀을 Low로 구동하는 것을 가능하게 함)
// BCD 데이터 사용, 12-hour 모드 사용
// 주기적 인터럽트를 사용하지 않는다면 disable 시켜도 상관없다.
// 주기적 인터럽트는 MCU의 /INT0 단자에 연결해서 MCU가 주기적으로
// 인터럽트를 받기 위해서 사용하는 것임
}
void RTC_Get_Time (void)
{
hour = hour2 = RTC_Read(0x04); // 몇 시인지 RTC로부터 시간을 읽어옴
// BCD 값이므로 상위 4비트와 하위 4비트를 각각 다른 변수에 저장함
hour &= 0xF0; // 하위 4비트는 0으로 채우고 상위 4비트만 사용
hour >>= 4; // 상위 4비트를 하위 4비트로 이동
hour2 &= 0x0F; // 상위 4비트는 0으로 채우고 하위 4비트만 사용
//---------------------------------------
min = min2 = RTC_Read(0x02); // 몇 분인지 RTC로부터 시간을 읽어옴
// BCD 값이므로 상위 4비트와 하위 4비트를 각각 다른 변수에 저장함
min &= 0xF0; // 하위 4비트는 0으로 채우고 상위 4비트만 사용
min >>= 4; // 상위 4비트를 하위 4비트로 이동
min2 &= 0x0F; // 상위 4비트는 0으로 채우고 하위 4비트만 사용
//----------------------------------------
sec = sec2 = RTC_Read(0x00); // 몇 초인지 RTC로부터 시간을 읽어옴
// BCD 값이므로 상위 4비트와 하위 4비트를 각각 다른 변수에 저장함
sec &= 0xF0; // 하위 4비트는 0으로 채우고 상위 4비트만 사용
sec >>= 4; // 상위 4비트를 하위 4비트로 이동
sec2 &= 0x0F; // 상위 4비트는 0으로 채우고 하위 4비트만 사용
}
//////////////////////////////////////////////////
void main(void)
{
rg_set();
SREG=0x80;
// RTC_Set_Time();
lcd_clr();
/* lcd_cmd(LINE1);
lcd_str("CJB");
lcd_cmd(LINE2);
lcd_str("31JB");
*/
while(1){
RTC_Get_Time();
lcd_cmd(LINE1);
lcd_str("???");
}
;
}
#include <delay.h>
#define ENABLE PORTA.2=1
#define DISABLE PORTA.2=0
#define LINE1 0x80
#define LINE2 0xc0
void rg_set(void)
{
DDRC=0xff;
DDRA=0xff;
}
void lcd_cmd(unsigned char cmd)
{
PORTA.0=0;
PORTA.1=0;
PORTC=cmd;
ENABLE;
DISABLE;
delay_ms(2);
}
void lcd_clr(void)
{
delay_ms(30);
lcd_cmd(0x30);
delay_ms(5);
lcd_cmd(0x30);
delay_us(100);
lcd_cmd(0x30);
lcd_cmd(0x38);
// lcd_cmd(0x01);
lcd_cmd(0x0c);
lcd_cmd(0x06);
}
void lcd_write(unsigned char data)
{
PORTC=data;
PORTA.0=1;
ENABLE;
DISABLE;
delay_us(40);
}
void lcd_str(unsigned char flash *str)
{
int i=0;
while(str[i])
{
lcd_write(str[i]);
i++;
}
}
////////////////////////////////////////////////
/* RTC */
///////////////////////////////////////////////
typedef unsigned char u08; // 0 ~ 255 1바이트
typedef unsigned short u16; // 0 ~ 65535 2바이트
void RTC_Write (u08 addr, u08 data);
u08 RTC_Read (u08 addr);
void RTC_Set_Time (void);
void RTC_Get_Time (void);
u08 hour, hour2; // 몇 시인지 저장할 변수
u08 min, min2; // 몇 분인지 저장할 변수
u08 sec, sec2; // 몇 초인지 저장할 변수
u08 RTC_Get_Hour (void)
{
return hour;
}
u08 RTC_Get_Hour2 (void)
{
return hour2;
}
u08 RTC_Get_Min (void)
{
return min;
}
u08 RTC_Get_Min2 (void)
{
return min2;
}
u08 RTC_Get_Sec (void)
{
return sec;
}
u08 RTC_Get_Sec2 (void)
{
return sec2;
}
///////////////////////////////////////////////////////////////////////////
///////// RTC시작 //////////
///////////////////////////////////////////////////////////////////////////
void RTC_Write (u08 addr, u08 data)
{
DDRB = 0xff; // 포트B를 출력으로 설정
PORTA.3=1; // RD = high
PORTA.4=1; // WR = high
PORTA.6=0; // CS = low
PORTA.5=1; // ALE = high
PORTB = addr; // RTC에 Address 전송
delay_us(2);
PORTA.5=0; // ALE = low
PORTA.4=0; // WR = low
PORTB = data; // RTC에 데이터 전송
delay_us(2);
PORTA.4=1; // WR = high
PORTA.5=1; // ALE = high
PORTA.6=1; // CS = high
}
u08 RTC_Read (u08 addr)
{
u08 data;
DDRB = 0xff; // 포트B를 출력으로 설정
PORTA.3=1; // RD = high
PORTA.4=1; // WR = high
PORTA.6=0; // CS = low
delay_us(2);
PORTB = addr; // RTC에 Address 전송
PORTA.5=1; // ALE = high
delay_us(2);
PORTA.5=0; // ALE = low
DDRB = 0x00; // 포트B를 입력으로 설정
PORTA.3=0; // RD = low
delay_us(2);
data = PINB; // RTC로부터 데이터 수신
delay_us(2);
PORTA.4=1; //WR = high
PORTA.3=1; // RD = high
PORTA.5=1; // ALE = high
PORTA.6=1; // CS = high
return data;
}
void RTC_Set_Time (void)
{
RTC_Write(0x0A, 0x2f); // A 레지스터 선택
// A 레지스터에 데이터 전송, 오실레이터를 ON 시키고,
// RTC가 시간을 유지하도록 설정, 주기적 인터럽트를 발생시킴(500ms)
// 이 코드가 실행되면서부터 RTC의 시간이 흘러가기 시작한다.
RTC_Write(0x0B, 0x80); // B 레지스터 선택
// 업데이트를 금지시킴
// 현재시각 설정하기
RTC_Write(0x09, 0x08); // 몇 년 2008년
RTC_Write(0x08, 0x06); // 몇 월 5월
RTC_Write(0x07, 0x09); // 몇 일 22일
RTC_Write(0x06, 0x02); // 몇 요일 목요일
RTC_Write(0x04, 0x91); // 몇 시 3시
RTC_Write(0x02, 0x06); // 몇 분 20분
RTC_Write(0x00, 0x10); // 몇 초 10초
RTC_Write(0x0B, 0x40); // B 레지스터 선택 , 저장완료코드
// 업데이트 정상동작, 주기적 인터럽트 인에이블 시킴
// (C 레지스터에 있는 주기적 인터럽트 플래그(PF)가 IRQ 핀을 Low로 구동하는 것을 가능하게 함)
// BCD 데이터 사용, 12-hour 모드 사용
// 주기적 인터럽트를 사용하지 않는다면 disable 시켜도 상관없다.
// 주기적 인터럽트는 MCU의 /INT0 단자에 연결해서 MCU가 주기적으로
// 인터럽트를 받기 위해서 사용하는 것임
}
void RTC_Get_Time (void)
{
hour = hour2 = RTC_Read(0x04); // 몇 시인지 RTC로부터 시간을 읽어옴
// BCD 값이므로 상위 4비트와 하위 4비트를 각각 다른 변수에 저장함
hour &= 0xF0; // 하위 4비트는 0으로 채우고 상위 4비트만 사용
hour >>= 4; // 상위 4비트를 하위 4비트로 이동
hour2 &= 0x0F; // 상위 4비트는 0으로 채우고 하위 4비트만 사용
//---------------------------------------
min = min2 = RTC_Read(0x02); // 몇 분인지 RTC로부터 시간을 읽어옴
// BCD 값이므로 상위 4비트와 하위 4비트를 각각 다른 변수에 저장함
min &= 0xF0; // 하위 4비트는 0으로 채우고 상위 4비트만 사용
min >>= 4; // 상위 4비트를 하위 4비트로 이동
min2 &= 0x0F; // 상위 4비트는 0으로 채우고 하위 4비트만 사용
//----------------------------------------
sec = sec2 = RTC_Read(0x00); // 몇 초인지 RTC로부터 시간을 읽어옴
// BCD 값이므로 상위 4비트와 하위 4비트를 각각 다른 변수에 저장함
sec &= 0xF0; // 하위 4비트는 0으로 채우고 상위 4비트만 사용
sec >>= 4; // 상위 4비트를 하위 4비트로 이동
sec2 &= 0x0F; // 상위 4비트는 0으로 채우고 하위 4비트만 사용
}
//////////////////////////////////////////////////
void main(void)
{
rg_set();
SREG=0x80;
// RTC_Set_Time();
lcd_clr();
/* lcd_cmd(LINE1);
lcd_str("CJB");
lcd_cmd(LINE2);
lcd_str("31JB");
*/
while(1){
RTC_Get_Time();
lcd_cmd(LINE1);
lcd_str("???");
}
;
}