11. Temperature & Time 제어 충북인력개발원 전자과 공학박사 강원찬
DS1620(Digital Thermometer & Thermostat)
0xee: 온도변한 시작 0x22:온도변환 정지 0x0c:컨피그 데이터 쓰기 0xac:컨피그 데이터 읽기 0xaa: 마지막으로 변환된 값 읽기
DS1302(Real-Time Clock chip)
P475 레지스터 정의표
Connection PORTA <->J10(DC Motor) PORTB <->J1(Temp-Time) PORTC <->J19(Text LCD)
CodeVision setting
프로그램 개요 DS1620 Temperature IC로 부터 현재 온도를 읽어들여 LCD로 표시. DS1302 TIME IC로 부터 현재의 시간을 읽어들여 LCD로 표시 Reset시 key값을 확인하여 HIGH 일때는 온도를 LOW일때는 TIME을 표시 SW 49를 전부 off상태에서 다운로드 할것!
프로그램소스 설명 Common.h // 새파일로 작성 #define BIT0 0x01 #define BIT1 0x02
#define DDRA_Init DDRA = 0x00 #define PORTA_Init PORTA = 0xFF #define DDRB_Init DDRB = 0xFF #define PORTB_Init PORTB = 0x11 #define DDRC_Init DDRC = 0xFF #define PORTC_Init PORTC = 0x00 #define LCDP PORTC #define ENPIN_0 PORTC = PORTC & ~BIT1 #define ENPIN_1 PORTC = PORTC | BIT1 typedef unsigned char BYTE; Typedef short int WORD; typedef unsigned long DWORD;
//DS1620 #define OUT_H PORTB = PORTB | BIT0 #define OUT_L PORTB = PORTB & ~BIT0 #define SCK_H PORTB = PORTB | BIT1 #define SCK_L PORTB = PORTB & ~BIT1 #define RST_H PORTB = PORTB | BIT2 #define RST_L PORTB = PORTB & ~BIT2 //DS1302 #define T_OUT_H PORTB = PORTB | BIT4 #define T_OUT_L PORTB = PORTB & ~BIT4 #define T_SCK_H PORTB = PORTB | BIT5 #define T_SCK_L PORTB = PORTB & ~BIT5 #define T_RST_H PORTB = PORTB | BIT6 #define T_RST_L PORTB = PORTB & ~BIT6
//Global variable BYTE DATA, DATA1; BYTE YEAR; BYTE MONTH; BYTE DATE; BYTE HR; BYTE MIN; BYTE SEC;
Main Function P478-p490 교재를 보고 프로그래밍하시오.,
#include <mega128. h> #include <delay. h> #include <lcd #include <mega128.h> #include <delay.h> #include <lcd.h> #include <stdio.h> // Alphanumeric LCD Module functions #asm .equ __lcd_port=0x15 ;PORTC #endasm #define BIT0 0x01 #define BIT1 0x02 #define BIT2 0x04 #define BIT3 0x08 #define BIT4 0x10 #define BIT5 0x20 #define BIT6 0x40 #define BIT7 0x80 #define LCDP PORTC #define ENPIN_0 PORTC = PORTC & ~BIT1 #define ENPIN_1 PORTC = PORTC | BIT1
typedef unsigned char BYTE; typedef short int WORD; typedef unsigned long DWORD; //DS1620 #define OUT_H PORTB = PORTB | BIT0 #define OUT_L PORTB = PORTB & ~BIT0 #define SCK_H PORTB = PORTB | BIT1 #define SCK_L PORTB = PORTB & ~BIT1 #define RST_H PORTB = PORTB | BIT2 #define RST_L PORTB = PORTB & ~BIT2 //DS1302 #define T_OUT_H PORTB = PORTB | BIT4 #define T_OUT_L PORTB = PORTB & ~BIT4 #define T_SCK_H PORTB = PORTB | BIT5 #define T_SCK_L PORTB = PORTB & ~BIT5 #define T_RST_H PORTB = PORTB | BIT6 #define T_RST_L PORTB = PORTB & ~BIT6
// Declare your global variables here BYTE DATA, DATA1; BYTE YEAR,MONTH,DATE,DAY,HR,MIN,SEC; BYTE flagg; BYTE KEY_DATA[8]; BYTE KEY_Flage; unsigned char ldata[17]=" "; BYTE THRMIST[17] = " Thermometer !! "; BYTE TEMP[12] = " Temp : "; //BYTE sun[4] = "SUN"; //BYTE mon[4] = "MON"; //BYTE tue[4] = "TUE"; //BYTE wed[4] = "WED"; //BYTE thu[4] = "THU"; //BYTE fri[4] = "FRI"; //BYTE sat[4] = "SAT"; // External Interrupt 4 service routine interrupt [EXT_INT4] void ext_int4_isr(void) { flagg = 1; }
BYTE READ(BYTE ADDRESS) { BYTE buff1,i,TEM; RST_H; for(i=0;i<8;i++) { SCK_L; //delay_us(30); if(ADDRESS & 0X01) OUT_H; else OUT_L; delay_us(10); SCK_H; delay_us(10); ADDRESS >>= 1; } DDRB = 0xFE; #asm NOP NOP #endasm OUT_L; delay_us(900); buff1 = 0X00;
for(i=0;i<8;i++) { SCK_L; buff1 >>= 1; //delay_us(3); #asm NOP NOP NOP #endasm TEM = PINB; KEY_DATA[i] = TEM & 0x01; //& 0X04; //if(IN) buff1 |= 0x80; //else buff1 &= 0x7F; SCK_H; #asm NOP NOP NOP #endasm //delay_us(3); } SCK_L; RST_L; DDRB = 0xFF; buff1 |= KEY_DATA[0]; for(i=1;i<8;i++) { buff1 |= (KEY_DATA[i] << i); } OUT_H; return(buff1); }
void READ_CAL(void) { DATE = READ(0X87); delay_ms(5); DATE &= 0X3F; MONTH = READ(0X89); delay_ms(5); MONTH &= 0X1F; DAY = READ(0X8B); delay_ms(5); DAY &= 0X07; YEAR = READ(0X8D); } void READ_CLOCK(void) { SEC = READ(0X81); SEC &= 0X7F; MIN = READ(0X83); MIN &= 0X7F; HR = READ(0X85); HR &= 0X3F; }
void WRITE(BYTE ADDRESS, BYTE DATA) { BYTE i; RST_H; for(i=0;i<8;i++) { SCK_L; //delay_us(10); if(ADDRESS & 0X01) OUT_H; else OUT_L; delay_us(10); SCK_H; delay_us(10); ADDRESS >>= 1; } delay_ms(1); for(i=0;i<8;i++) { SCK_L; //delay_us(10); if(DATA & 0X01) OUT_H; else OUT_L; delay_us(10); SCK_H; delay_us(10); DATA >>= 1; } SCK_L; RST_L; }
void WRITE_CLOCK(void) { WRITE(0X80 , SEC); delay_ms(5); WRITE(0X82 , MIN); delay_ms(5); WRITE(0X84 , HR); delay_ms(5); WRITE(0X86 , DATE); delay_ms(5); WRITE(0X88 , MONTH); delay_ms(5); WRITE(0X8A , DAY); delay_ms(5); WRITE(0X8C , YEAR); }
void DISP_CAL(void) { char temp[4]=" "; switch(DAY) { case 1 : sprintf(temp,"sun"); break; case 2 : sprintf(temp,"mon"); break; case 3 : sprintf(temp,"tue"); break; case 4 : sprintf(temp,"wed"); break; case 5 : sprintf(temp,"thu"); break; case 6 : sprintf(temp,"pri"); break; case 7 : sprintf(temp,"sat"); break; } lcd_gotoxy(0,0); sprintf(ldata,"20%02x,%2x,%2x,%4s", YEAR, MONTH, DATE, temp); lcd_puts(ldata); }
void DISP_CLOCK(void) { lcd_gotoxy(0,1); sprintf(ldata,"TIME: %2x:%2x:%2x ", HR, MIN, SEC); lcd_puts(ldata); } void TEMP_SEND(BYTE DATA) { BYTE i; for(i=0;i<8;i++) { T_SCK_L; #asm NOP NOP #endasm if(DATA & 0X01) T_OUT_H; else T_OUT_L; delay_us(10); T_SCK_H; DATA >>=1; delay_us(10); } }
BYTE TEMP_RECEIVE(void) { BYTE i,data,data1; DDRB = 0XEF; data = 0; data1 = 0; T_OUT_L; delay_us(700); for(i=0;i<8;i++) { T_SCK_L; #asm NOP NOP NOP #endasm delay_us(10); data1 = PINB; KEY_DATA[i] = (data1 >> 4)& 0x01; //& 0X04; T_SCK_H; delay_us(10); #asm NOP NOP NOP #endasm } DDRB = 0XFF; data |= KEY_DATA[0]; for(i=1;i<8;i++) { data |= (KEY_DATA[i] << i); } return data; }
void DISP_TEMP(BYTE TO,BYTE T) { BYTE T1,T2,T3; T3 = T & 0x01; T >>= 1; if(TO == 0X01) { sprintf(ldata,"-"); lcd_puts(ldata); T = ~T; T += 1; } T2 = T/100; if(T2 != 0X00) { T2 += 0X30; sprintf(ldata,"%c",T2); lcd_puts(ldata); T2 = T%100; T1 = T2/10; T1 += 0X30; } else { T2 = T%100; T1 = T2/10; if(T1 == 0X00) {sprintf(ldata," "); lcd_puts(ldata);} else T1 += 0X30; } sprintf(ldata,"%c",T1); lcd_puts(ldata); T1 = T2%10; T1 += 0X30; sprintf(ldata,"%c.",T1); lcd_puts(ldata); if(T3 & 0x01){ sprintf(ldata,"5");lcd_puts(ldata); } else { sprintf(ldata,"0");lcd_puts(ldata);} sprintf(ldata,"%cC%c",0xDF,0x20); lcd_puts(ldata); }
void Temp_Rd_disp(void) { T_RST_L; T_RST_H; TEMP_SEND(0XAC); delay_us(50); DATA = TEMP_RECEIVE(); T_RST_L; if((DATA & 0X03) != 0X03) { T_RST_H; TEMP_SEND(0X0C); TEMP_SEND(0X03); T_RST_L; } T_RST_H; TEMP_SEND(0X22); T_RST_L; T_RST_H; TEMP_SEND(0XEE); T_RST_L; Do{ T_RST_H; TEMP_SEND(0XAC); DATA = TEMP_RECEIVE(); T_RST_L; }while((DATA & 0X80) != 0X80); T_RST_H; TEMP_SEND(0XAA); DATA = TEMP_RECEIVE(); DATA1 = TEMP_RECEIVE(); T_RST_L; // lcd_clear(); //LCD CLEAR delay_ms(100); lcd_gotoxy(0,0); // Position : 1st Line sprintf(ldata,"%s",THRMIST); lcd_puts(ldata); lcd_gotoxy(0,1); sprintf(ldata,"%s",TEMP); lcd_puts(ldata); // delay_ms(1000); DISP_TEMP(DATA1,DATA); }
void main(void) { // Declare your local variables here PORTA=0xFF; DDRA=0x00; PORTB=0x11; DDRB=0xFF; PORTC=0x00; DDRC=0xFF; PORTD=0x00; DDRD=0x00; // External Interrupt(s) initialization EICRA=0x00; EICRB=0x02; EIMSK=0x10; EIFR=0x10; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x00; ETIMSK=0x00; // Analog Comparator initialization ACSR=0x80; SFIOR=0x00;
// LCD module initialization lcd_init(16); KEY_Flage = 0; flagg = 0; RST_L; SCK_L; OUT_H; T_RST_L; T_SCK_L; T_OUT_H; WRITE(0X8E,0); WRITE(0X80,0); //날자/시간 세팅 YEAR = 0X11; //2011 year MONTH = 0X07; //7 month DAY = 0X04; //wed DATE = 0X21; //20 date HR = 0X11; //11 hour MIN = 0X59; //44 minite SEC = 0X00; //second
WRITE_CLOCK(); delay_ms(10); WRITE_CLOCK(); delay_ms(10); READ_CAL(); delay_ms(10); READ_CAL(); #asm("sei") while (1) { DISP_CAL(); READ_CLOCK(); DISP_CLOCK();
if(flagg) { Temp_Rd_disp(); delay_ms(1000); delay_ms(1000); delay_ms(1000); flagg = 0; lcd_clear(); } }; //end of while }
연습문제 1) 전원을 켜면 시계가 표시된다. 2) KEY2를 누르면 5초간 현재온도가 표시되고, 다시 시계로 돌아간다. 1) 전원을 켜면 시계가 표시된다. 2) KEY2를 누르면 5초간 현재온도가 표시되고, 다시 시계로 돌아간다. 3) 시계를 맞추도록 다른키를 이용해 세팅부분을 완성하시오.
-끝-