#include"DS 18B20_3。 h "
# Define uint unsigned integer
# Define uchar unsigned characters
Uchar a, Miao, Shi, min, day, month, year, week, flag, key 1n, temp.
//flag is used to read the temperature value in the header file and display the temperature value.
# Define the initial position of the first line of YH 0x 80//LCD, because the first bit D7 of the LCD 1602 character address is always 1 (10000000 = 80).
# definer 0x80+0x 40//Initial position of the second line of LCD (because the first character position address of the second line is 0x40)
Definition of connection between LCD and C5 1 pin (display data line is connected to P0 port of C5 1)
sbit rs=p 1^0;
sbit en=p 1^2;
sbit rw=p 1^ 1; //If rw is grounded in hardware, you don't need to write this sentence and rw=0.
sbit led=p3^7; //LCD backlight switch
//DS 1302 Definition of Connection between Clock Chip and C5 1
sbit io=p2^2;
sbit sclk=p2^ 1;
sbit rst=p2^2;
sbit acc0=acc^0;
sbit acc7=acc^7;
/************************************************************
ACC accumulator =A
Acceleration 0=E0H
ACC.0 is the 0 th place of ACC. Acc can be bit-addressed.
Accumulator ACC is an 8-bit storage unit used to store data. However, this storage unit has its special location.
It is a very key unit in the single chip microcomputer, and many operations have to be carried out through ACC. When you learn instructions later,
Usually used to represent an accumulator. However, there are some exceptions. For example, the name ACC must be used in the PUSH instruction.
Generally speaking, A stands for the contents of the accumulator and ACC stands for the address of the accumulator.
***************************************************************/
//Definition of connection between time calibration key and C5 1 pin
sbit key 1=p2^4; //Set the key
sbit key2=p2^5; //Keying
sbit key3=p2^6; //key restore
sbit buzzer=p2^0; //Buzzer, driven by transistor 90 12, low-level port response.
/**************************************************************/
Uchar code tab1[] = {"20-"}; //Fixed display year characters
Uchar code tab2 [] = {"::"}; //Fixed characters of time display
//Delay function, which is often called later.
Void delay(uin TMS)// delay function, parameter function
{
uint x,y;
for(x = xms; x & gt0; x -)
for(y = 120; y & gt0; y-);
}
/* * * * * * * The instruction writing function and data writing function of LCD can be called * * * * * * * *
/* In this program, the functions related to liquid crystal writing will be called in the function of DS 1302, so the liquid crystal program should be put in front */
Write _1602com (uchircom)/* * * LCD write command function * * * *
{
RS = 0; //The data/instruction selection is set to instruction.
rw = 0; //The read-write selection is set to write.
P0 = com// Send data
Delay (1);
en = 1; //Pull the enable pin high to prepare for an effective falling edge.
Delay (1);
en = 0; //en changes from high to low, resulting in a falling edge, and the liquid crystal executes the command.
}
Write _1602dat (uchardat)/* * * LCD data writing function * * *
{
RS = 1; //Data/Command Selection Set to Data
rw = 0; //The read-write selection is set to write.
P0 = dat// Send data
Delay (1);
en = 1; //en is set to high level to prepare for the falling edge.
Delay (1);
en = 0; //en changes from high to low, resulting in a falling edge, and the liquid crystal executes the command.
}
LCD _ init ()/* * * LCD initialization function * * * *
{
write _ 1602 com(0x 38); //Set the LCD working mode, meaning: 16*2 line display, 5*7 dot matrix, 8-bit data.
write _ 1602 com(0x0c); //Turn on the display, but don't display the cursor.
write _ 1602 com(0x 06); //The whole screen is still, and the cursor automatically moves to the right.
write _ 1602 com(0x 0 1); //Clear the display
write _ 1602 com(yh+ 1); //The calendar display fixed symbol starts to be displayed after the 1 bit in the first line.
for(a = 0; a & lt 14; a++)
{
write _ 1602 dat(tab 1[a]); //Write the fixed symbol part of the calendar display into the LCD screen.
//delay(3);
}
write _ 1602 com(er+2); //Time shows a fixed writing position of symbols, starting from the second position.
for(a = 0; a & lt8; a++)
{
write _ 1602 dat(tab 2[a]); //Write a symbol with a fixed display time and two colons.
//delay(3);
}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
/* * * * * * * * * * * * DS 1302 Related subfunctions * * * * * * * * * * * * *
Void write_byte(uchar dat)// Write a byte.
{
ACC = dat
RST = 1;
for(a = 8; a & gt0; Answer-)
{
IO = ACC0
SCLK = 0;
SCLK = 1;
ACC = ACC & gt& gt 1;
}
}
Uchar read_byte()// Read a byte.
{
RST = 1;
for(a = 8; a & gt0; Answer-)
{
ACC7 = IO
SCLK = 1;
SCLK = 0;
ACC = ACC & gt& gt 1;
}
Return (ACC);
}
// -
Voidwrite _ 1302 (uchar add, uchar dat)// Write a function to the 1302 chip, specifying the write address and data.
{
RST = 0;
SCLK = 0;
RST = 1;
Write_byte (add);
Write bytes (dat);
SCLK = 1;
RST = 0;
}
Uchar read _ 1302 (uchar add)//Read data function from1302, and specify the source address of the read data.
{
Uchar temperature;
RST = 0;
SCLK = 0;
RST = 1;
Write_byte (add);
temp=read_byte()。
SCLK = 1;
RST = 0;
Return (temporary);
}
Uchar BCD _ decimal (Uchar BCD)//BCD code to decimal function, enter BCD, and return Decimal.
{
Uchar decimal system;
Decimal = bcd & gt& gt4;
return(Decimal = Decimal * 10+(BCD & amp; = 0x0F));
}
// -
Voids1302 _ init ()/1302 chip initialization sub-function (2010/01-07, 12: 00: 00, week 4).
{
RST = 0;
SCLK = 0;
write_ 1302(0x8e,0x 00); //Write is allowed and write protection is prohibited.
write_ 1302(0x80,0x 00); //Write the initial second data 00 into the write second register 80H in DS 1302.
write_ 1302(0x82,0x 00); //Write the initial sub data 00 into the write sub register 82H in DS 1302.
write_ 1302(0x84,0x 12); //Write the initial hour data 12 into the write hour register 84H in DS 1302.
write_ 1302(0x8a,0x 04); //Write the initial week data 4 into the write week register 8aH in DS 1302.
write_ 1302(0x86,0x 07); //Write the initial date data 07 into the write date register 86H in DS 1302.
write_ 1302(0x88,0x 0 1); //Write the initial month data 0 1 into the write month register 88H in DS 1302.
write_ 1302(0x8c,0x 10); //Write the initial year data 10 into the write year register 8cH in DS 1302.
write_ 1302(0x8e,0x 80); //Turn on write protection
}
// -
//Temperature display subfunction
Voidwrite _ temp (uchar add, uchar dat)// Write the temperature data into LCD and specify the display position.
{
uchar gw,SW;
GW = dat % 10; //Get the single digits.
SW = dat/ 10; //Get ten digits
write _ 1602 com(er+add); //er is the value 0x80+0x40 specified in the header file.
write _ 1602 dat(0x 30+SW); //Number +30 to get the LCD 1602 display code of this number.
write _ 1602 dat(0x 30+GW); //Number +30 to get the LCD 1602 display code of this number.
write _ 1602 dat(0x df); //Small circle symbol showing temperature, 0xdf is the address code of the symbol in the LCD character library.
write _ 1602 dat(0x 43); //The symbol "C" is displayed, and 0x43 is the address code of capital C in the LCD character library.
}
// -
//Display subfunctions in minutes and seconds.
Voidwrite _ SFM (UCHAR ADD, UCHAR DAT)// When writing LCD, there are two parameters: display position plus current data.
{
uchar gw,SW;
GW = dat % 10; //Get the single digits.
SW = dat/ 10; //Get ten digits
write _ 1602 com(er+add); //er is the value 0x80+0x40 specified in the header file.
write _ 1602 dat(0x 30+SW); //Number +30 to get the LCD 1602 display code of this number.
write _ 1602 dat(0x 30+GW); //Number +30 to get the LCD 1602 display code of this number.
}
// -
//year, month and day display sub-functions.
Voidwrite _ nyr (uchar add, uchar dat)// writes the year, month and date into LCD, with two parameters: display position addend and display data.
{
uchar gw,SW;
GW = dat % 10; //Get the single digits.
SW = dat/ 10; //Get ten digits
write _ 1602 com(yh+add); //Set the display position to the first position +add.
write _ 1602 dat(0x 30+SW); //Number +30 to get the LCD 1602 display code of this number.
write _ 1602 dat(0x 30+GW); //Number +30 to get the LCD 1602 display code of this number.
}
// -
Void write_week(uchar week)// Write weekly function
{
write _ 1602 com(yh+0x0c); //Displays the position of the day of the week.
Switch (week)
{
case 1:write _ 1602 dat(' M '); //When the number of weeks is 1, it will be displayed.
write _ 1602 dat(' O ');
write _ 1602 dat(' N ');
Break;
Case 2: write _1602dat ('t'); //Displayed when the weekly data is 2.
write _ 1602 dat(' U ');
write _ 1602 dat(' E ');
Break;
Case 3: write _1602dat ('w'); //Displayed when the weekly data is 3.
write _ 1602 dat(' E ');
write _ 1602 dat(' D ');
Break;
Case 4: write _1602dat ('t'); //Display the weekly data of 4.
write _ 1602 dat(' H ');
write _ 1602 dat(' U ');
Break;
Scenario 5: write _1602dat ('f'); //Displayed when the weekly data is 5.
write _ 1602 dat(' R ');
write _ 1602 dat(' I ');
Break;
Case 6: write _1602dat ('s'); //Displayed when the weekly data is 6.
write _ 1602 dat(' T ');
write _ 1602 dat(' A ');
Break;
Case 7: write _1602dat ('s'); //Displayed when the weekly data is 7.
write _ 1602 dat(' U ');
write _ 1602 dat(' N ');
Break;
}
}
//* * * * * * * * * * * * Keyboard scanning related functions * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Void key scan ()
{
If (key 1 = = 0)/-key 1 is a function key (setting key)-.
{
Delay (9); //delay to eliminate jitter
If(key 1==0)// After a delay, confirm to press the key again.
{
Buzzer = 0; //The buzzer rings once.
Delay (20);
Buzzer =1;
And (! key 1);
key 1n++;
if(key 1n==9)
key 1n = 1; //Set button * * * has eight function cycles: second, minute, hour, week, day, month, year and return.
Switch (key 1n)
{
Case1:tr0 = 0; //Turn off the timer
//tr 1 = 0;
write _ 1602 com(er+0x 09); //Press the setting key once, and the cursor will be displayed in seconds.
write _ 1602 com(0x0f); //Set the cursor to blink.
Temp= (seedling)/10* 16+ (seedling)%10; //sec data is written to DS 1302.
write_ 1302(0x8e,0x 00);
write_ 1302(0x80,0x 80 | temp); /Miao
write_ 1302(0x8e,0x 80);
Break;
Case 2: write _1602 com (er+6); //Double-click the fen position to display the cursor.
//write _ 1602 com(0x0f);
Break;
Case 3: write _1602 com (er+3); //press three times, stone
//write _ 1602 com(0x0f);
Break;
Case 4: write _1602com (YH+0x0E); //Press 4 times a week.
//write _ 1602 com(0x0f);
Break;
Case 5: write _1602 com (yh+0); //Press 5 times, ri
//write _ 1602 com(0x0f);
Break;
Case 6: write _1602com (YH+0x07); //Press 6 times, saying
//write _ 1602 com(0x0f);
Break;
Scenario 7: write _1602com (yh+0x04); //Press 7 times, year
//write _ 1602 com(0x0f);
Break;
Case 8:
write _ 1602 com(0x0c); //Press for the eighth time to set the cursor not to blink.
TR0 = 1; //Turn on the timer
Temp= (seedling)/10* 16+ (seedling)%10;
write_ 1302(0x8e,0x 00);
write_ 1302(0x80,0x 00 | temp); //Miao data is written in DS 1302.
write_ 1302(0x8e,0x 80);
Break;
}
}
}
//-Press key 2.
if(key 1n! =0)// When the key 1 is pressed. Press the following key effectively (the number of keystrokes is not equal to zero)
{
If(key2==0) // up arrow
{
Delay (10);
if(key2==0)
{
Buzzer = 0; //The buzzer rings once.
Delay (20);
Buzzer =1;
And (! key 2);
Switch (key 1n)
{
Case 1: Miao++; //Press the setting key 1 time to adjust the second.
If (Miao ==60)
Miao = 0; //If the second exceeds 59, add zero to 1.
Write_sfm(0x08, Miao); //Make the LCD display the number of seconds set by "plus sign" in the correct position.
Temp= (seedling)/10* 16+ (seedling)%10; //ds 1302 requires decimal conversion to DCB code.
write_ 1302(0x8e,0x 00); //Write is allowed and write protection is prohibited.
write_ 1302(0x80,temp); //Write the adjusted second data BCD code into the write second register 80H in DS 1302.
write_ 1302(0x8e,0x 80); //Turn on write protection
write _ 1602 com(er+0x 09); //Because the LCD mode is set to automatically move the cursor to the right after writing data, you need to specify return.
//write _ 1602 com(0x0b);
Break;
Case 2: fen++;+;
If (fen==60)
fen = 0;
write_sfm(0x05,fen); //Let the LCD display the "plus sign" setting sub-data in the correct position.
Temp= (min)/10* 16+ (min)%10; //ds 1302 requires decimal conversion to DCB code.
write_ 1302(0x8e,0x 00); //Write is allowed and write protection is prohibited.
write_ 1302(0x82,temp); //Write the adjusted sub-data BCD code into the sub-write register 82H of DS 1302.
write_ 1302(0x8e,0x 80); //Turn on write protection
write _ 1602 com(er+6); //Because the LCD mode is set to write data, the pointer will automatically increase by one, in which case it will be written back to its original position.
Break;
Case 3: Stone++;
if(shi==24)
Shi = 0;
write_sfm(2,Shi); //Make the LCD display the "plus sign" setting hour data in the correct position.
Temp= (stone)/10* 16+ (stone)%10; //ds 1302 requires decimal conversion to DCB code.
write_ 1302(0x8e,0x 00); //Write is allowed and write protection is prohibited.
write_ 1302(0x84,temp); //Write the adjusted hour data BCD code into the write hour register 84H in DS 1302.
write_ 1302(0x8e,0x 80); //Turn on write protection
write _ 1602 com(er+3); //Because the LCD mode is set to write data, the pointer will automatically increase by one, so the cursor needs to return.
Break;
Case 4: Zhou++;
if(week==8)
Week =1;
write _ 1602 com(yh+0x0C); //Specify the display position of weekly data after "plus sign"
Write_week (week); //Specify the weekly data display content.
Temp= (week)/10* 16+ (week)%10; //ds 1302 requires decimal conversion to DCB code.
write_ 1302(0x8e,0x 00); //Write is allowed and write protection is prohibited.
write_ 1302(0x8a,temp); //Write the adjusted week data BCD code into the week register 8aH in DS 1302.
write_ 1302(0x8e,0x 80); //Turn on write protection
write _ 1602 com(yh+0x0e); //Because the LCD mode is set to write data, the pointer will automatically increase by one, so the cursor needs to return.
Break;
Case 5: ri++;+;
If (ri==32)
ri = 1;
write_nyr(9,ri); //Make the LCD display "plus sign" setting date data in the correct position.
temp =(ri)/ 10 * 16+(ri)% 10; //ds 1302 requires decimal conversion to DCB code.
write_ 1302(0x8e,0x 00); //Write is allowed and write protection is prohibited.
write_ 1302(0x86,temp); //Write the adjusted date data BCD code into the write date register 86H in DS 1302.
write_ 1302(0x8e,0x 80); //Turn on write protection
write _ 1602 com(yh+ 10); //Because the LCD mode is set to write data, the pointer will automatically increase by one, so the cursor needs to return.
Break;
Case 6: Yue++;
If (Yue == 13)
Yue =1;
Write_nyr(6, Yue); //Make the LCD display the month data set by "plus sign" in the correct position.
Temp= (Yue)/10* 16+ (Yue)%10; //ds 1302 requires decimal conversion to DCB code.
write_ 1302(0x8e,0x 00); //Write is allowed and write protection is prohibited.
write_ 1302(0x88,temp); //Write the adjusted BCD code of monthly data into the monthly write register 88H in DS 1302.
write_ 1302(0x8e,0x 80); //Turn on write protection
write _ 1602 com(yh+7); //Because the LCD mode is set to write data, the pointer will automatically increase by one, so the cursor needs to return.
Break;
Case 7: Year++;
If (year == 100)
Year = 0;
Write_nyr(3 years); //Make the LCD display the set year data of "plus sign" in the correct position.
Temp= (year)/10* 16+ (year)%10; //ds 1302 requires decimal conversion to DCB code.
write_ 1302(0x8e,0x 00); //Write is allowed and write protection is prohibited.
write_ 1302(0x8c,temp); //Write the adjusted year data BCD code into the year register 8cH in DS 1302.
write_ 1302(0x8e,0x 80); //Turn on write protection
write _ 1602 com(yh+4); //Because the LCD mode is set to write data, the pointer will automatically increase by one, so the cursor needs to return.
Break;
}
}
}
// - key3。 Please refer to the "Keying" note for the function of each sentence.
if(key3==0)
{
Delay (10); //Delay adjustment and jitter elimination
if(key3==0)
{
Buzzer = 0; //The buzzer rings once.
Delay (20);
Buzzer =1;
And (! key 3);
Switch (key 1n)
{
Case 1: Miao-;
If (Miao =-1)
Miao = 59; //second data will automatically become 59 when it is restored to-1.
Write_sfm(0x08, Miao); //Display the new seconds after the change in the correct position on the LCD.
Temp= (seedling)/10* 16+ (seedling)%10; //ds 1302 requires decimal conversion to DCB code.
write_ 1302(0x8e,0x 00); //Write is allowed and write protection is prohibited.
write_ 1302(0x80,temp); //Write the adjusted second data BCD code into the write second register 80H in DS 1302.
write_ 1302(0x8e,0x 80); //Turn on write protection
write _ 1602 com(er+0x 09); //Because the LCD mode is set to write data, the pointer will automatically increase by one, in which case it will be written back to its original position.
//write _ 1602 com(0x0b);
Break;
Case 2: fen-;
if(fen==- 1)
fen = 59
write_sfm(5,fen);
Temp= (min)/10* 16+ (min)%10; //ds 1302 requires decimal conversion to DCB code.
write_ 1302(0x8e,0x 00); //Write is allowed and write protection is prohibited.
write_ 1302(0x82,temp); //Write the adjusted sub-data BCD code into the sub-write register 82H of DS 1302.
write_ 1302(0x8e,0x 80); //Turn on write protection
write _ 1602 com(er+6); //Because the LCD mode is set to write data, the pointer will automatically increase by one, in which case it will be written back to its original position.
Break;
Case 3: Stone-;
if(shi==- 1)
Stone = 23;
write_sfm(2,Shi);
Temp= (stone)/10* 16+ (stone)%10; //ds 1302 requires decimal conversion to DCB code.
write_ 1302(0x8e,0x 00); //Write is allowed and write protection is prohibited.
write_ 1302(0x84,temp); //Write the adjusted hour data BCD code into the write hour register 84H in DS 1302.
write_ 1302(0x8e,0x 80); //Turn on write protection
write _ 1602 com(er+3); //Because the LCD mode is set to write data, the pointer will automatically increase by one, so the cursor needs to return.
Break;
Case 4: Zhou-;
if(week==0)
Week = 7;
write _ 1602 com(yh+0x0C); //Specify the display position of weekly data after "plus sign"
Write_week (week); //Specify the weekly data display content.
Temp= (week)/10* 16+ (week)%10; //ds 1302 requires decimal conversion to DCB code.
write_ 1302(0x8e,0x 00); //Write is allowed and write protection is prohibited.
write_ 1302(0x8a,temp); //Write the adjusted week data BCD code into the week register 8aH in DS 1302.
write_ 1302(0x8e,0x 80); //Turn on write protection
write _ 1602 com(yh+0x0e); //Because the LCD mode is set to write data, the pointer will automatically increase by one, so the cursor needs to return.
Break;
Case 5: ri-;
If (ri==0)
ri = 3 1;
write_nyr(9,ri);
temp =(ri)/ 10 * 16+(ri)% 10; //ds 1302 requires decimal conversion to DCB code.
write_ 1302(0x8e,0x 00); //Write is allowed and write protection is prohibited.
write_ 1302(0x86,temp); //Write the adjusted date data BCD code into the write date register 86H in DS 1302.
write_ 1302(0x8e,0x 80); //Turn on write protection
write _ 1602 com(yh+ 10); //Because the LCD mode is set to write data, the pointer will automatically increase by one, so the cursor needs to return.
Break;
Case 6: Yue-;
If (Yue ==0)
Yue =12;
Write_nyr(6, Yue);
Temp= (Yue)/10* 16+ (Yue)%10; //ds 1302 requires decimal conversion to DCB code.
write_ 1302(0x8e,0x 00); //Write is allowed and write protection is prohibited.
write_ 1302(0x88,temp); //Write the adjusted BCD code of monthly data into the monthly write register 88H in DS 1302.
write_ 1302(0x8e,0x 80); //Turn on write protection
write _ 1602 com(yh+7); //Because the LCD mode is set to write data, the pointer will automatically increase by one, so the cursor needs to return.
Break;
Case 7: Year-;
If (year =-1)
Year = 99;
Write_nyr(3 years);
Temp= (year)/10* 16+ (year)%10; //ds 1302 requires decimal conversion to DCB code.
write_ 1302(0x8e,0x 00); //Write is allowed and write protection is prohibited.
write_ 1302(0x8c,temp); //Write the adjusted year data BCD code into the year register 8cH in DS 1302.
write_ 1302(0x8e,0x 80); //Turn on write protection
write _ 1602 com(yh+4); //Because the LCD mode is set to write data, the pointer will automatically increase by one, so the cursor needs to return.
Break;
}
}
}
}
}
// -
Void init() // timer, counter setting function
{
TMOD = 0x 1 1; //Specifies that the working mode of timer/counter is 3.
TH0 = 0; //Upper four bits of timer T0 =0
TL0 = 0; //Lower four bits of timer T0 =0
EA = 1; //The system allows to open interrupts.
ET0 = 1; //Allow T0 interrupt
TR0 = 1; //Turn on the interrupt and start the timer.
}
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
//***************************************************
void main()
{
LCD _ init(); //Call the LCD initialization subroutine.
ds 1302 _ init(); //Call the initialization sub-function of DS 1302 clock.
init(); //Call the setting sub-function of the timer counter.
led = 0; //Turn on the backlight power of the LCD.
Buzzer = 0; //The buzzer rings once.
Delay (80);
Buzzer =1;
While( 1) // Loop the following statement indefinitely:
{
key scan(); //Call the keyboard scanning subfunction.
}
}
Void timer0 () interrupts 1 // Get and display the calendar and time.
{
//Init _ ds 18b 20(); //The initialization sub-function of the temperature sensor DS 18b2 is in the header file.
flag = read temperature(); //Send the function result returned by running the 18b2 header file to the variable FLAG for display.
//Read seven data of week, month, year and year in seconds (the reading register of DS 1302 is different from the writing register):
Miao = BCD _ Decimal(read _ 1302(0x 8 1));
fen = BCD _ Decimal(read _ 1302(0x 83));
Shi = BCD _ Decimal(read _ 1302(0x 85));
ri = BCD _ Decimal(read _ 1302(0x 87));
Yue = BCD _ decimal (read _1302 (0x89));
nian = BCD _ Decimal(read _ 1302(0x8d));
week = BCD _ Decimal(read _ 1302(0x8b));
//Display temperature, second, hour and minute data:
write_temp( 12,flag); //Displays the temperature, starting with the 12 character in the second line.
Write_sfm(8, Miao); //seconds, starting from the eighth word in the second line (the sub-function is displayed every second when called)
write_sfm(5,fen); //minutes, starting from the fifth character in the second line.
write_sfm(2,Shi); //hour, starting from the second character in the second line.
//Display date, month and year data:
write_nyr(9,ri); //Date, displayed after the ninth character in the second line.
Write_nyr(6, Yue); //Month, which is displayed after the sixth character in the second line.
Write_nyr(3 years); //Year, starting from the third character in the second line.
Write_week (week);
}