I worked on this small project for 5 days and I feel a sense of accomplishment. Thanks to the seniors for their suggestions.
12864 LCD, DS12C887 clock chip, DS18B20 temperature sensor...
#define uchar unsigned char
#define uint unsigned int
uint temp;
float f_temp;
sbit Ds=P2^2;
sbit Dula=P2^6;
sbit Wela=P2^7;
sbit LcdCS=P3^5; //Register selection input determines whether to write data or write command through rs
sbit LcdSID=P3^6; //LCD read/write control Because no data is read from the LCD, rw is always 0
sbit LcdSCLK=P3^4; //LCD enable control Give en a high pulse to send data to the LCD controller
sbit LcdPSB=P3^7; //Serial-parallel control
sbit DSCS=P1^4; //Chip select signal, low level is valid
sbit DSAS=P1^5; //The rising edge of the address select input terminal AS latches the address information appearing on AD0~AD7 into the DS12C887, and the falling edge clears the address information
sbit DSRW=P1^6; //
sbit DSDS=P1^7; //
uchar code table1[]={"CHPAVC 天若海愚"};
uchar code table3[]={"Monday"};
uchar code table4[]={"Tuesday"};
uchar code table5[]={"Wednesday"};
uchar code table6[]={"Thursday"};
uchar code table7[]={"Friday"};
uchar code table8[]={"Saturday"};
uchar code table9[]={"Sunday"};
uchar code table10[]={"°C"};
uchar buff[4];
char year,month,day,week,miao,fen,shi;
uchar nyrsfm[17]; //In the Write_nyrsfm function, method 2 nyrsfm only needs to be declared as nyrsfm[16]
/****************************************************** ******************
File name: wannianli
Author: Tian Ruo Hai Yu
Version number: V1.0
illustrate :
Created: September 17, 2013 13:30:38
Modification history: None
Note: The year, month, day, hour and minute data collected from DS12C887 are displayed on the 12864 LCD screen, and the temperature collected by DS18B20 is displayed on the 12864
*************************************************** *************/
#include
#include
#include
#include
/**********************************
Function Name: Delay()
Function: Delay
Input parameters: z
Remark :
*************************************/
void Delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/************************************
Function Name: Ds_reset()
Function: DS18B20 reset, initialization function
Entry parameters: None
Remark :
**********************************/
void Ds_reset()
{
uint i;
Ds=1; //Book P348, timing diagram, first set the data line to high level 1
_nop_(); //Delay, as short as possible
Ds=0;
i=103;
while(i>0)
i--; //When the bus stays at a low level for more than 480us, all devices on the bus will be reset.
//Delay about 680us The bus stays at a low level for more than 480μs, and all devices on the bus will be reset
_nop_(); //Delay, as short as possible
Ds=1;
i=5;
while(i>0)
i--; //After releasing the bus, if the initialization is successful, a low level 0 is generated within 15~60us, which is returned by DDS18B20.
//This state can confirm its existence, but cannot wait indefinitely
}
/************************************
Function name: Ds_read_bit()
Function: Read one bit of data
Entry parameters: None
Remark :
**********************************/
bit Ds_read_bit()
{
uint i;
bit date;
Ds=0; //MCU (microprocessor) pulls the bus low
_nop_(); //The read time slot starts when the microprocessor pulls the bus down for at least 1us
Ds=1; //Pull the bus down and then release the bus, so that the slave 18b20 can take over the bus and output valid data
_nop_();
_nop_(); // Delay a little and read the data on 18b20, because the data output from ds18b20 is valid within 15us when the falling edge of the read "time gap" appears
dat=Ds; //The host reads the data output by the slave 18b20. These data are valid within 15us of the falling edge of the read time slot.
i=10;
while(i>0)
i--; //All read "time intervals" must be 60~120us, here 77us
return(dat);
}
/************************************
Function name: Ds_read_byte()
Function: Read a byte of data
Entry parameters: None
Remark :
**********************************/
uchar Ds_read_byte()
{
uchar i,j,dat;
dat=0; //The initial value cannot be forgotten
for(i=1;i<=8;i++) //This sentence was once written as for(i=0;i<=8;i++), which caused the program to display the wrong result. Details...
{
j=Ds_read_bit();
dat=(j<<7)|(dat>>1); //The lowest bit of the read data is at the front, so there is exactly one byte in dat
}
return(dat);
}
/************************************
Function name: Ds_write_byte()
Function: Write a byte function to DS18B20
Entry parameters:
Remark :
**********************************/
void Ds_write_byte(uchar dat)
{
uchar i;
uint j;
bit testb;
for(i=1;i<=8;i++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb)
{
Ds=0;
_nop_();
_nop_(); //Look at the timing diagram, at least 1us delay is required to generate a write "time gap"
Ds=1; //The data line is allowed to be pulled high within 15μs after the start of the write time gap
j=8;
while(j>0)
j--; //All write time gaps must last at least 60us
}
else
{
Ds=0;
j=8;
while(j>0)
j--; //The host needs to generate a write-0 time gap, and must pull the data line to a low level and maintain it for at least 60μs.
Ds=1;
_nop_();
_nop_();
}
}
}
/************************************
Function name: Ds_change()
Function: 18b20 starts to obtain temperature and convert
Entry parameters:
Remark :
**********************************/
void Ds_change()
{
Ds_reset(); //initialization
Delay(1);
Ds_write_byte(0xcc); // Skip ROM. Send temperature conversion command directly to 18b20, suitable for one slave machine
Ds_write_byte(0x44); //Write temperature conversion instruction
}
/************************************
Function Name: Get_temp()
Function: Read the temperature stored in the register
Entry parameters: None
Remark :
**********************************/
uint Get_temp()
{
uchar a,b;
Ds_reset();
Delay(1);
Ds_write_byte(0xcc); //Write and skip the ROM read instruction
Ds_write_byte(0xbe); //Read the temporary register. Read the 9-byte temperature data in the internal RAM
a=Ds_read_byte(); //Read lower 8 bits
b=Ds_read_byte(); //Read high 8 bits
temp=b;
temp<<=8; //Two bytes are combined into one word
temp=temp|a;
f_temp=temp*0.0625; //Get the true decimal temperature value. Since DS18B20 can be accurate to 0.0625 degrees, the lowest bit of the read-back data represents 0.0625 degrees.
temp=f_temp*10+0.5; //Multiplying by 10 does not mean taking only one digit after the decimal point, and adding 0.5 means rounding
f_temp=f_temp+0.05;
return temp; //temp is an integer
}
/************************************
Function name: init_com()
Function: Serial port initialization
Entry parameters: None
Remark :
**********************************/
void init_com()
{
TMOD=0x20; //Timer 1, mode 2
PCON=0x00;
SCON=0x50; //equivalent to REN=1;SM0=0;SM1=1;
TH1=0xFD;
TL1=0xFD; //Set baud rate to 9600
TR1=1; //Start timer 1
}
/************************************
Function name: comm()
Function: Serial port sends data
Entry parameters:
Remark :
**********************************/
void comm(uchar *parr)
{
do
{
SBUF=*parr++;
while(!TI); //Sending completed, TI is set to 1 by hardware
TI=0;
}while(*parr); //Keep looping until the character is '\0'
}
/**********************************
Function name: Send_byte()
Function: Send a byte
Input parameter: bbyte
Remark :
*************************************/
void Send_byte(uchar bbyte)
{
uchar i;
for(i=0;i<8;i++)
{
LcdSID=bbyte&0x80; //Get the highest bit
LcdSCLK=1;
LcdSCLK=0; //At the moment when sclk changes from low level to high level, the LCD controller reads or outputs the data on sid
bbyte<<=1; //left shift 1 bit
}
}
/**********************************
Function Name: Write_char()
Function: Write data or write command
Entry parameters: start,ddata
Remark :
*************************************/
void Write_char(bit start,uchar ddata)
{
uchar start_data,Hdata,Ldata;
if(start==0)
{
start_data=0xf8; //write instruction
}
else
{
start_data=0xfa; //write data
}
Hdata=ddata&0xf0; //Get the upper 4 bits
Ldata=(ddata<<4)&0xf0; //Get the lower 4 bits
Send_byte(start_data); //Send start signal
Delay(5); //Delay is required
Send_byte(Hdata); //Send high 4 bits
Delay(1); //Delay is required
Send_byte(Ldata);
Delay(1);
}
/**********************************
Function Name: Lcd_pos()
Function: Set the display position
Input parameters: X,Y
Remark :
*************************************/
void Lcd_pos(uchar X,uchar Y)
{
uchar pos;
if(X==0)
{
X=0x80;
}
else if(X==1)
{
X=0x90;
}
else if(X==2)
{
X=0x88;
}
else if(X==3)
{
X=0x98;
}
pos=X+Y;
Write_char(0,pos);
}
/**********************************
Function name: Lcd_init()
Function: LCD initialization
Entry parameters: None
Remark :
*************************************/
void Lcd_init()
{
Delay(5); //Start waiting, wait for LCD to enter working state
LcdPSB=0; //Serial port driver
Write_char(0,0x30); //Basic instruction operation
Delay(5);
Write_char(0,0x0c); //display on, off cursor, highlight off
Delay(5);
Write_char(0,0x01); //Clear the screen and reset the DDRAM address counter to zero
Delay(5);
}
/************************************
Function Name: Display_temp()
Function: Display temperature on 12864
Entry parameters:
Note: Keep one decimal place.
**********************************/
void Display_temp()
{
uchar i;
Lcd_pos(2,4);
Write_char(1,buff[0]);
Write_char(1,buff[1]);
Write_char(1,buff[2]);
Write_char(1,buff[3]);
for(i=0;i<3;i++)
{
Write_char(1,table10[i]); //Display symbol °C
Delay(5);
}
}
/*********The following is how to operate the DS12C87 clock chip***********/
/**********************************
Function Name: Write_ds()
Function: Write 12C8887 function
Entry parameters: add,date
Remark :
*************************************/
void Write_ds(uchar add,uchar date)
{
DSCS=0;
DSAS=1;
DSDS=1;
DSRW=1;
P0=add;
DSAS=0; //The falling edge of dsas latches the address information on AD0~~AD7 into DS12C887
DSRW=0;
P0=date;
DSAS=1;
DSRW=1; //INTER mode, the rising edge of dsrw latches data
DSCS=1;
}
/**********************************
Function Name: Read_ds()
Function: Read 12C8887 function
Entry parameters: add
Remark :
*************************************/
uchar Read_ds(uchar add)
{
uchar ds_date;
DSAS=1;
DSDS=1;
DSRW=1;
DSCS=0;
P0=add; //write address first
DSAS=0;
DSDS=0;
P0=0xff;
ds_date=P0; //Read data again
DSDS=1;
DSCS=1;
DSAS=1;
return ds_date;
}
/************************************
Function name: Write_nyrsfm()
Function: Display year, month, day, hour and minute on 12864 LCD
Entry parameters:
Note: This cannot be achieved through the functions in /* below
**********************************/
void Write_nyrsfm(char year,char month,char day,char shi,char fen)
{
//method one:
/*uchar i;
Lcd_pos(1,0);
nyrsfm[0]=0x32;
nyrsfm[1]=0x30;
nyrsfm[2]=year/10+0x30;
nyrsfm[3]=year%10+0x30;
nyrsfm[4]='-';
nyrsfm[5]=month/10+0x30;
nyrsfm[6]=month%10+0x30;
nyrsfm[7]='-';
nyrsfm[8]=day/10+0x30;
nyrsfm[9]=day%10+0x30;
nyrsfm[10]=' ';
nyrsfm[11]=shi/10+0x30;
nyrsfm[12]=shi%10+0x30;
nyrsfm[13]=':';
nyrsfm[14]=fen/10+0x30;
nyrsfm[15]=fen%10+0x30;
nyrsfm[16]='\0';
//while(nyrsfm[i]!='\0') //while() loop is not displayed, it is wrong
//{
// Write_char(1,nyrsfm[i]);
// i++;
//}
for(i=0;i<17;i++)
{
Write_char(1,nyrsfm[i]);
Delay(5);
}*/
//Method Two:
Lcd_pos(1,0);
nyrsfm[0]=0x32;
Write_char(1,0x32);
nyrsfm[1]=0x30;
Write_char(1,0x30);
nyrsfm[2]=year/10+0x30;
Write_char(1,nyrsfm[2]);
nyrsfm[3]=year%10+0x30;
Write_char(1,nyrsfm[3]);
nyrsfm[4]='-';
Write_char(1,nyrsfm[4]);
nyrsfm[5]=month/10+0x30;
Write_char(1,nyrsfm[5]);
nyrsfm[6]=month%10+0x30;
Write_char(1,nyrsfm[6]);
nyrsfm[7]='-';
Write_char(1,nyrsfm[7]);
nyrsfm[8]=day/10+0x30;
Write_char(1,nyrsfm[8]);
nyrsfm[9]=day%10+0x30;
Write_char(1,nyrsfm[9]);
nyrsfm[10]=' ';
Write_char(1,nyrsfm[10]);
nyrsfm[11]=shi/10+0x30;
Write_char(1,nyrsfm[11]);
nyrsfm[12]=shi%10+0x30;
Write_char(1,nyrsfm[12]);
nyrsfm[13]=':';
Write_char(1,nyrsfm[13]);
nyrsfm[14]=fen/10+0x30;
Write_char(1,nyrsfm[14]);
nyrsfm[15]=fen%10+0x30;
Write_char(1,nyrsfm[15]);
}
/************************************
Function name: Write_week()
Function: Week display
Entry parameters: xq
Remark :
**********************************/
void Write_week(char xq)
{
uchar i;
Lcd_pos(2,0);
switch(xq)
{
case 1:
i=0;
while(table3[i]!='\0')
{
Write_char(1,table3[i]);
i++;
}
break;
case 2:
i=0;
while(table4[i]!='\0')
{
Write_char(1,table4[i]);
i++;
}
break;
case 3:
i=0;
while(table5[i]!='\0')
{
Write_char(1,table5[i]);
i++;
}
break;
case 4:
i=0;
while(table6[i]!='\0')
{
Write_char(1,table6[i]);
i++;
}
break;
case 5:
i=0;
while(table7[i]!='\0')
{
Write_char(1,table7[i]);
i++;
}
break;
case 6:
i=0;
while(table8[i]!='\0')
{
Write_char(1,table8[i]);
i++;
}
break;
case 7:
i=0;
while(table9[i]!='\0')
{
Write_char(1,table9[i]);
i++;
}
break;
}
}
/************************************
Function name: Set_time()
Function: DS12C887 first power-on initialization time function
Entry parameters: None
Remark :
**********************************/
void Set_time()
{
Write_ds(2,25);
Write_ds(4,10);
Write_ds(6,3);
Write_ds(7,18);
Write_ds(8,9);
Write_ds(9,13);
}
/**********************************
Function name: init()
Function: Initialization
Entry parameters: None
Remark :
*************************************/
void init()
{
uchar i;
i=0;
Wela=0;
Dula=0;
EA=1;
EX1=1;
IT1=1;
Set_time(); //Used when powered on for the first time, only needs to be executed once
Lcd_pos(3,0);
while(table1[i]!='\0')
{
Write_char(1,table1[i]);
i++;
}
}
/************************************
Function name: Main()
Function:
Entry parameters:
Remark :
**********************************/
void Main()
{
init_com(); //Serial port initialization
Lcd_init(); //LCD initialization
init(); //Cannot be placed before the Lcd_init() function, the contents of the init() function can only be displayed after the LCD is initialized
while(1)
{
Ds_change(); //Read the temperature stored in the register
Get_temp(); //Get temperature and convert
sprintf(buff,"%.1f",f_temp); //Format the floating point temperature as a character type and keep one digit. #include
Delay(1000);
comm(buff); //Serial port sends data and displays it on the serial port debugging assistant. This sentence is mainly added here to test the content of buff.
Display_temp(); //Display temperature on 12864 LCD
Delay(5);
year=Read_ds(9); //Read data from DS12C887
month=Read_ds(8);
day=Read_ds(7);
week=Read_ds(6);
shi=Read_ds(4);
fen = Read_ds(2);
Write_nyrsfm(year,month,day,shi,fen); //display on 12864 LCD
Write_week(week); //Display the week
}
}
Previous article:[51 MCU Study Notes FIVE]----Independent Buttons
Next article:In-depth analysis of 51 MCU stack
- Popular Resources
- Popular amplifiers
- Multi-channel pressure measuring instrument based on C8051F020 single chip microcomputer
- Design of automatic player for work and rest signal based on 51 single chip microcomputer
- STM32F103VET6 Qihang development board——3.2-inch color screen application
- Design of C8051F320 Train Safety Inspection Instrument
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Share CC2541 Bluetooth clock settings
- Analysis of the structure and working principle of single chip microcomputer serial communication
- Basic functions of linear charger
- A place that I don't understand
- Problems with sensor acquisition circuits
- What are the RF challenges of small cells for 5G networks?
- Basic Features of DSP TMS320C6000
- Let's take a look at this power switching circuit.
- What is the reason for the Flash Timeout error message when downloading the program on STM32F4?
- EEWORLD University ---- FreeRTOS on stm32 ST