Perfect version of single chip electronic clock program (with alarm clock temperature function)

Publisher:SereneNature7Latest update time:2015-01-15 Source: 51hei Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

This electronic clock has been tested and is OK. It has an alarm function, year, month, day, hour, minute, second, day of the week, and temperature. Four buttons can be used to set the alarm and adjust the time. The temperature can be displayed between positive 125 degrees and negative 55 degrees. As for the time, I tested it for a month and the error was less than 1 minute. I have recorded it in a video. There is a detailed introduction in the video. If you are interested, you can take a look. The address of the video, multiple pictures and source code:  http://www.51hei.com/bbs/dpj-26057-1.html

program:

#include 
#include 
#define uchar unsigned char
#define uint unsigned int
sbit rs=P1^0; //register selection
sbit rw=P1^1; // read and write signal line
sbit lcden=P1^2; //led enable terminal

sbit scl=P1^3; //clock line
sbit rst=P1^5; //reset line
sbit io=P1^4; //data port

sbit key_set_time=P3^4; //Set time key
sbit key_add=P3^5; //Add key
sbit key_minus=P3^6; //minus key
sbit key_set_alarm=P3^7; //Set the alarm key
sbit bee=P1^6; //Buzzer interface
sbit dq=P1^7; //ds18b20 temperature measurement

uchar getTimebuf[7]; //Store time data
uchar time[]={" : : "}; //Time format string
uchar date[]={"20 - - "}; //Date format string
uchar weeklist[]={"SunMonTueWedThuFriSat"}; //week character list
uchar week[]={" "}; //week format string

int count; //Set the values ​​of count to 1235647 for seconds, minutes, hours, days, months, weeks, and years
int alarm; //Whether to enter the alarm setting interface 123 represents the setting of switch minute and hour respectively
int isOpen; //Whether the alarm is on or not. Not on by default
int fen,shi; //minutes and hours of the alarm
int isRing; //Is the alarm ringing?

uchar isInit_1302; //Whether the clock is initialized

int num;
int temperature; //temperature
int temp_flag; //Temperature positive and negative flag

void delay(uint x){
	int y;
	while(x--){
		for(y=100;y>0;y--);
	}
}
void write_1602com(uchar com){
	//1602 write instruction
	rs=0;
	lcden=0;
	P2=com;
	delay(5);
	lcden=1;
	delay(5);
	lcden=0;
}
void write_1602data(uchar dat){
	//1602 write data
	rs=1;
	lcden=0;
	P2=dat;
	delay(5);
	lcden=1;
	delay(5);
	lcden=0;
}
void init_1602(){
	// Initialize 1602 LCD
	rw=0;
	lcden=0;
	write_1602com(0x38); //Set display mode
	write_1602com(0x0c); //Display switch and cursor display and flashing
	write_1602com(0x06); //Cursor moving direction
	write_1602com(0x01);//Clear screen
}
void write_ds1302_byte(uchar temp){
	//ds1302 writes a byte of data
	uchar i;
	for(i=0;i<8;i++){
		io=temp&0x01; //Put the data on the IO port
		scl=0; // prepare data when scl is low
		scl=1; // rising edge write
		temp>>=1;
	}
}
void write_ds1302(uchar add,uchar dat){
	//Write data dat to address add
	rst=0;
	scl=0;
	rst=1;
	write_ds1302_byte(add);
	write_ds1302_byte(dat);
	scl=1;
	rst=0;
}
uchar read_ds1302(uchar add){
	//ds1302 read data
	uchar i,dat;
	rst=0;
	scl=0;
	rst=1;
	write_ds1302_byte(add); //First write the address of the data to be read
	for(i=0;i<8;i++){
		if(io==1){
			dat|=0x80;
		}
		scl=1;
		scl=0; // falling edge reads data
		dat>>=1;
	}
	scl=1;
	rst=0;
	return dat;
}
void read_time(uchar curr_time[]){
	  uchar i;
	  uchar ucAddr = 0x81;
	  for (i=0;i<7;i++){
		curr_time[i] = read_ds1302(ucAddr); //Format: seconds, minutes, hours, days, months, weeks, years
		ucAddr += 2;
	  }
}[page]
void set_time(uchar *pSecDa){
	//set time
	uchar i;
	uchar ucAddr = 0x80;
	write_ds1302(0x8e,0x00);	
	for(i =7;i>0;i--){
		write_ds1302(ucAddr,*pSecDa); //seconds, minutes, hours, days, months, weeks, and years
		pSecDa++;
		ucAddr+=2;
	}
	write_ds1302(0x8e,0x80);
}
void init_ds1302(){
	//ds1302 initialization
	isInit_1302=read_ds1302(0x81); //Read the clock status
	if(isInit_1302&0x80){//Indicates no initialization
		write_ds1302(0x8e,0x00); //Close write protection and keep it open
		write_ds1302(0x90,0xa5); //Auxiliary power charging command: one diode and one 2K resistor
		write_ds1302(0x80,0x00); // second CH set to 0 to start the clock
		write_ds1302(0x82,0x59);// points
		write_ds1302(0x84,0x10);//
		write_ds1302(0x86,0x07);//day
		write_ds1302(0x88,0x05);//month
		write_ds1302(0x8a,0x04);//week
		write_ds1302(0x8c,0x14);//year
		write_ds1302(0x8e,0x80);
	}
}
char int_to_char(int temp){
	//Convert the numbers from 0 to 9 into characters
	char x='0';
	switch(temp){
		case 0:x='0';break;
		case 1:x='1';break;
		case 2:x='2';break;
		case 3:x='3';break;
		case 4:x='4';break;
		case 5:x='5';break;
		case 6:x='6';break;
		case 7:x='7';break;
		case 8:x='8';break;
		case 9:x='9';break;
	}
	return x;
}
int ds18b20_read_temp();
void display(){
	uchar bai,shi,ge,point,fuhao;
	read_time(getTimebuf); //Read time from time to time
    time[6]=(getTimebuf[0])/16+48; //Format time in seconds
    time[7]=(getTimebuf[0])%16+48;

    time[3]=(getTimebuf[1])/16+48; //Format time
    time[4]=(getTimebuf[1])%16+48;

    time[0]=(getTimebuf[2])/16+48; //Format time in hours
    time[1]=(getTimebuf[2])%16+48;

    date[8]=getTimebuf[3]/16+48; //Format date
    date[9]=getTimebuf[3]%16+48;

    date[5]=getTimebuf[4]/16+48; //Format date and month
    date[6]=getTimebuf[4]%16+48;

    date[2]=getTimebuf[6]/16+48; //Format date year
    date[3]=getTimebuf[6]%16+48;

    week[0]=weeklist[(getTimebuf[5]%10)*3]; //Format the week
    week[1]=weeklist[(getTimebuf[5]%10)*3+1];
    week[2]=weeklist[(getTimebuf[5]%10)*3+2];
	
	write_1602com(0x80+1);
	for(num=0;num<10;num++){
		write_1602data(date[num]);
	}

	write_1602data(' ');
	for(num=0;num<3;num++){
		write_1602data(week[num]);
	}

	write_1602com(0x80+0x40);
	for(num=0;num<8;num++){
		write_1602data(time[num]);
	}
	
	//Display temperature value
	write_1602com(0x80+0x40+8); //Set data pointer
	temperature=ds18b20_read_temp();
	bai=temperature/1000+0x30;
	shi=temperature%1000/100+0x30;
	ge=temperature%100/10+0x30;
	point=temperature%100%10+0x30;
	if(temp_flag==1){//Indicates that the sign is not displayed for positive numbers 125.6 25.7
		fuhao=0x20; //display blank
		if(bai==0x30){
			bai=0x20; //If the hundreds place is 0, it will not be displayed
			if(shi==0x30){
				shi=0x20; //If the hundreds digit is 0 and the tens digit is also 0, neither will be displayed
			}
		}
		write_1602data(fuhao);
		write_1602data(bai);
		write_1602data(shi);
	}else{
		fuhao=0x2d; //Display negative sign -2.5 -25.8
		write_1602data(0x20); //Because the lowest negative number is 55, the hundreds place is not displayed
		if(shi==0x30){	
			write_1602data(0x20);
			write_1602data(fuhao);
		}else{
			write_1602data(fuhao);
			write_1602data(shi);
		}
	}
	write_1602data(ge);
	write_1602data('.');
	write_1602data(point);
	write_1602data(0xdf);
	write_1602data('C');
}
void display_alarm(uchar add,int dat){
	//Display the set time and minute
	int x,y;
	x=dat/10;
	y=dat%10;
	write_1602com(add);
	write_1602data(int_to_char(x));
	write_1602com(add+1); //Prevent the address from automatically adding one after writing, and the cursor will flash and cannot be seen
	write_1602data(int_to_char(y));
	write_1602com(add+1);
}
void init_alarm(){
	//The alarm setting interface is only executed when it is entered for the first time
	uchar code x[]="SET ALARM";
	uchar i;
	if (alarm == 0) {
		write_1602com(0x01);//Clear screen
		write_1602com(0x80+3); //Set data pointer
		for(i=0;i<9;i++){
			write_1602data(x[i]);
		}
		display_alarm(0x80+0x40+5,shi);//Load the alarm time
		write_1602com(0x80+0x40+7);
		write_1602data(':');
		display_alarm(0x80+0x40+8,fen);
		if(isOpen){//When initializing, if the alarm has been set, it will display ON
			write_1602com(0x80+0x40+13);
			write_1602data(' ');
			write_1602data('O');
			write_1602data('N');
		}else{
			write_1602com(0x80+0x40+13);
			write_1602data('O');
			write_1602data('F');
			write_1602data('F');
		}
	}
}
void key_scan(){
	int i;
	uchar code tips1[]="SET SUCCESS"; //Tips for successful alarm setting
	uchar code tips2[]="CANCEL SUCCESS"; //Cancel the alarm prompt
	if(key_set_time==0){//Check if it is pressed
		delay(10); //debounce
		if(key_set_time==0){//Check again if it is pressed
			while(!key_set_time);//Check whether it is released
			delay(10); //delay to eliminate jitter
			while(!key_set_time);//Check again whether it is released
			if(alarm==0){//The time setting will be displayed only when the alarm interface is not displayed
				count++;
				write_ds1302(0x80,0x80); //Stop the clock
				if(count==8){
					//When you continue to walk, it means that the time has been set
					write_1602com(0x0c); // Make the cursor disappear
					write_ds1302(0x80,0); //Let the clock continue
					set_time(getTimebuf); //Write new time
					count=0;
					return;
				}
				switch(count){
					case 1:
						write_1602com(0x80+0x40+7);//at the second position
						break;
					case 2:
						write_1602com(0x80+0x40+4);//at the split position
						break;
					case 3:
						write_1602com(0x80+0x40+1);//the position at
						break;
					case 4:
						write_1602com(0x80+14);//in the week position
						break;
					case 5:
						write_1602com(0x80+10);//in the day position
						break;
					case 6:
						write_1602com(0x80+7);//at the position of the month
						break;
					case 7:
						write_1602com(0x80+4);//In the year position
						break;
				}
				write_1602com(0x0f); //Make the cursor flash
			}
		}
	}
	if(key_add==0){//Check if it is pressed
		delay(10); //debounce
		if(key_add==0){//Check again if it is pressed
			while(!key_add);//Check whether it is released
			delay(10); //delay to eliminate jitter
			while(!key_add);//Check again whether it is released
			if(count!=0){
				switch(count){
				case 1:
					//In the seconds position
					getTimebuf[0]++;
					if(getTimebuf[0]==0x5a){
						getTimebuf[0]=0;
					}
					if(getTimebuf[0]==0x4a){
						getTimebuf[0]=0x50;
					}
					if(getTimebuf[0]==0x3a){
						getTimebuf[0]=0x40;
					}
					if(getTimebuf[0]==0x2a){
						getTimebuf[0]=0x30;
					}
					if(getTimebuf[0]==0x1a){
						getTimebuf[0]=0x20;
					}
					if(getTimebuf[0]==0x0a){
						getTimebuf[0]=0x10;
					}
					time[6]=(getTimebuf[0])/16+48; //Format time in seconds
					time[7]=(getTimebuf[0])%16+48;
					write_1602com(0x80+0x40+6);//at the second position
					write_1602data(time[6]);
					write_1602com(0x80+0x40+7);//at the second position
					write_1602data(time[7]);
					write_1602com(0x80+0x40+7); //Let the cursor flash at the second position
					break;
				case 2:
					//At the split position
					getTimebuf[1]++;
					if(getTimebuf[1]==0x5a){
						getTimebuf[1]=0;
					}
					if(getTimebuf[1]==0x4a){
						getTimebuf[1]=0x50;
					}
					if(getTimebuf[1]==0x3a){
						getTimebuf[1]=0x40;
					}
					if(getTimebuf[1]==0x2a){
						getTimebuf[1]=0x30;
					}
					if(getTimebuf[1]==0x1a){
						getTimebuf[1]=0x20;
					}
					if(getTimebuf[1]==0x0a){
						getTimebuf[1]=0x10;
					}
					time[3]=(getTimebuf[1])/16+48; //Format time
					time[4]=(getTimebuf[1])%16+48;
					write_1602com(0x80+0x40+3);//at the split position
					write_1602data(time[3]);
					write_1602com(0x80+0x40+4);//at the split position
					write_1602data(time[4]);
					write_1602com(0x80+0x40+4); //Let the cursor flash at the minute position
					break;
				case 3:
					//The position at time
					getTimebuf[2]++;
					if(getTimebuf[2]==0x24){
						getTimebuf[2]=0;
					}
					if(getTimebuf[2]==0x1a){
						getTimebuf[2]=0x20;
					}
					if(getTimebuf[2]==0x0a){
						getTimebuf[2]=0x10;
					}
					time[0]=(getTimebuf[2])/16+48; //Format time in hours
					time[1]=(getTimebuf[2])%16+48;
					write_1602com(0x80+0x40+0);//at the hour position
					write_1602data(time[0]);
					write_1602com(0x80+0x40+1);
					write_1602data(time[1]);
					write_1602com(0x80+0x40+1);
					break;
				case 4:
					//In the week position
					getTimebuf[5]++;
					if(getTimebuf[5]==0x08){
						getTimebuf[5]=0x01;
					}
					if((getTimebuf[5]%10)*3==21){//Start again after the round
						week[0]=weeklist[0];
						week[1]=weeklist[1];
						week[2]=weeklist[2];
					}else{
						week[0]=weeklist[(getTimebuf[5]%10)*3]; //Format the week
						week[1]=weeklist[(getTimebuf[5]%10)*3+1];
						week[2]=weeklist[(getTimebuf[5]%10)*3+2];
					}
					write_1602com(0x80+12);
					write_1602data(week[0]);
					write_1602com(0x80+13);
					write_1602data(week[1]);
					write_1602com(0x80+14);
					write_1602data(week[2]);
					write_1602com(0x80+14);
					break;
				case 5:
					// In the day position
					getTimebuf[3]++;
					if(getTimebuf[3]==0x32){
						getTimebuf[3]=0x01;
					}
					if(getTimebuf[3]==0x2a){
						getTimebuf[3]=0x30;
					}
					if(getTimebuf[3]==0x1a){
						getTimebuf[3]=0x20;
					}
					if(getTimebuf[3]==0x0a){
						getTimebuf[3]=0x10;
					}
					date[8]=(getTimebuf[3])/16+48;
					date[9]=(getTimebuf[3])%16+48;
					write_1602com(0x80+9);
					write_1602data(date[8]);
					write_1602com(0x80+10);
					write_1602data(date[9]);
					write_1602com(0x80+10);
					break;
				case 6:
					//At the position of the moon
					getTimebuf[4]++;
					if(getTimebuf[4]==0x13){
						getTimebuf[4]=0x01;
					}
					if(getTimebuf[4]==0x0a){
						getTimebuf[4]=0x10;
					}
					date[5]=(getTimebuf[4])/16+48;
					date[6]=(getTimebuf[4])%16+48;
					write_1602com(0x80+6);
					write_1602data(date[5]);
					write_1602com(0x80+7);
					write_1602data(date[6]);
					write_1602com(0x80+7);
					break;
				case 7:
					//In the year position
					getTimebuf[6]++;
					if(getTimebuf[6]==0x9a){
						getTimebuf[6]=0x00;
					}
					if(getTimebuf[6]==0x8a){
						getTimebuf[6]=0x90;
					}
					if(getTimebuf[6]==0x7a){
						getTimebuf[6]=0x80;
					}
					if(getTimebuf[6]==0x6a){
						getTimebuf[6]=0x70;
					}
					if(getTimebuf[6]==0x5a){
						getTimebuf[6]=0x60;
					}
					if(getTimebuf[6]==0x4a){
						getTimebuf[6]=0x50;
					}
					if(getTimebuf[6]==0x3a){
						getTimebuf[6]=0x40;
					}
					if(getTimebuf[6]==0x2a){
						getTimebuf[6]=0x30;
					}
					if(getTimebuf[6]==0x1a){
						getTimebuf[6]=0x20;
					}
					if(getTimebuf[6]==0x0a){
						getTimebuf[6]=0x10;
					}
					date[2]=(getTimebuf[6])/16+48;
					date[3]=(getTimebuf[6])%16+48;
					write_1602com(0x80+3);
					write_1602data(date[2]);
					write_1602com(0x80+4);
					write_1602data(date[3]);
					write_1602com(0x80+4);
					break;
				}
			}
			if(alarm!=0){
				switch(alarm){
					case 1:
						//Adjust the alarm on and off
						if(isOpen==0){
							isOpen=1;
							write_1602com(0x80+0x40+13);
							write_1602data(' ');
							write_1602data('O');
							write_1602data('N');
						}else{
							isOpen=0;
							write_1602com(0x80+0x40+13);
							write_1602data('O');
							write_1602data('F');
							write_1602data('F');
						}
						//Prevent the address from automatically adding one after writing, and the cursor flashes and cannot be seen
						write_1602com(0x80+0x40+15);
						break;
					case 2:
						//Adjust the alarm minutes
						fen++;
						if(fen==60){
							fen=0;
						}
						display_alarm(0x80+0x40+8,fen);
						break;
					case 3:
						//Adjust the alarm hour
						shi++;
						if(shi==24){
							shi=0;
						}
						display_alarm(0x80+0x40+5,shi);
						break;
				}
			}
		}
	}
	if(key_minus==0){//Check if it is pressed
		delay(10); //debounce
		if(key_minus==0){//Check again if it is pressed
			while(!key_minus);//Check whether it is released
			delay(10); //delay to eliminate jitter
			while(!key_minus);//Check again whether it is released
			if(count!=0){
				switch(count){
				case 1:
					//In the seconds position
					getTimebuf[0]--;
					if (getTimebuf[0]==0xff){
						getTimebuf[0]=0x59;
					}
					if (getTimebuf[0]==0x4f){
						getTimebuf[0]=0x49;
					}
					if(getTimebuf[0]==0x3f){
						getTimebuf[0]=0x39;
					}
					if (getTimebuf[0]==0x2f){
						getTimebuf[0]=0x29;
					}
					if(getTimebuf[0]==0x1f){
						getTimebuf[0]=0x19;
					}
					if(getTimebuf[0]==0x0f){
						getTimebuf[0]=0x09;
					}
					time[6]=(getTimebuf[0])/16+48; //Format time in seconds
					time[7]=(getTimebuf[0])%16+48;
					write_1602com(0x80+0x40+6);//at the second position
					write_1602data(time[6]);
					write_1602com(0x80+0x40+7);//at the second position
					write_1602data(time[7]);
					write_1602com(0x80+0x40+7); //Let the cursor flash at the second position
					break;
				case 2:
					//At the split position
					getTimebuf[1]--;
					if(getTimebuf[1]==0xff){
						getTimebuf[1]=0x59;
					}
					if(getTimebuf[1]==0x4f){
						getTimebuf[1]=0x49;
					}
					if(getTimebuf[1]==0x3f){
						getTimebuf[1]=0x39;
					}
					if(getTimebuf[1]==0x2f){
						getTimebuf[1]=0x29;
					}
					if(getTimebuf[1]==0x1f){
						getTimebuf[1]=0x19;
					}
					if(getTimebuf[1]==0x0f){
						getTimebuf[1]=0x09;
					}
					time[3]=(getTimebuf[1])/16+48; //Format time
					time[4]=(getTimebuf[1])%16+48;
					write_1602com(0x80+0x40+3);//at the split position
					write_1602data(time[3]);
					write_1602com(0x80+0x40+4);//at the split position
					write_1602data(time[4]);
					write_1602com(0x80+0x40+4); //Let the cursor flash at the minute position
					break;
				case 3:
					//The position at time
					getTimebuf[2]--;
					if(getTimebuf[2]==0xff){
						getTimebuf[2]=0x23;
					}
					if(getTimebuf[2]==0x1f){
						getTimebuf[2]=0x19;
					}
					if(getTimebuf[2]==0x0f){
						getTimebuf[2]=0x09;
					}
					time[0]=(getTimebuf[2])/16+48; //Format time in hours
					time[1]=(getTimebuf[2])%16+48;
					write_1602com(0x80+0x40+0);//at the hour position
					write_1602data(time[0]);
					write_1602com(0x80+0x40+1);
					write_1602data(time[1]);
					write_1602com(0x80+0x40+1);
					break;
				case 4:
					//In the week position
					getTimebuf[5]--;
					if(getTimebuf[5]==0){
						getTimebuf[5]=0x07;
					}
					if((getTimebuf[5]%10)*3==21){//Start again after the round
						week[0]=weeklist[0];
						week[1]=weeklist[1];
						week[2]=weeklist[2];
					}else{
						week[0]=weeklist[(getTimebuf[5]%10)*3]; //Format the week
						week[1]=weeklist[(getTimebuf[5]%10)*3+1];
						week[2]=weeklist[(getTimebuf[5]%10)*3+2];
					}
					write_1602com(0x80+12);
					write_1602data(week[0]);
					write_1602com(0x80+13);
					write_1602data(week[1]);
					write_1602com(0x80+14);
					write_1602data(week[2]);
					write_1602com(0x80+14);
					break;
				case 5:
					// In the day position
					getTimebuf[3]--;
					if(getTimebuf[3]==0){
						getTimebuf[3]=0x31;
					}
					if(getTimebuf[3]==0x2f){
						getTimebuf[3]=0x29;
					}
					if(getTimebuf[3]==0x1f){
						getTimebuf[3]=0x19;
					}
					if(getTimebuf[3]==0x0f){
						getTimebuf[3]=0x09;
					}
					date[8]=(getTimebuf[3])/16+48;
					date[9]=(getTimebuf[3])%16+48;
					write_1602com(0x80+9);
					write_1602data(date[8]);
					write_1602com(0x80+10);
					write_1602data(date[9]);
					write_1602com(0x80+10);
					break;
				case 6:
					//At the position of the moon
					getTimebuf[4]--;
					if(getTimebuf[4]==0){
						getTimebuf[4]=0x12;
					}
					if(getTimebuf[4]==0x0f){
						getTimebuf[4]=0x09;
					}
					date[5]=(getTimebuf[4])/16+48;
					date[6]=(getTimebuf[4])%16+48;
					write_1602com(0x80+6);
					write_1602data(date[5]);
					write_1602com(0x80+7);
					write_1602data(date[6]);
					write_1602com(0x80+7);
					break;
				case 7:
					//In the year position
					getTimebuf[6]--;
					if(getTimebuf[6]==0xff){
						getTimebuf[6]=0x99;
					}
					if(getTimebuf[6]==0x8f){
						getTimebuf[6]=0x89;
					}
					if(getTimebuf[6]==0x7f){
						getTimebuf[6]=0x79;
					}
					if(getTimebuf[6]==0x6f){
						getTimebuf[6]=0x69;
					}
					if(getTimebuf[6]==0x5f){
						getTimebuf[6]=0x59;
					}
					if(getTimebuf[6]==0x4f){
						getTimebuf[6]=0x49;
					}
					if(getTimebuf[6]==0x3f){
						getTimebuf[6]=0x39;
					}
					if(getTimebuf[6]==0x2f){
						getTimebuf[6]=0x29;
					}
					if(getTimebuf[6]==0x1f){
						getTimebuf[6]=0x19;
					}
					if(getTimebuf[6]==0x0f){
						getTimebuf[6]=0x09;
					}
					date[2]=(getTimebuf[6])/16+48;
					date[3]=(getTimebuf[6])%16+48;
					write_1602com(0x80+3);
					write_1602data(date[2]);
					write_1602com(0x80+4);
					write_1602data(date[3]);
					write_1602com(0x80+4);
					break;
				}
			}
			if(alarm!=0){
				switch(alarm){
					case 1:
						//Adjust the alarm on and off
						if(isOpen==0){
							isOpen=1;
							write_1602com(0x80+0x40+13);
							write_1602data(' ');
							write_1602data('O');
							write_1602data('N');
						}else{
							isOpen=0;
							write_1602com(0x80+0x40+13);
							write_1602data('O');
							write_1602data('F');
							write_1602data('F');
						}
						//Prevent the address from automatically adding one after writing, and the cursor flashes and cannot be seen
						write_1602com(0x80+0x40+15);
						break;
					case 2:
						//Adjust the alarm minutes
						fen--;
						if(fen<0){
							fen=59;
						}
						display_alarm(0x80+0x40+8,fen);
						break;
					case 3:
						//Adjust the alarm hour
						shi--;
						if(shi<0){
							shi=23;
						}
						display_alarm(0x80+0x40+5,shi);
						break;
				}
			}
		}
	}
	if(key_set_alarm==0){//Check if it is pressed
		delay(10); //debounce
		if(key_set_alarm==0){//Check again if it is pressed
			while(!key_set_alarm);//Check if it is released
			delay(10); //delay to eliminate jitter
			while(!key_set_alarm);//Check again whether it is released
			if(count==0){//The alarm can only be set when the time is moving normally
				init_alarm();
				alarm++; //Instructions to enter the alarm setting interface
				if (alarm == 4) {
					alarm=0; //Indicates that the alarm is set
					write_1602com(0x01); //Clear the screen to display the time
					write_1602com(0x0c); //Close the cursor
					//Display prompt of setting success or cancellation
					if(isOpen){
						write_1602com(0x80+2);
						for(i=0;i<11;i++){
							write_1602data(tips1[i]);
						}
					}else{
						write_1602com(0x80+1);
						for(i=0;i<14;i++){
							write_1602data(tips2[i]);
						}
					}
					// Clear the screen and display the time after a delay of 2ms
					delay(2000);
					write_1602com(0x01);
				}else{
					switch(alarm){
						case 1:
							write_1602com(0x80+0x40+15);
							break;
						case 2:
							write_1602com(0x80+0x40+9);
							break;
						case 3:
							write_1602com(0x80+0x40+6);
							break;
					}
					write_1602com(0x0f);
				}
			}
		}
	}
}[page]
void beep(){
	//Detect the alarm and sound the alarm
	if(time[0]==int_to_char(shi/10)&&time[1]==int_to_char(shi%10)&&time[3]==int_to_char(fen/10)&&time[4]==int_to_char(fen%10) ){
		isRing=1; //The alarm rings. If you enter the alarm setting interface to change the time and minute, the alarm will be turned off.
		bee=0;
		delay(250);
		bee=1;
		delay(250);
	}else{
		isRing=0; //Turn off the alarm or the alarm will automatically turn off after one minute
		bee=1;
	}
}
void delay1(int i){
	while(i--);
}
void ds18b20_init(){
	uchar x=0;
	dq = 1; //DQ reset
	delay1(8); //slight delay
	dq = 0; //MCU pulls DQ low
	delay1(80); //Precise delay greater than 480us
	dq = 1; //Pull the bus high
	delay1(14);
	x=dq; //After a short delay, if x=0, initialization is successful, if x=1, initialization fails
	delay1(20);
}
uchar ds18b20_read(){
	//Read a byte
	uchar i=0;
	uchar dat = 0;
	for (i=8;i>0;i--)
	{
		dq = 0; // give pulse signal
		dat>>=1;
		dq = 1; // give pulse signal
		if(dq)
			dat|=0x80;
		delay1(4);
	}
	return(dat);
}
void ds18b20_write(char dat){
	//Write a byte
	uchar i=0;
	for (i=8; i>0; i--)
	{
		dq = 0;
		dq = dat&0x01;
		delay1(5);
		dq = 1;
		dat>>=1;
	}
}
int ds18b20_read_temp(){
	//Read the temperature
	uchar low;
	uchar high;
	unsigned long tmp;
	float value;
	int t; //temperature
	ds18b20_init();
	ds18b20_write(0xCC); //Skip the operation of reading the serial number
	ds18b20_write(0x44); //Start temperature conversion
	ds18b20_init();
	ds18b20_write(0xCC); //Skip the operation of reading the serial number
	ds18b20_write(0xBE); //Read the temperature register, there are nine in total, the first two represent the temperature
	low=ds18b20_read(); //low eight bits of data
	high=ds18b20_read(); //high eight bits of data

	tmp=high;
	tmp<<=8;
	tmp=tmp|low;
	//There are positive and negative values ​​here
	if(tmp>=63488){//ffff f000 0000 0000-->(f800)
		temp_flag=0;
		//When all 8 bits are 1, add 1 to carry
		if((~low)==0xff){//Judge whether there is a carry after adding 1 to low
			high=(~high)+1;
			low=0;
		}else{
			high=~high;
			low=(~low)+1;
		}
		tmp=high*256+low;
	}else{
		temp_flag=1;
	}
	value=tmp*0.0625;
	t=value*10+((temp_flag==1)?+0.5:-0.5); //Amplify the output tenfold and round it off
	return t;
}
void main(){
	init_1602();
	init_ds1302();
	while(1){
		if(isOpen){//Detect only when the alarm is turned on
			beep(); //Continuously detect the alarm
		}
		key_scan();
		if(count==0&&alarm==0){//The time is displayed only when the time is not set and the alarm interface is not on.
			display();
		}
	}
}
Reference address:Perfect version of single chip electronic clock program (with alarm clock temperature function)

Previous article:Fix Keil's cant execute C:\Keil\C51\BIN\A51.EXE
Next article:Solution to the problem of Verilog multiplication result being 0

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号