单片机读取130218B021602

合集下载

DS1302与液晶1602简单时钟

DS1302与液晶1602简单时钟

《单片机原理实验》考试报告题目:DS1302和1602时钟姓名:学号:班级:专业:电子信息工程指导老师:提交时间:DS1302和1602时钟***(**学院电子信息工程 ***班 **********)摘要:关键词:DS1302 ,液晶1602,89C51。

1.引言我们在日常生活中常常用到时钟来记录时间,有时候还不能准确的记录下时间,这就要用到芯片DS1302了。

时间还远远不够,因为人性化的设计自然是要清楚的显示年、月、日、星期、时间。

而在此用到的DS1302非常好的与时间进行同步,并且在掉电时不会对时间有影响,较理的考虑到了人们的思维模式,从而简单的控制了时钟,结合了常理的理论。

2.原理DS1302引脚X1 X2 32.768KHz 晶振管脚GND 地CE 复位脚I/O 数据输入/输出引脚SCLK 串行时钟Vcc1,Vcc2 电源供电管脚各引脚的功能为:Vcc1:主电源;Vcc2:备份电源。

当Vcc2>Vcc1+0.2V时,由Vcc2向DS1302供电,当Vcc2< Vcc1时,由Vcc1向DS1302供电。

SCLK:串行时钟,输入,控制数据的输入与输出;I/O:三线接口时的双向数据线;CE:输入信号,在读、写数据期间,必须为高。

该引脚有两个功能:第一,CE开始控制字访问移位寄存器的控制逻辑;其次,CE提供结束单字节或多字节数据传输的方法。

DS1302控制字:控制字的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入到DS1302中。

位6:如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1(A4~A0):指示操作单元的地址;位0(最低有效位):如为0,表示要进行写操作,为1表示进行读操作。

控制字总是从最低位开始输出。

在控制字指令输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从最低位(0位)开始。

同样,在紧跟8位的控制字指令后的下一个SCLK脉冲的下降沿,读出DS1302的数据,读出的数据也是从最低位到最高位。

ds1302驱动+18b20+1602

ds1302驱动+18b20+1602
* 当前版本 : 修改人: 修改日期:
* 修改说明 :
******************************************************************************************/
void main(void)
void Disp_line2(void); //显示屏幕第二行
void id_case1_key();
//*********** DS1302 时间显示定义部分
sbit T_CLK = P3^5;
sbit T_IO = P3^6;
sbit T_RST = P3^7;
sbit ACC0=ACC^0;
id_case1_key();
break;
case 7://秒
min=0;
sec=1;
Disp_line1();
Disp_line2();
void Delay5Ms(void);
void Delay400Ms(void);
uchar code week[]={"Week."};
/******************************************************************************************
//初始化后设置为:04年12月2日星期4 0点0分0秒
uchar inittime[7]={0x00,0x00,0x00,0x02,0x12,0x04,0x04};
// 秒 分钟 小时 日 月 年 星期
//***** 18B20温度显示定义部分
id_case1_key();

DS1302 DS18B20 LCD1602经典万年历 高低温报警

DS1302    DS18B20   LCD1602经典万年历  高低温报警

/*********************************************//* Filename :万年历** Describe : 时间星期日期温度高低温报警** Designer :潜力狼** Date :2012-07-16/*********************************************/#include<reg52.h>#include<intrins.h>/**********************************************//************ 接口定义如下***************//**********************************************/sbit SCK = P1^7; //时钟sbit SDA = P2^3; //数据sbit RST = P1^3; //DS1302复位(片选)sbit E=P1^2;//1602使能引脚sbit RW=P2^1;//1602读写引脚sbit RS=P2^0;//1602数据/命令选择引脚#define uchar unsigned char#define uint unsigned int#define DS1302_W_ADDR 0xBE#define DS1302_R_ADDR 0xBF#define jump_ROM 0xCC //DS18B20#define start 0x44 //DS18B20#define read_EEROM 0xBE //DS18B20sbit DQ = P1^4;unsigned char TMPH_DS18B20,TMPL_DS18B20;/****************************************************/uchar num,m,n;uchar time1[7]={0x50,0x59,0x23,0x31,0x12,0x07,0x12};//秒分时日月周年10-08-15 23:59:50 ****注意没有code 才可以做指针变量(地址)//uchar time1[7]={50,59,23,31,12,07,12};//此种十进制表示需要转换成BCD码才能写入DS1302 ,而且这样表达,在液晶上显示困难char code table[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};//液晶显示0~9数字的LCD字型码值(ASCII码)void delay(uint z){while(z--);}void delay_1ms(uchar z){uint i,j;for(i=0;i<z;i++)for(j=0;j<128;j++);}void write_DS1302_byte(uchar dat) {uchar i;//RST=1;for(i=0;i<8;i++){SDA=dat&0x01;SCK=1;dat>>=1;SCK=0;}}uchar read_DS1302_byte(void) {uchar i,temp=0;for(i=0;i<8;i++){temp>>=1;if(SDA)temp|=0x80;SCK=1;SCK=0;}return temp;}void reset_DS1302(){RST=0;SCK=0;RST=1;}void clear_DS1302_WP(){reset_DS1302();RST=1; //?write_DS1302_byte(0x8e);write_DS1302_byte(0);SDA=0; //?RST=0; // ?}void set_DS1302_WP(){reset_DS1302();RST=1;write_DS1302_byte(0x8e);write_DS1302_byte(0x80);SDA=0;RST=0;}void set_time(uchar *timedata){uchar i;//,temp;/* for(i=0;i<7;i++) //时钟显示的7个数BCD码转换{temp=timedata[i]/10;timedata[i]=timedata[i]%10;timedata[i]=temp*16+timedata[i];} */clear_DS1302_WP();reset_DS1302();write_DS1302_byte(DS1302_W_ADDR);//写入写地址指令for(i=0;i<7;i++){write_DS1302_byte(timedata[i]);delay(10);}write_DS1302_byte(0); //??????SDA=0;RST=0;set_DS1302_WP();}void read_time(uchar *timedata){uchar i;clear_DS1302_WP();reset_DS1302();write_DS1302_byte(DS1302_R_ADDR);for(i=0;i<7;i++){timedata[i]=read_DS1302_byte();delay(10);}SDA=0;RST=1;set_DS1302_WP();}/****************************************//*LCD1602 函数体*//****************************************///uchar code table[]="Time: ";//uchar code table1[]="Data:20";uchar code week[]="MonTueWenThuFriSatSun";void write_LCD1602_cmd(uchar del) // 写入命令函数{RS=0;//RS=0时,一个高脉冲读取命令RW=0;E=0; //可以省略不写delay_1ms(5);P0=del;delay_1ms(5);E=1; //E从0到1再跳变到0,即一个高脉冲delay_1ms(5);E=0;}void write_LCD1602_data(uchar del) //写入数据函数{RS=1; //RS=1时,一个高脉冲读取数据RW=0;E=0;delay_1ms(5);P0=del;delay_1ms(5);E=1;//E从0到1再跳变到0,即一个高脉delay_1ms(5);E=0;}void LCD1602_init(){write_LCD1602_cmd(0x38);write_LCD1602_cmd(0x0e);write_LCD1602_cmd(0x06);//wcmd(0x80); //命令数据0x80是让液晶从第一位开始显示}/********************************************************/ /* 温度传感器DS18B20 对温度的采集*//********************************************************/ uchar Reset_DS18B20(void){uchar deceive_ready;DQ = 0;delay(29);DQ = 1;delay(3);deceive_ready = DQ;delay(25);return(deceive_ready);}uchar read_DS18B20_bit(void){uchar i;DQ = 0;DQ = 1;for(i=0; i<3; i++);return(DQ);}void write_DS18B20_bit(uchar bitval){DQ=0;if(bitval==1)DQ=1;delay(5);DQ=1;}uchar read_DS18B20_byte(void){uchar i,m,receive_data;m = 1;receive_data = 0;for(i=0; i<8; i++){if(read_DS18B20_bit()){receive_data = receive_data + (m << i);}delay(6);}return(receive_data);}void write_DS18B20_byte(uchar val){uchar i,temp;for(i=0; i<8; i++){temp = val >> i;temp = temp & 0x01;write_DS18B20_bit(temp);delay(5);}}void main(){uint temp;//DS18B20LCD1602_init();set_time(&time1);while(1){Reset_DS18B20();write_DS18B20_byte(jump_ROM);write_DS18B20_byte(start);Reset_DS18B20();write_DS18B20_byte(jump_ROM);write_DS18B20_byte(read_EEROM);TMPL_DS18B20 = read_DS18B20_byte();TMPH_DS18B20 = read_DS18B20_byte();temp = TMPL_DS18B20/16 + TMPH_DS18B20*16;m = table[temp/10%10];n = table[temp%10];/* if(temp>32|temp<20) //蜂鸣器报警!!!{Bell=0;delay_1ms(200);Bell=1;} */read_time(&time1);write_LCD1602_cmd(0x80);write_LCD1602_data(' ');write_LCD1602_data(time1[2]/16+48); //时write_LCD1602_data(time1[2]%16+48);write_LCD1602_data(':');write_LCD1602_data(time1[1]/16+48); // 分write_LCD1602_data(time1[1]%16+48);write_LCD1602_data(':');write_LCD1602_data(time1[0]%16+48);write_LCD1602_data(' ');write_LCD1602_cmd(0x80+12); //英文缩写星期switch(time1[5]%16) //{case 1:write_LCD1602_data(week[0]);write_LCD1602_data(week[1]);write_LCD1602_data(week[2]);break;case 2:write_LCD1602_data(week[3]);write_LCD1602_data(week[4]);write_LCD1602_data(week[5]);break;case 3:write_LCD1602_data(week[6]);write_LCD1602_data(week[7]);write_LCD1602_data(week[8]);break;case 4:write_LCD1602_data(week[9]);write_LCD1602_data(week[10]);write_LCD1602_data(week[11]);break;case 5:write_LCD1602_data(week[12]);write_LCD1602_data(week[13]);write_LCD1602_data(week[14]);break;case 6:write_LCD1602_data(week[15]);write_LCD1602_data(week[16]);write_LCD1602_data(week[17]);break;case 7:write_LCD1602_data(week[18]);write_LCD1602_data(week[19]);write_LCD1602_data(week[20]);break;}write_LCD1602_cmd(0x80+0x40);write_LCD1602_data(2+48); //显示2write_LCD1602_data(0+48); //显示0write_LCD1602_data(time1[6]/16+48); //显示12年write_LCD1602_data(time1[6]%16+48);write_LCD1602_data('-');write_LCD1602_data(time1[4]/16+48); //月write_LCD1602_data(time1[4]%16+48);write_LCD1602_data('-');write_LCD1602_data(time1[3]%16+48);write_LCD1602_data(' ');write_LCD1602_data(m); //温度write_LCD1602_data(n);//write_LCD1602_data(temp/10%10+48);//直接转换为LCD字型码(ASCII码)显示温度//write_LCD1602_data(temp%10+48);write_LCD1602_data(0xdf);write_LCD1602_data('C');}}。

DS1302时钟芯片与液晶1602的程序

DS1302时钟芯片与液晶1602的程序

DS1302测试程序晶振:11.0592MHZ/*********************************包含头文件********************************/#include "reg51.h"#include <intrins.h>/*********************************端口定义**********************************/ sbit DS1302_CLK = P1^0;sbit DS1302_IO = P1^1;sbit DS1302_RST = P1^2;/******************************定义全局变量*********************************/ unsigned char second,minute,hour,week,day,month,year; //秒、分、时、星期、日、月、年unsigned char time[]={0x06,0x03,0x14,0x03,0x12,0x30,0x00}; //初始时间数组/**************************************************************************** 函数功能:数码管扫描延时子程序入口参数:出口参数:****************************************************************************/ void delay1(void){int k;for(k=0;k<400;k++);}/***************************************************************************** 函数功能:向DS1302送一字节数据子程序入口参数:出口参数:*****************************************************************************/ void InputByte(unsigned char byte1){char i;for(i=8;i>0;i--){DS1302_IO=(bit)(byte1&0x01);DS1302_CLK=1;_nop_();DS1302_CLK=0;byte1>>=1;}return;}/***************************************************************************** 函数功能:读DS1302一个字节子程序入口参数:出口参数:*****************************************************************************/ unsigned char outputbyte(void){unsigned char i;unsigned ucdat=0;for(i=8;i>0;i--){DS1302_IO=1;ucdat>>=1;if(DS1302_IO)ucdat|=0x80;DS1302_CLK=1;_nop_();DS1302_CLK=0;}return(ucdat);}/***************************************************************************** 函数功能:向DS1302某地址写一字节数据子程序入口参数:addr,TDat出口参数:*****************************************************************************/ void write_ds1302(unsigned char addr,unsigned char TDat){DS1302_RST=0;_nop_();DS1302_CLK=0;_nop_();DS1302_RST=1;InputByte(addr);_nop_();InputByte(TDat);DS1302_CLK=1;_nop_();DS1302_RST=0;}/***************************************************************************** 函数功能:读DS1302地址子程序入口参数:add出口参数:timedata*****************************************************************************/ unsigned char read_ds1302(unsigned char addr){unsigned char timedata;DS1302_RST=0;_nop_();DS1302_CLK=0;_nop_();DS1302_RST=1;InputByte(addr);timedata=OutputByte();DS1302_CLK=1;_nop_();DS1302_RST=0;return(timedata);}/***************************************************************************** 函数功能:初始化DS1302子程序入口参数:time[](全局变量)出口参数:*****************************************************************************/ void initial_ds1302(){write_ds1302(0x8e,0x00); //写保护寄存器,在对时钟或RAM写前WP一定要为0write_ds1302(0x8c,time[0]); //年write_ds1302(0x88,time[1]); //月write_ds1302(0x86,time[2]); //日write_ds1302(0x8A,time[3]); //星期write_ds1302(0x84,time[4]); //时write_ds1302(0x82,time[5]); //分write_ds1302(0x80,time[6]); //秒write_ds1302(0x8e,0x80); //写保护寄存器}/***************************************************************************** 函数功能:读DS1302时间子程序入口参数:出口参数:全局变量(second,minute,hour,week,day,month,year)*****************************************************************************/ void read_time(){second=read_ds1302(0x81); //秒寄存器minute=read_ds1302(0x83); //分hour=read_ds1302(0x85); //时week=read_ds1302(0x8B); //星期day=read_ds1302(0x87); //日month=read_ds1302(0x89); //月year=read_ds1302(0x8d); //年}void write_com(uchar com){P0=com;rs=0;lcden=0;delay(10);lcden=1;delay(10);lcden=0;}//液晶读写程序//void write_date(uchar date){P0=date;rs=1;lcden=0;delay(10);lcden=1;delay(10);lcden=0;}void init(){dula=0;wela=0;write_com(0x38);delay(20);write_com(0x0f);delay(20);write_com(0x06);delay(20);write_com(0x01);delay(20);}//液晶显示时间程序//void time_display(){void write_com(0x80);void write_date(year);void write_com(0x80+5);void write_date(month);void write_com(0x80+8);void write_date(day);void write_com(0x80+11);void write_date(week);}/***************************************************************************** 函数功能:主程序入口参数:出口参数:*****************************************************************************/ void main(void){initial_ds1302(); //初始化DS1302while(1){read_time(); //读取时间time_display(); //显示时间}}。

玩转DS1302和DS18B20

玩转DS1302和DS18B20

玩转DS1302和DS18B20对于市面上的大多数51单片机开发板来说。

ds1302和ds18b20应该是比较常见的两种外围芯片。

ds130 2是具有SPI总线接口的时钟芯片。

ds18b20则是具有单总线接口的数字温度传感器。

下面让我们分别来认识并学会应用这两种芯片。

首先依旧是看DS1302的datasheet中的相关介绍。

上面是它的一些基本的应用介绍。

下面是它的引脚的描述。

下面是DS1302的时钟寄存器。

我们要读取的时间数据就是从下面这些数据寄存器中读取出来的。

当我们要想调整时间时,可以把时间数据写入到相应的寄存器中就可以了。

这是DS1302内部的31个RAM寄存器。

在某些应用场合我们可以应用到。

如我们想要做一个带定时功能的闹钟。

则可以把闹钟的时间写入到31个RAM寄存器中的任意几个。

当单片机掉电时,只要我们的DS 1302的备用电池还能工作,那么保存在其中的闹钟数据就不会丢失~~由于对于这些器件的操作基本上按照数据手册上面提供的时序图和相关命令字来进行操作就可以了。

因此在我们应用这些器件的时候一定要对照着手册上面的要求来进行操作。

如果觉得还不够放心的话。

可以到网上下载一些参考程序。

对着手册看别人的程序,看别人的思路是怎么样的。

DS1302和单片机的连接很简单。

只需一根复位线,一根时钟线,一根数据线即可。

同时它本身还需要接一个32.768KHz的晶振来提供时钟源。

对于晶振的两端可以分别接一个6PF左右的电容以提高晶振的精确度。

同时可以在第8脚接上一个3.6V的可充电的电池。

当系统正常工作时可以对电池进行涓流充电。

当系统掉电时,DS1302由这个电池提供的能量继续工作。

下面让我们来驱动它。

sbit io_DS1302_RST = P2^0 ;sbit io_DS1302_IO = P2^1 ;sbit io_DS1302_SCLK = P2^2 ;//-------------------------------------常数宏---------------------------------//#define DS1302_SECOND_WRITE 0x80 //写时钟芯片的寄存器位置#define DS1302_MINUTE_WRITE 0x82#define DS1302_HOUR_WRITE 0x84#define DS1302_WEEK_WRITE 0x8A#define DS1302_DAY_WRITE 0x86#define DS1302_MONTH_WRITE 0x88#define DS1302_YEAR_WRITE 0x8C#define DS1302_SECOND_READ 0x81 //读时钟芯片的寄存器位置#define DS1302_MINUTE_READ 0x83#define DS1302_HOUR_READ 0x85#define DS1302_WEEK_READ 0x8B#define DS1302_DAY_READ 0x87#define DS1302_MONTH_READ 0x89#define DS1302_YEAR_READ 0x8D//-----------------------------------操作宏----------------------------------//#define DS1302_SCLK_HIGH io_DS1302_SCLK = 1 ;#define DS1302_SCLK_LOW io_DS1302_SCLK = 0 ;#define DS1302_IO_HIGH io_DS1302_IO = 1 ;#define DS1302_IO_LOW io_DS1302_IO = 0 ;#define DS1302_IO_READ io_DS1302_IO#define DS1302_RST_HIGH io_DS1302_RST = 1 ;#define DS1302_RST_LOW io_DS1302_RST = 0 ;/******************************************************* 保存时间数据的结构体*******************************************************/struct{uint8 Second ;uint8 Minute ;uint8 Hour ;uint8 Day ;uint8 Week ;uint8 Month ;uint8 Year ;}CurrentTime ;/************************************************************** **************** * Function: static void v_DS1302Write_f( uint8 Content ) * * Description:向DS1302写一个字节的内容* * Parameter:uint8 Content : 要写的字节** **************************************************************** ***************/static void v_DS1302Write_f( uint8 Content ){uint8 i ;for( i = 8 ; i > 0 ; i-- ){if( Content & 0x01 ){DS1302_IO_HIGH}else{DS1302_IO_LOW}Content >>= 1 ;DS1302_SCLK_HIGHDS1302_SCLK_LOW}}/************************************************************** **************** * Function: static uint8 v_DS1302Read_f( void ) * * Description: 从DS1302当前设定的地址读取一个字节的内容* * Parameter: ** Return: 返回读出来的值(uint8) **************************************************************** ***************/ static uint8 v_DS1302Read_f( void ){uint8 i, ReadValue ;DS1302_IO_HIGHfor( i = 8 ; i > 0 ; i-- ){ReadValue >>= 1 ;if( DS1302_IO_READ ){ReadValue |= 0x80 ;}else{ReadValue &= 0x7f ;}DS1302_SCLK_HIGHDS1302_SCLK_LOW}return ReadValue ;}/************************************************************** ***************** Function: void v_DS1302WriteByte_f( uint8 Address, uint8 Content ) ** Description: 从DS1302指定的地址写入一个字节的内容** Parameter: Address: 要写入数据的地址** Content: 写入数据的具体值** Return: * ******************************************************************* ***********/void v_DS1302WriteByte_f( uint8 Address, uint8 Content ){DS1302_RST_LOWDS1302_SCLK_LOWDS1302_RST_HIGHv_DS1302Write_f( Address ) ;v_DS1302Write_f( Content ) ;DS1302_RST_LOWDS1302_SCLK_HIGH}/************************************************************** ***************** Function: uint8 v_DS1302ReadByte_f( uint8 Address ) ** Description:从DS1302指定的地址读出一个字节的内容** Parameter:Address: 要读出数据的地址** ** Return: 指定地址读出的值(uint8) **************************************************************** ***************/uint8 v_DS1302ReadByte_f( uint8 Address ){uint8 ReadValue ;DS1302_RST_LOWDS1302_SCLK_LOWDS1302_RST_HIGHv_DS1302Write_f( Address ) ;ReadValue = v_DS1302Read_f() ;DS1302_RST_LOWDS1302_SCLK_HIGHreturn ReadValue ;}/************************************************************** ***************** Function: void v_ClockInit_f( void ) ** Description:初始化写入DS1302时钟寄存器的值(主程序中只需调用一次即可) * * Parameter:** ** Return: **************************************************************** ***************/void v_ClockInit_f( void ){if( v_DS1302ReadByte_f( 0xc1) != 0xf0 ){v_DS1302WriteByte_f( 0x8e, 0x00 ) ; //允许写操作v_DS1302WriteByte_f( DS1302_YEAR_WRITE, 0x08 ) ; //年v_DS1302WriteByte_f( DS1302_WEEK_WRITE, 0x04 ) ; //星期v_DS1302WriteByte_f( DS1302_MONTH_WRITE, 0x12 ) ; //月v_DS1302WriteByte_f( DS1302_DAY_WRITE, 0x11 ) ; //日v_DS1302WriteByte_f( DS1302_HOUR_WRITE, 0x13 ) ; //小时v_DS1302WriteByte_f( DS1302_MINUTE_WRITE, 0x06 ) ; //分钟v_DS1302WriteByte_f( DS1302_SECOND_WRITE, 0x40 ) ; //秒v_DS1302WriteByte_f( 0x90, 0xa5 ) ; //充电v_DS1302WriteByte_f( 0xc0, 0xf0 ) ; //判断是否初始化一次标识写入v_DS1302WriteByte_f( 0x8e, 0x80 ) ; //禁止写操作}}/************************************************************** ***************** Function: void v_ClockUpdata_f( void ) ** Description:读取时间数据,并保存在结构体CurrentTime中** Parameter:** ** Return:**************************************************************** ***************/void v_ClockUpdata_f( void ){CurrentTime.Second =v_DS1302ReadByte_f( DS1302_SECOND_READ ) ;CurrentTime.Minute = v_DS1302ReadByte_f( DS1302_MINUTE_READ ) ;CurrentTime.Hour = v_DS1302ReadByte_f( DS1302_HOUR_READ ) ;CurrentTime.Day = v_DS1302ReadByte_f( DS1302_DAY_READ ) ;CurrentTime.Month = v_DS1302ReadByte_f( DS1302_MONTH_READ ) ;CurrentTime.Week = v_DS1302ReadByte_f( DS1302_WEEK_READ ) ;CurrentTime.Year = v_DS1302ReadByte_f( DS1302_YEAR_READ ) ;}有了上面的这些函数我们就可以对DS1302进行操作了。

51单片机实现基于DS1302_1602_18B20的多功能电子时钟_带测温功能

51单片机实现基于DS1302_1602_18B20的多功能电子时钟_带测温功能

#include<reg51.h>#define uchar unsigned char#define uint unsigned int/*------------------寄存器地址定义------------*/#define WRITE_SECOND 0x80#define WRITE_MINUTE 0x82#define WRITE_HOUR 0x84#define WRITE_DAY 0x86#define WRITE_MONTH 0x88#define WRITE_YEAR 0x8C#define WRITE_PROTECT 0x8E#define WRITE_WEEK 0x8A#define WRITE_CURRENT 0x90#define READ_SECOND 0x81#define READ_MINUTE 0x83#define READ_HOUR 0x85#define READ_DAY 0x87#define READ_MONTH 0x89#define READ_WEEK 0x8B#define READ_YEAR 0x8Dsbit RST=P3^5; //DS1302片选sbit DIO=P3^4; //DS1302数据信号sbit SCLK=P3^6; //DS1302时钟信号sbit ACC7=ACC^7;sbit ACC0=ACC^0;unsigned char count;sbit beep=P1^4;void INITIAL_1302();unsigned char READ_1302(unsigned char addr);void WRITE_1302(unsigned char addr,unsigned char date); sbit LCD_E=P2^7; //液晶使能端sbit LCD_RS=P2^6; //液晶数据命令选择端sbit LCD_RW=P2^5; //液晶读写选择端sbit key0=P3^2; //功能键sbit key1=P3^3; //增大键sbit key2=P3^4; //减小键sbit DQ=P3^7; //18b20温度输入输出端char hour,minute,second,week,day,month,year,tem; unsigned char num,flag;unsigned char str1[]=" 20 - - ";unsigned char str2[]=" : : C";void delay(unsigned char z);void LCD_WRITE_COM(unsigned char com);void LCD_WRITE_DA TA(unsigned char date);void LCD_WRITE_SFM(unsigned char addr,unsigned char date);void LCD_WRITE_NYR(unsigned char addr,unsigned char date);void LCD_WRITE_WEEK(unsigned char week);void LCD_INITIAL();void LCD_WRITE_TEMP(uchar addr,uchar temp);void keyscan();void INITIAL_TEMER0();uchar TMPH ,TMPL;void w1602c(uchar com);void w1602d(uchar data01);void delay2(uint ms);void delay3(uint us);uchar resert(void);uchar read_byte();void write_byte(uchar val);uint get_temp();void display();void delay3(uint us); //18b20uchar resert(void); //18b20uchar read_byte(); //18b20void write_byte(uchar val); //18b20uint get_temp(); //18b20void main(){LCD_INITIAL(); //液晶初始化INITIAL_1302(); //DS1302初始化INITIAL_TEMER0(); //定时器初始化while(1){keyscan(); //按键扫描if(flag==0) //当标志位为0,允许读取DS1302数据,将数据送入液晶显示{second=READ_1302(0x81);LCD_WRITE_SFM(10,second);minute=READ_1302(0x83);LCD_WRITE_SFM(7,minute);hour=READ_1302(0x85);LCD_WRITE_SFM(4,hour);week=READ_1302(0x8b);LCD_WRITE_WEEK(week);day=READ_1302(0x87);LCD_WRITE_NYR(9,day);month=READ_1302(0x89);LCD_WRITE_NYR(6,month);year=READ_1302(0x8d);LCD_WRITE_NYR(3,year);tem=get_temp();LCD_WRITE_TEMP(13,tem);}}}/**********************1602BU份******************************************************/void delay(unsigned char z) //1602de延时函数{unsigned char x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void LCD_WRITE_COM(unsigned char com){LCD_RS=0;LCD_RW=0;LCD_E=1;P0=com;delay(5);LCD_E=0;}void LCD_WRITE_DA TA(unsigned char date){LCD_RS=1;LCD_RW=0;LCD_E=1;P0=date;delay(5);LCD_E=0;}void LCD_WRITE_SFM(unsigned char addr,unsigned char date) {unsigned char shi,ge;shi=date/10;ge=date%10;LCD_WRITE_COM(0x80+0x40+addr);LCD_WRITE_DATA(0x30+shi);LCD_WRITE_DATA(0x30+ge);}void LCD_WRITE_NYR(unsigned char addr,unsigned char date) {char shi,ge;shi=date/10;ge=date%10;LCD_WRITE_COM(0x80+addr);LCD_WRITE_DATA(0x30+shi);LCD_WRITE_DATA(0x30+ge);}void LCD_WRITE_WEEK(unsigned char week){LCD_WRITE_COM(0x80+12);switch(week){case 1: LCD_WRITE_DA TA('M');delay(5);LCD_WRITE_DATA('O');delay(5);;LCD_WRITE_DATA('N');break;case 2: LCD_WRITE_DA TA('T');delay(5);LCD_WRITE_DATA('U');delay(5);LCD_WRITE_DATA('E');break;case 3: LCD_WRITE_DA TA('W');delay(5);LCD_WRITE_DATA('E');delay(5);LCD_WRITE_DATA('D');break;case 4: LCD_WRITE_DA TA('T');delay(5);LCD_WRITE_DATA('H');delay(5);LCD_WRITE_DATA('U');break;case 5: LCD_WRITE_DA TA('F');delay(5);LCD_WRITE_DATA('R');delay(5);LCD_WRITE_DATA('I');break;case 6: LCD_WRITE_DA TA('S');delay(5);LCD_WRITE_DATA('A');delay(5);LCD_WRITE_DATA('T');break;case 7: LCD_WRITE_DA TA('S');delay(5);LCD_WRITE_DATA('U');delay(5);LCD_WRITE_DATA('N');break;}}void LCD_WRITE_TEMP(uchar addr,uchar temp){char shi,ge;shi=temp/10;ge=temp%10;LCD_WRITE_COM(0x80+0x40+addr);LCD_WRITE_DATA(0x30+shi);LCD_WRITE_DATA(0x30+ge);}void LCD_INITIAL(){unsigned char i;LCD_WRITE_COM(0x38);LCD_WRITE_COM(0x0c);LCD_WRITE_COM(0x06); //经本人试验证明1602初始化不清屏也可实现LCD_WRITE_COM(0x80);for(i=0;i<16;i++){LCD_WRITE_DATA(str1[i]);delay(5);}LCD_WRITE_COM(0x80+0x40);//液晶第二行显示for(i=0;i<16;i++){LCD_WRITE_DATA(str2[i]);delay(5);}}/***************************1302部分***************************************************/void WRITE_1302(unsigned char addr,unsigned char date) {unsigned char i;RST=0;SCLK=0;RST=1;for(i=8;i>0;i--){SCLK=0;ACC=addr;DIO=ACC0;addr>>=1;SCLK=1;}for(i=8;i>0;i--){SCLK=0;ACC=date;DIO=ACC0;date>>=1;SCLK=1;}RST=0;}unsigned char READ_1302(unsigned char addr){unsigned char i,date1,date2;RST=0;SCLK=0;RST=1;for(i=8;i>0;i--){SCLK=0;ACC=addr;DIO=ACC0;addr>>=1;SCLK=1;}for(i=8;i>0;i--){ACC7=DIO;SCLK=1;ACC>>=1;SCLK=0;}RST=0;date1=ACC;date2=date1/16;date1=date1%16;date1=date1+date2*10;return(date1) ;}void INITIAL_1302(){WRITE_1302(WRITE_SECOND,READ_1302(READ_SECOND)&0x7f); //启动DS1302}/**************************键盘扫描部分***************************************************/void keyscan(){if(key0==0)//确认功能键按下{delay(20);if(key0==0)//去抖{while(!key0);//释放num++;switch(num){case 1: flag=1; //修改时间,禁止从DS1302读数据TR0=0; //定时器关LCD_WRITE_COM(0x0f); //光标开始闪烁LCD_WRITE_COM(0x80+3);//第一次按下,光标定位到年位置break;case 2: LCD_WRITE_COM(0x80+6);//第二次按下,光标定位到月位置break;case 3: LCD_WRITE_COM(0x80+9);//第三次按下,光标定位到日位置break;case 4: LCD_WRITE_COM(0x80+12);//第四次按下,光标定位到星期位置break;case 5: LCD_WRITE_COM(0x80+0x40+4);//第五次按下,光标定位到时位置break;case 6: LCD_WRITE_COM(0x80+0x40+7);//第六次按下,光标定位到分位置break;case 7: LCD_WRITE_COM(0x80+0x40+10);//第七次按下,光标定位到秒位置break;case 8: num=0;//第八次按下,记录清零LCD_WRITE_COM(0x0c);//不显示光标WRITE_1302(WRITE_PROTECT,0x00); //允许写操作WRITE_1302(0x80,(second/10*16)+second%10);//将调节后的秒写入DS1302WRITE_1302(0x82,(minute/10*16)+minute%10);//将调节后的分写入DS1302WRITE_1302(0x84,(hour/10*16)+hour%10);//将调节后的时写入DS1302WRITE_1302(0x8a,(week/10*16)+week%10);//将调节后的星期写入DS1302WRITE_1302(0x86,(day/10*16)+day%10);//将调节后的日写入DS1302WRITE_1302(0x88,(month/10*16)+month%10);//将调节后的月写入DS1302WRITE_1302(0x8c,(year/10*16)+year%10);//将调节后的年写入DS1302WRITE_1302(WRITE_PROTECT,0x80); //开写保护flag=0; //时间修改完毕,允许液晶从DS1302读数据TR0=1;break;}}}if(num!=0){if(key1==0)//确认增大键按下{delay(20);if(key1==0)//增大键确实按下{while(!key1);switch(num){case 1: year++;//调节年if(year==100)year=0;LCD_WRITE_NYR(3,year);//将调节后的年送入液晶显示LCD_WRITE_COM(0x80+3);//光标回到指定处break;case 2: month++;//调节月if(month==13)month=0;LCD_WRITE_NYR(6,month);//将调节后的月送入液晶显示LCD_WRITE_COM(0x80+6);//光标回到指定处break;case 3: day++;//调节日if(day==32)day=0;LCD_WRITE_NYR(9,day);//将调节后的日送入液晶显示LCD_WRITE_COM(0x80+9);//光标回到指定处break;case 4: week++;if(week==8)week=0;LCD_WRITE_WEEK(week);//将调节后的星期送入液晶显示LCD_WRITE_COM(0x80+12);//光标回到指定处break;case 5: hour++;if(hour==24)hour=0;LCD_WRITE_SFM(4,hour);//将调节后的小时送入液晶显示LCD_WRITE_COM(0x80+0x40+4);//光标回到指定处break;case 6: minute++;if(minute==60)minute=0;LCD_WRITE_SFM(7,minute);//将调节后的分送入液晶显示LCD_WRITE_COM(0x80+0x40+7);//光标回到指定处break;case 7: second++;if(second==60)second=0;LCD_WRITE_SFM(10,second);//将调节后的秒送入液晶显示LCD_WRITE_COM(0x80+0x40+10);//光标回到指定处break;default:break;}}}if(key2==0)//确认减小键按下{delay(20);if(key2==0)//减小键确实按下{while(!key2);switch(num){case 1: year--;//调节年if(year==-1)year=99;LCD_WRITE_NYR(3,year);LCD_WRITE_COM(0x80+3);break;case 2: month--;//调节月if(month==-1)month=12;LCD_WRITE_NYR(6,month);LCD_WRITE_COM(0x80+6);break;case 3: day--;//调节日if(day==-1)day=31;LCD_WRITE_NYR(9,day);LCD_WRITE_COM(0x80+9);break;case 4: week--;//调节星期if(week==0)week=7;LCD_WRITE_WEEK(week);LCD_WRITE_COM(0x80+12);break;case 5: hour--;//调节时if(hour==-1)hour=23;LCD_WRITE_SFM(4,hour);LCD_WRITE_COM(0x80+0x40+4);break;case 6: minute--;//调节分if(minute==-1)minute=59;LCD_WRITE_SFM(7,minute);LCD_WRITE_COM(0x80+0x40+7);break;case 7: second--;//调节秒if(second==-1)second=59;LCD_WRITE_SFM(10,second);LCD_WRITE_COM(0x80+0x40+10);break;default:break;}}}}}/*******************************蜂鸣器部分******************************************//*-----------定时器0初始化-------------------------*/void INITIAL_TEMER0(){TMOD=0x01;TH0=(65536-20000)/256;TL0=(65536-20000)%256; //晶振频率12MHZ 定时20ms作右TR0=1;EA=1;ET0=1;}/*-------------------------------------------*/void timer0()interrupt 1{TH0=(65536-20000)/256;TL0=(65536-20000)%256; //重装count++;if(count==50) //1秒到{count=0;beep=0; //蜂鸣器响delay(5);beep=1; //蜂鸣器灭}if(tem>=30){beep=0;}}/*****************************18b20部分*********************************************888*/void delay3(uint us){uint s;for(s=0;s<us;s++);}uchar resert(void){uchar ready;DQ=0;delay3(32) ;DQ=1;delay3(3);ready=DQ;delay3(25);return ready;}uchar read_byte(){uchar i,j;uchar value=0;for(i=0;i<8;i++){DQ=0;DQ=1;for(j=0;j<3;j++);if(DQ){value|=0x01<<i;}delay3(6) ;}return value;}void write_byte(uchar val) {uchar i,temp;for(i=0;i<8;i++){temp=val>>i;temp=temp&0x01;DQ=0;if(temp==1)DQ=1;delay3(5);DQ=1;}DQ=1;}uint get_temp(){float f_temp;uint temp;P2=0x00;resert();delay3(50);write_byte(0xcc);write_byte(0x44);resert();write_byte(0xcc);write_byte(0xbe);TMPL = read_byte();TMPH = read_byte();temp = TMPH;temp <<= 8;TMPL=TMPL&0xf0;temp = temp | TMPL;f_temp=temp*0.0625;temp=f_temp;return temp;}。

51+DS1302+DS18B20+LCD1602,显示时间,温度,可调时

51+DS1302+DS18B20+LCD1602,显示时间,温度,可调时

实时时钟芯片DS1302应用,DS18B20应用实例——可调时钟,LCD1602显示:(时间+温度)说明:需要按程序中定义的接口。

按自己接口,只要在程序中修改接口定义即可。

1、DS1302引脚排列:如下图引脚说明:1)Vcc1:后备电源,VCC2:主电源。

在主电源关闭的情况下,也能保持时钟的连续运行。

DS1302由Vcc1或Vcc2两者中的较大者供电。

当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电。

当Vcc2小于Vcc1时,DS1302由Vcc1供电。

2)X1、X2:振荡源,外接32.768kHz晶振。

3)RST:复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。

RST输入有两种功能:首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。

当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。

如果在传送过程中RST 置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。

上电运行时,在Vcc>2.0V之前,RST必须保持低电平。

只有在SCLK 为低电平时,才能将RST置为高电平。

4)I/O为串行数据输入输出端(双向)。

5)SCLK为时钟输入端。

2、 DS1302的控制字节DS1302 的控制字如下图所示。

控制字节的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1指示操作单元的地址;最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出。

3、数据输入输出(I/O)在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。

同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。

时钟DS1302在液晶1602显示程序

时钟DS1302在液晶1602显示程序

#include <reg52.h>#define uchar unsigned char#define uint unsigned intuchar code table[]="ziye334"; uchar code table1[]="0123456789"; uchar code table2[]="DAY-";sbit rs=P2^5;sbit rw=P2^6;sbit en=P2^7;sbit rst=P1^7;sbit io=P3^5;sbit clk=P1^6;sbit ACC0=ACC^0;sbit ACC7=ACC^7;sbit key1=P1^0;sbit key2=P1^1;sbit key3=P1^2;sbit key4=P1^3;sbit key5=P1^4;uchar num;uchar t_sec,sec1,sec2;uchar t_min,min1,min2;uchar t_hr,hr1,hr2;uchar t_mon,mon1,mon2; uchar t_date,date1,date2; uchar t_year,year1,year2; uchar t_day,day1,flag;void input_1byte(uchar TD) {uchar i;ACC=TD;for(i=8;i>0;i--){io=ACC0;clk=1;clk=0;ACC=ACC>>1;}}uchar output_1byte(void) {uchar i;for(i=8;i>0;i--){ACC=ACC>>1;ACC7=io;clk=1;clk=0;}return(ACC);}void write_ds1302(uchar add,uchar dat) {rst=0;clk=0;rst=1;input_1byte(add);input_1byte(dat);clk=1;rst=0;}uchar read_ds1302(uchar add){uchar inf;rst=0;clk=0;input_1byte(add);inf=output_1byte();clk=1;rst=0;return(inf);}void delay(uchar z) //延时{uint x,y;for(x=110;x>0;x--)for(y=z;z>0;z--);}void write_com(uchar com) //写指令{rs=0;rw=0;en=0;P0=com;delay(5);en=1;delay(5);}void write_date(uchar date) //写数据{rs=1;rw=0;en=0;P0=date;delay(5);en=1;delay(5);en=0;}void init_lcd(){en=0;write_com(0x38); //显示write_com(0x0c); //光标不显示write_com(0x06); //指针加1,整屏不移动write_com(0x01); //清屏write_com(0x80);}void init_1302(){write_ds1302(0x8e,0x00);//关闭写保护write_ds1302(0x90,0xaa); //定义充电write_ds1302(0x80,0x30); //秒write_ds1302(0x82,0x59);//分write_ds1302(0x84,0x23);//时write_ds1302(0x86,0x31);//日write_ds1302(0x88,0x12);//月write_ds1302(0x8a,0x04);//星期write_ds1302(0x8c,0x11);//年write_ds1302(0x8e,0x80);//打开写保护}void display(){t_sec=read_ds1302(0x81);sec1=t_sec&0x0f;sec2=(t_sec>>4);t_min=read_ds1302(0x83);min1=t_min&0x0f;min2=(t_min>>4);t_hr=read_ds1302(0x85); hr1=t_hr&0x0f;hr2=(t_hr>>4);t_date=read_ds1302(0x87); date1=t_date&0x0f;date2=(t_date>>4);t_mon=read_ds1302(0x89); mon1=t_mon&0x0f;mon2=(t_mon>>4);t_day=read_ds1302(0x8b); day1=t_day&0x0f;t_year=read_ds1302(0x8d); year1=t_year&0x0f;year2=(t_year>>4);write_com(0x80+0x4e);write_date(table1[sec2]); write_com(0x80+0x4f); write_date(table1[sec1]); write_com(0x80+0x4d); write_date(':');write_com(0x80+0x4c); write_date(table1[min1]); write_com(0x80+0x4b); write_date(table1[min2]); write_com(0x80+0x4a); write_date(':');write_com(0x80+0x49); write_date(table1[hr1]); write_com(0x80+0x48); write_date(table1[hr2]);write_com(0x80+0x0f); write_date(table1[date1]); write_com(0x80+0x0e); write_date(table1[date2]);write_com(0x80+0x0d);write_date('/');write_com(0x80+0x0c);write_date(table1[mon1]);write_com(0x80+0x0b);write_date(table1[mon2]);write_com(0x80+0x0a);write_date('/');write_com(0x80+0x09);write_date(table1[year1]);write_com(0x80+0x08);write_date(table1[year2]);write_com(0x80+0x40+5);write_date(table1[day1]); }void main(){init_lcd();delay(5);init_1302();delay(5);for(num=0;num<7;num++) {write_date(table[num]);delay(10);}write_com(0x80+0x41);for(num=0;num<4;num++) {write_date(table2[num]);delay(10);}while(1){if(flag==0){display();}}}。

51单片机+ds1302+DS18b20温度时钟(电路图+C语言程序)

51单片机+ds1302+DS18b20温度时钟(电路图+C语言程序)

时钟电路图:*■11PCB板:酱时井務ft是用诵m-pdfMerisi 口叵因Fjr 齐舱 C :s ® 工细理沖缶皿ndm - * TfS ' 4' 包田U i > 'ir ft ZS:MZ fH钟些fl是用说町-Pdf Wirrcf闻礒雜sbit dis_ bitlsbit dis_ bit2sbit dis_ bit3sbit dis_ bit4sbit dis_ bit5sbit dis_ bit6sbit ledl _bitsbit led2 ! bit=P2A7; II定义数码管控制口=P2A6; II定义数码管控制口=卩2八4; II定义数码管控制口=卩2八3; II定义数码管控制口=P2A1; II定义数码管控制口=P2A0; II定义数码管控制口=P2A2; II定时LED勺控制口=P2A5; II定时LED勺控制口单片机程序:/*===================================================================调试要求:1. MCU:AT89S52 芯片或AT89C522. 晶振:12MHz功能:多功能时钟+温度计/#inelude <reg52. h>#inelude vintrins . h>訂开始 LJ-雲匕®务如1痒3月计ttVl. •呈T』d"吐拠席射■ w耳pg文宇■[豹…SS时軽件思冃说#define uehar #define uint unsigned char unsigned intsbit s1_bit =P1A 0; // 定义S1 控制口 sbit s2_bit =P01; // 定义 S2控制口 sbit s3_bit =P02; // 定义 S3控制口 sbit dq_ds18b20 =P3A3;// 定义控制 DS18B20 sbit speak =P3A7; //定义蜂鸣器控制口sbit clk_ds1302 =P3A6; // 定义控制 DS1302勺时钟线 sbit io_ds1302 =P3A5;//定义控制DS1302勺串行数据 sbit rest_ds1302 =P3A4;#define smg_data P0 //定义数码管数据口void delay_3us(); //3US 的延时程序 void delay_8us(ui nt t);//8US 延时基准程序void delay_50us(ui nt t); //void display1(uchar dis_data); void display2(uchar dis_data); void display3(uchar dis_data); void display4(uchar dis_data); void display5(uchar dis_data); void display6(uchar dis_data);void init_t0(); //定时器0初始化函数 void dis_led(); //LED 处理函数 void judge_s1(); //S1 按键处理函数void judge_s2(); //S2 按键处理函数 void judge_s3(); //S3 按键处理函数void dis(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1); 示子程序 void dis_sa n( uchar s6,uchar s5,uchar s4,uchar s3,uchar s1,uchar san); 〃闪烁显示子程序 void judge_dis(); //显示处理函数 void judge_clock(); // 显示处理函数 void set_ds1302(); // 设置时间void get_ds1302();// 读取当前时间void w_1byte_ds1302(uchar t); // 向 DS130写一个字节的数据 uchar r_1byte_ds1302(); // 从DS130读一个字节的数据//DS18B20测温函数定义延时50*T 微妙函数的声明//数码管1显示子程序 //数码管2显示子程序 //数码管3显示子程序 //数码管4显示子程序 //数码管5显示子程序 //数码管6显示子程序//显 s2,ucharvoid w_1byte_ds18b20(uchar value); // 向DS18B2写一个字节ucharr_1byte_ds18b20( void ); // 从DS18B2读取一个字节的数据voidrest_ds18b20( void ); //DS18B20复位程序void readtemp_ds18b20( void ); // 读取温度void dis_temp(); //温度显示函数//共阳数码管断码表const uchar tabl1[16] ={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,// 0 1 2 3 4 50x82,0xf8,0x80,0x90,0x86,0x87,0xFF,//6 7 8 9 E T B0xc6,0xbf,0xff };// C -const uchar tabl3[] ={ 0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09 };uchar t0_crycle;uchar hour_co un t, minu te_c oun t,sec on d_co un t,msec ond_count;uchar clock_hour,clock_m inu te;uchar coun tdow n_sec ond;uchar coun tdow n_hour,co un tdow n_min ute;uchar clock_en; //闹钟关闭和开启的标志,1开启,0关闭uchar flag1,sec on d_flag,za ncun 1,za ncun 2,za ncun3;uchar zancun4 ,za ncun 5,za ncun 6,za ncun7;uchar clock_flag,co un tdow n_flag;uchar msec on d_mi nute,msec on d_sec on d,mseco nd_mseco nd,mseco nd_flag; // 秒表相关参数uint speak_c ount;uchar templ,temph,temp_flag;uchar t_b,t_s,t_g,t_x,temp_flag2; //从左到右分别存储温度百位,十位,个位,小数位uchar tab23[3]; 〃二{0x40,0x59,0x23,0x28,0x11,0x06,0x09};// 上电时默认的时间//主程序void main(){P3 =0x00;flag1 =0;zancun3 =0;msecond_minute =0; //置秒表相关参数为0msecond_second =0;msec on d_msec ond =0;speak =1;//关闭蜂鸣器speak_co unt =0;clock_hour =0;clock_m inute =0;clock_flag =0;countdown_flag =0; //倒计时标志位为0clock_en =0;//开机时默认关闭闹钟ini t_t0();TRO =1;//// set_ds1302();〃设置DS1302勺初始时间//接下来开始编写让数码管显示的程序while (1){get_ds1302();judge_dis(); // 显示处理judge_s1();judge_s2();judge_s3();judge_clock(); //闹钟处理程序} _}void timerO() interrupt 1{TH0=(65536-50000)/256;TL0=(65536 - 50000)%256; t0_crycle ++;if (t0_crycle ==2) // 0.1 秒{t0_crycle =0;msec on d_flag =1;msec ond_count ++;if (msecond_count==10)//1 秒{ _msec on d_co unt =0;sec on d_flag =1;}}}//**************************************************//显示处理函数void judge_dis(){if (flag1 ==0){if (second_flag ==1){ _zancun7 ++;sec on d_flag =0;} _if (zancun7 <1){if (temp_flag2 ==1){ 一readtemp_ds18b20(); // 读取温度temp_flag2 =0;厂dis_temp(); //温度显示函数}if (zancun7 >=1){temp_flag2 =1;zancun4 =hour_count &0xf0;zancun4 >>=4;zancun5 =minute_count&0xf0;zancun5 >>=4;zancun6 =sec on d_co unt&0xf0;zancun6 >>=4;dis(za ncun4 ,hour_co unt &0x0f,za ncun5,minu te_co unt &0x0f,za ncun 6,sec ond_ cou nt &0x0f);dis_led();if (zancun7 ==5)zancun7 =0;}}if (flag1 !=0){switch (flag1){case 1:dis(5,10,11,1,12,12); // 显示SET1led1_bit =1;led2_bit =1;break;case 2:dis(5,10,11,2,12,12); // 显示SET2break;case 3:dis(5,10,11,3,12,12); // 显示SET3break;case 4:dis(5,10,11,4,12,12); // 显示SET4break;case 5:dis(5,10,11,5,12,12); // 显示SET5break;case 6:dis_san(zancun1 / 10,zancunl %10,zancun2/ 10,zancun2 %0,12,12,1); break;case 7:dis_san(zancun1 / 10,zancunl %10,zancun2/ 10,zancun2 %0,12,12,2); break;case 8:dis_san(zancun1 / 10,zancunl %10,zancun2/ 10,zancun2 %0,12,12,3); break;case 9: //进入修改时间,时间分位个位闪烁dis_san(zancun1 / 10,zancunl %10,zancun2/ 10,zancun2 %0,12,12,4); break;case 10: //进入修改闹钟,闹钟小时十位闪烁dis_san(zancunl / 10,zancunl %10,zancun2/ 10,zancun2 %0,12,zancun3,1); break;case 11://进入修改闹钟,闹钟小时个位闪烁dis_san(zancun1 / 10,zancunl %10,zancun2/ 10,zancun2%0,12,zancun3,2); break;case 12: //进入修改闹钟,闹钟小时十位闪烁dis_sa n(zan cu n1 / 10,za ncun1 %10,za ncun 2/ 10,za ncu n2%0,12,za ncun 3,3);break;case 13: //进入修改闹钟,闹钟小时个位闪烁dis_sa n(zan cu n1 / 10,za ncun1 %10,za ncun 2/ 10,za ncu n2%0,12,za ncun 3,4);break;case 14: //进入修改闹钟的开关dis_sa n(zan cu n1 / 10,za ncun1 %10,za ncun 2/ 10,za ncu n2%0,12,za ncun 3,6);break;case 15:dis_sa n(zancun1 / 10,za ncun1 %10,za ncun 2/ 10,za ncun 2%0,za ncun3/ 10,za ncun 3%10,1);break;case 16:dis_san(zancun1 / 10,zancunl %10,zancun2/10,zancun2%0,zancun3/ 10,zancun3%10,2);break;case 17:dis_san(zancun1 / 10,zancunl %10,zancun2/ 10,zancun2%0,zancun3/ 10,zancun 3%10,3);break;case 18:dis_sa n(zancun1 / 10,za ncun1 %10,za ncun 2/ 10,za ncun 2%0,za ncun3/ 10,za ncun 3%10,4);break;case 19:dis_sa n(zancun1 / 10,za ncun1 %10,za ncun 2/ 10,za ncun 2%0,za ncun3/ 10,za ncun 3%10,5);break;case 20:dis_sa n(zancun1 / 10,za ncun1 %10,za ncun 2/ 10,za ncun 2%0,za ncun3/ 10,za ncun 3%10,6);break;case 21:if (second_flag ==1){ _sec on d_flag =0;countdown_second --;if (countdown_second ==255){ _coun tdow n_sec ond =59;countdown_minute --;if (countdown_minute ==255){ _coun tdow n_min ute =59;countdown_hour --;if (countdown_hour ==255){flag1 =22;coun tdow n_min ute =0;coun tdow n_hour =0;coun tdow n_sec ond =0;coun tdow n_flag=1;_ } } } }dis(countdown_hour / 10,countdown_hour %10,countdown_minute / 10,countdown _minute%10,countdown_second/ 10,countdown_second%10); //break; case 22:{ speak =1;}dis(countdown_hour / 10,countdown_hour %10,countdown_minute / 10,countdown _minute%10,countdown_second/ 10,countdown_second%10); //break; case 23: dis(msecond_minute / 10,msecond_minute%10,msecond_second/ 10,msecond_sec on d%10,mseco nd_msec on d%0,12);break; case 24:if (msecond_flag ==1) { _msec on d_flag =0; msec on d_msec ond ++;if (msecond_msecon (==10){msec on d_msec ond =0; msec on d_sec ond ++;if (msecond_second==60) { _msecond_second =0; msec ond_minute ++;if (countdown_flag { _speak=0;if (second_flag { _sec on d_flag coun tdow n_flag} _ } else>0 &&countdown_flag <7)==1) =0; ++;if (msecond_minute==1OO) { _msec ond_minute =99;flagl =23;}}}}dis(msecond_minute / 10,msecond_minute%10,msecond_second/ 10,msecond_sec on d%10,mseco nd_msec on d%0,12);break;case 25:dis(zancun3 / 10,zancun3 %0,zancun2 / 10,zancun2 %10,zancun1 /10,zancun1 %0 );break;default :break;}}}//**************************************************〃S1按键处理函数void judge_s1(){ _s1_bit =1;//置IO为1,准备读入收据if (s1_bit ==0)//判断是否有按键按下{delay_50us(1); //延时,去除机械抖动if (s1_bit ==0){switch (flag1){case 0:case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 10:case 11:case 12:case 13:case 15:case 16:case 17:case 18:case 19: flag1++;break;case 9: flag1=6;break;case 14: flag1=10;break;case 20: flag1=15;break;case 5:case 21:case 22:case 23: //系统从秒表状态复位case 24: //系统从秒表状态复位case 25: //系统从计数器复位flag1 =0;break;default :break;}while (s1_bit ==0){ _judge_dis();}〃等待按键释放}}}〃************************************************** 〃S2按键处理函数void judge_s2(){ _s2_bit =1; //置IO为1,准备读入收据if (s2_bit ==0)//判断是否有按键按下=0;{delay_50us(1); //延时,去除机械抖动 if (s2_bit ==0) { switch (flagl) { flag1 =6; zancun4 =hour_count &0xf0;zancun4 >>=4; zancun6 =hour_count &0x0f;zancun1=zancun4*10+zancun6; //zancun 1=hour_co unt; zancun5 =minute_count &0xf0; zancun5 >>=4; zancun6 =minute_count &0x0f; zancun2 =za ncun5* 10+za ncun6; case 1: //在显示SET 状态下按S2牛,进入修改时间 // zancun2=minu te_co unt; break; case 2: //在显示SET2犬态下按S2,进入设置闹钟 zancunl =clock_hour; zancun2 =clock_m inu te; flagl =10; break; case 6: //修改时钟小时十位状态下按 case 7: //修改时钟小时个位状态下按 case 8: //修改时钟分钟十位状态下按 case 9: //修改时钟分钟个位状态下按 〃zancun4=za ncun 1/10; 测S:SM tab23[2] =zancun1/10* 16+za ncu n1%10; tab23[1] hour_c ount minu te_c ount sec ond_co unt tab23[0]set_ds1302(); flag1//zancun 5=za ncun2&0 xf0; //zancun 5>>=4; =zancun2/10* 16+za ncu n2%10; =tab23[2]; =tab23[1]; =0; //设置DS130的初始时间 =0;break; case 10: //修改闹钟小时十位状态下按S2case 11: //修改闹钟小时个位状态下按S2case 12: //修改闹钟分钟十位状态下按S2 case 13: //修改闹钟分钟个位状态下按S2 case 14: //修改闹钟使能状态下按S2clock_hour clock_m inute clock_e n flag1=zancun1; =zancun2; =zancun3;=0;break;case 3:flagl =15;zancunl =co un tdow n_hour;zancun2 =co un tdow n_minu te;zancun3 =co un tdow n_sec ond;break;case 15:case 16:case 17:case 18:case 19:case 20:coun tdow n_hour =zancun1;coun tdow n_minute =za ncun2;coun tdow n_sec ond =za ncun3;flag1 =21;coun tdow n_flag =0;break;case 22:flag1 =21;break;case 21:flag1 =22;break;case 4:flag1 =23; //秒表暂停msec ond_minute =0;msecond_second =0;msec on d_msec ond =0;break;case 23:flag1 =24;break;case 24:flag1 =23;break;case 5:flagl =25;//进入计数器模式zancunl =0;zancun2 =0;zancun3 =0;break; default :break;}while (s2_bit ==0){ _judge_dis();}//等待按键释放}}}//**************************************************//S3按键处理函数void judge_s3(){ _s3_bit =1;//置IO为1,准备读入收据if (s3_bit ==0)//判断是否有按键按下{delay_50us(1); //延时,去除机械抖动if (s3_bit ==0){ _switch (flag1){case 6: //修改时间小时的十位数zancun1 +=10;if (zancun1 >=24)zancun1 =zancun 1%10;break;case 7: //修改时间小时的个位数za ncun1 =za ncu n1/10* 10+(za ncun1 %10+1) %10;if (zancun1 >=24)zancun1 =20;break;case 8: //修改时间分钟的十位数zancun2 +=10;if (zancun2 >=60)zancun2-=60;break;case 9: //修改时间分钟的个位数za ncun2 =za ncun2/10* 10+(za ncun2 %10+1) %10;break;case 10: //修改闹钟小时的十位数zancunl +=10;if (zancunl >=24)zancunl =zancun 1%10; break;case 11: //修改闹钟小时的个位数zancunl =za ncu n1/10* 10+(za ncun1 %10+1) %10;if (zancun1 >=24)zancun1 =20;break;case 12: //修改闹钟分钟的十位数zancun2 +=10;if (zancun2 >=60)zancun2-=60; break;case 13: //修改闹钟分钟的个位数zan cu n2 =za ncun2/10* 10+(za ncun2 %10+1) %10;break;case 14:zancun3 A=1;break;case 15: //修改倒计时小时的十位数zancun1 +=10;if (zancun1 >=100)zancun 1 -=100; break;case 16: //修改倒计时小时的个位数zancun1 =za ncu n1/10* 10+(za ncun1 %10+1) %10;break;case 17: //修改倒计时分钟的十位数zancun2 +=10;if (zancun2 >=60)zancun2-=60; break;case 18: //修改倒计时分钟的个位数zan cu n2 =za ncun2/10* 10+(za ncun2 %10+1) %10;break;case 19: //修改倒计时秒的十位数zancun3 +=10;if (zancun3 >=60)zancun3-=60; break;case 20: //修改倒计时秒的个位数zan cu n3 =za ncun3/10* 10+(za ncun3 %10+1) %10;break;case 21:case 22: //coun tdow n_hour =zancun1;coun tdow n_minute =za ncun2;coun tdow n_sec ond =za ncun3;flagl =21;break;case 23:case 24: //秒表复位flag1 =24;msec ond_minute =0;msecond_second =0;msec on d_msec ond =0;break;case 25:zancun1 ++;if (zancun1 ==100){zancun1 =0;zancun2 ++;if (zancun2 ==100){zancun2 =0;zancun3 ++;}}break;default : break;}while (s3_bit ==0){ _judge_dis();}〃等待按键释放}}} //显示处理函数void judge_clock() {zancun4 =hour_count &0xf0;zancun4 >>=4;zancun6 =hour_count &0x0f;zancun4 *=10;zancun4 +=za ncun6;zancun5=minute_count &0xf0;if (san ==1){zancun5 >>=4;zancun6 =minute_count &0x0f;zancun5 *=10;zancun5 +=za ncun6;if (msecond_count<=5) {speak =0; speak_co unt ++;}else{speak =1;}}else{speak =1;}}〃****************************************////闪烁显示子程序void dis_sa n( uchar s6,uchar s5,uchar s4,uchar s3,uchars1,uchar san){if (clock_hour ==zancun4 &&clock_minute ==zancun5){ 一 一if (clock_en { _ speak_co unt clock_flag speak_co unt} _ } else{clock_flag =0;} _if{ (clock_flag ==1 ==1&&clock_flag ==0)=0; //开启蜂鸣器=1;=0;&&speak_count <400)s2,ucharif (msecond_count<5) { _ display1(s6);}}else{display1(s6);}if (san ==2){if (msecond_count<5) { _ display2(s5);}}else{display2(s5);}if (san ==3){if (msecond_count<5) { _ display3(s4);}}else{display3(s4);}if (san ==4){if (msecond_count<5) { _ display4(s3);}}else{display4(s3);}if (san ==5){if (msecond_count<5){ _ display5(s2);}}else{display5(s2);}if (san ==6){if (msecond_count<5){ _ display6(s1);}}else{ display6(s1);}}〃****************************************//时钟显示程序void dis(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1) { display1(s6);display2(s5);display3(s4);display4(s3);display5(s2);display6(s1);}〃********************************************************************************************void init_tO(){ _TMOD0x01;〃设定定时器工作方式1,定时器定时50毫秒TH0=(65536-50000)/256;TL0=(65536- 50000)%256;EA=1; //开总中断ET0=1; //允许定时器0中断t0_crycle =0; //定时器中断次数计数单元}//LED处理函数void dis_led(){if (msecond_count<5){ _Ied1_bit =1;Ied2_bit =1;}else{led1_bit =0;led2_bit =0;}}〃***************************************************************//功能:把数据1显示在数码管1上void display6(uchar dis_data){ _smg_data =tabl1[dis_data]; // 送显示断码dis_bit6 =0; // 锁存数据delay_50us(40); dis_bit6 =1;}〃***************************************************************//功能:把数据1显示在数码管1上void display5(uchar dis_data){ _smg_data =tabl1[dis_data]; // 送显示断码dis_bit5 =0; // 锁存数据delay_50us(40);dis_bit5 =1;} _〃***************************************************************//功能:把数据1显示在数码管1上void display4(uchar dis_data){ _smg_data =tabl1[dis_data]; // 送显示断码dis_bit4 =0; // 锁存数据delay_50us(40);dis_bit4 =1;} 〃***************************************************************//功能:把数据1显示在数码管1上void display3(uchar dis_data){ _smg_data =tabl1[dis_data]; // 送显示断码dis_bit3 =0; // 锁存数据delay_50us(40);dis_bit3 =1;}〃***************************************************************//功能:把数据1显示在数码管1上void display1(uchar dis_data){ _smg_data =tabl1[dis_data]; // 送显示断码dis_bit1 =0; // 锁存数据delay_50us(40);dis_bit1 =1;}〃***************************************************************//功能:把数据1显示在数码管1上void display2(uchar dis_data){ _smg_data =tabl1[dis_data]; // 送显示断码dis_bit2 =0; // 锁存数据delay_50us(40);dis_bit2 =1;}〃******************************************************************* *******************************// 函数名称:void delay_50US(unsigned int t)//功能:延时50*t(us)void delay_50us(uint t){ _unsigned char j;for (;t >0;t --){for (j =19;j >0;j --);}}〃******************************************************************* ************〃8微秒延时基准程序void delay_8us(uint t){while (-- t);}************〃3微秒延时程序void delay_3us() {}〃******************************************************************* ************//子程序功能:向DS18B2写一字节的数据void w_1byte_ds18b20(uchar value){uchar i =0;for (i =0;i <8;i ++){dq_ds18b20 =1;delay_3us();dq_ds18b20 =0; delay_8us(2);if ( value & 0x01) dq_ds18b20 =1; 〃DQ = 1 delay_50us(1); // 延时50us 以上delay_8us(2);value >>=1;}dq_ds18b20 =1; //DQ = 1}//读一个字节uchar r_1byte_ds18b20( void){ 一一uchar i =0;uchar value = 0;for (i =0;i <8;i ++){value >>=1;dq_ds18b20 =0;// DQ_L;delay_3us();dq_ds18b20 =1; 〃DQ_H;delay_8us(2);if (dq_ds18b20==1) value |= 0x80;delay_8us(6); // 延时40us}dq_ds18b20 =1;return value ;}11 ・**************************************************〃ds18b20复位子程序void rest_ds18b20( void){rest:delay_3us(); // 稍做延时delay_3us();dq_ds18b20 =1;delay_3us();dq_ds18b20 =0;// DQ_L; delay_50us(11); 〃480us<T<960usdq_ds18b20 =1; // 拉高总线delay_8us(5);if (dq_ds18b20==1){return ;}delay_50us(2); // 延时90usif (dq_ds18b20==1){return ;}else{goto rest;}}〃****************************************************//读取温度void readtemp_ds18b20( void){ _uchar temp32;rest_ds18b20();w_1byte_ds18b20(0xcc); //跳过读序列号的操作w_1byte_ds18b20(0x44); // 启动温度转换delay_8us(2);rest_ds18b20();w_1byte_ds18b20(0xcc); //跳过读序列号的操作w_1byte_ds18b20(0xbe); //读取温度寄存器等(共可读9个寄存器)前两个就是温度templ =r_1byte_ds18b20();temph =r_1byte_ds18b20();if ((temph &0xf0)) //判断温度的正负性{temp_flag =0; //温度为负数标志temph =-temph;tempi =-templ;t_x =tabl3[templ & OxOf]; // 计算温度的小数temp32 =temph & OxOf;temp32 <<=4;tempi >>=4;temp32 =temp32 | tempi;t_b =temp32/100%10; //计算温度的百位数据t_s =temp32/10%0;〃计算温度的十位数据t_g =temp32%0;〃计算温度的个位数据5else //为正数{t_x =tabl3[templ & 0x0f]; // 计算温度的小数temp32 =temph & 0x0f;temp32 <<=4;templ >>=4;temp32 =temp32 | templ;t_b =temp32/100%10; //计算温度的百位数据t_s =temp32/10%0;〃计算温度的十位数据t_g =temp32%0;〃计算温度的个位数据temp_flag =1;} _}void dis_temp() //温度显示函数{ _if (temp_flag =1){ _if (t_b ==0){dis(12,12,t_s,t_g,13,12);}else{dis(12,t_b,t_s,t_g,13,12);}}else{dis(14,t_b,t_s,t_g,13,12);}}/ / """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" / / , ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ############ //;子程序名:w_1byte_ds1302//;功能:向DS130写一个字节的数据void w_1byte_ds1302(uchar t){uchar i;for (i =0;i <8;i ++){if (t & 0x01){io_ds1302=1;}else{io_ds1302 =0;}clk_ds1302 =1;delay_3us();delay_3us();clk_ds1302 =0;delay_3us();delay_3us();t >>=1;}}/ / , ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ######//;子程序名:r_1byte_ds1302()//;功能:从DS130读一个字节的数据uchar r_1byte_ds1302(){ 一一uchar i,temp11 =0;io_ds1302 =1;//置10为1,准备读入数据for (i =0;i <8;i ++){temp11 >>=1;if (io_ds1302) temp11 |= 0x80;clk_ds1302 =1;delay_3us();delay_3us();clk_ds1302 =0;delay_3us();}return (temp11);}/ / """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""/ / , JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ """""""""""""""ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff//;子程序名:setbds1302//;功能:设置DS130初始时间,并启动计时void set_ds1302(){uchar i,j;rest_ds1302 =0;delay_3us();clk_ds1302 =0;delay_3us();rest_ds1302 =1;delay_3us();w_1byte_ds1302(0x8e); // 写控制命令字delay_3us();w_1byte_ds1302(0x00); // 写保护关闭clk_ds1302 =1;delay_3us();for (i =0,j =0x80;i <7;i ++,j +=2){rest_ds1302 =0;delay_3us();clk_ds1302 =0;delay_3us();rest_ds1302 =1;delay_3us();w_1byte_ds1302(j);delay_3us();w_1byte_ds1302(tab23[i]);delay_3us();delay_3us();clk_ds1302 =1;delay_3us();rest_ds1302 =0;delay_3us();delay_3us();} _rest_ds1302 =0;delay_3us();clk_ds1302 =0;delay_3us();rest_ds1302 =1;delay_3us();w_1byte_ds1302(0x8e); delay_3us();w_1byte_ds1302(0x80); clk_ds1302 =1;delay_3us();rest_ds1302 =0;delay_3us();}/ / """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" / / , ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff //;子程序名:get1302void get_ds1302(){ _uchar temp11[7],i,j;for (i =0;i <7;i ++){temp11[i] =0;}for (i =0,j =0x81;i <7;i ++,j +=2){rest_ds1302 =0;delay_3us();clk_ds1302 =0;delay_3us();delay_3us();w_1byte_ds1302(j);temp11[i] =r_1byte_ds1302();delay_3us();clk_ds1302 =1;delay_3us();rest_ds1302 =0;delay_3us();} _if (temp11[0] != 0xff){second_count =temp11[0]; }if (temp11[1] != 0xff) // 数据验证{minute_count =temp11[1]; }if (temp11[2] != 0xff) // 数据验证{hour_count =temp11[2]; }// date=temp[3];//mon th=temp[4];// week=temp[5];//year=temp[6];}/*===================================================================调试要求:1. MCU:AT89S52 芯片或AT89C522. 晶振:12MHz功能:多功能时钟+温度计/#inelude <reg52. h>#inelude vintrins . h>sbit dis_bit1 =P2A 7; //定义数码管控制口sbit dis_bit2 =卩2八6;//定义数码管控制口sbit dis_bit3 =卩2八4;//定义数码管控制口sbit dis_bit4 =卩2八3;//定义数码管控制口sbit dis_bit5 =卩2八1; //定义数码管控制口sbit dis_bit6 =P2A0; //定义数码管控制口sbit led1_bit =卩2八2; // 定时 LED 勺控制口sbit led2_bit =卩2八5; // 定时 LED 勺控制口sbit s1_bit =P1A0; // 定义S1 控制口sbit s2_bit =P01; // 定义 S2空制口sbit s3_bit =P02; // 定义 S3控制口sbit dq_ds18b20 =P3A3;// 定义控制 DS18B20 sbit speak =P3A7; //定义蜂鸣器控制口sbit clk_ds1302 =P3A6; // 定义控制 DS1302勺时钟线 sbit io_ds1302 =P3A5;//定义控制DS1302勺串行数据sbit rest_ds1302 =P3A4;#define smg_data P0 //定义数码管数据口 void delay_3us(); //3US 的延时程序 void delay_8us(ui nt t); //8US 延时基准程序void delay_50us(ui nt t); // void display1(uehardis_data); voiddisplay2(uehar dis_data); void display3(uehar dis_data); void display4(uehar dis_data); void display5(uehar dis_data); void display6(uehar dis_data);void init_t0(); //定时器0初始化函数void dis_led(); //LED 处理函数void judge_s1();//S1 按键处理函数 void judge_s2(); //S2 按键处理函数void judge_s3(); //S3 按键处理函数 void dis(uehar s6,uehar s5,uehar s4,uehar s3,uehar s2,uehar s1); 示子程序 void dis_sa n( uchar s6,uehar s5,uehar s4,uehar s3,uehars1,uchar san); 〃闪烁显示子程序void judge_dis(); //显示处理函数void judge_clock(); // 显示处理函数void set_ds1302(); // 设置时间void get_ds1302(); // 读取当前时间#define uehar#define uintunsigned char unsigned int延时50*T 微妙函数的声明//数码管1显示子程序 //数码管2显示子程序 //数码管3显示子程序//数码管4显示子程序//数码管5显示子程序//数码管6显示子程序 //显s2,ueharvoid w_1byte_ds1302(uchar t); // 向DS130写一个字节的数据uchar r_1byte_ds1302(); // 从DS130读一个字节的数据〃*******************************************************************//DS18B20测温函数定义void w_1byte_ds18b20(uchar value); // 向DS18B2写一个字节ucharr_1byte_ds18b20( void ); // 从DS18B2读取一个字节的数据voidrest_ds18b20( void ); //DS18B20复位程序void readtemp_ds18b20( void ); // 读取温度void dis_temp(); //温度显示函数//共阳数码管断码表const uchar tabl1[16] ={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,// 0 1 2 3 4 50x82,0xf8,0x80,0x90,0x86,0x87,0xFF,//6 7 8 9 E T B0xc6,0xbf,0xff };// C -const uchar tabl3[] ={ 0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09 };uchar t0_crycle;uchar hour_co un t, minu te_c oun t,sec on d_co un t,msec ond_count;uchar clock_hour,clock_m inu te;uchar coun tdow n_sec ond;uchar coun tdow n_hour,co un tdow n_min ute;uchar clock_en; //闹钟关闭和开启的标志,1开启,0关闭uchar flag1,sec on d_flag,za ncun 1,za ncun 2,za ncun3;uchar zancun4 ,za ncun 5,za ncun 6,za ncun7;uchar clock_flag,co un tdow n_flag;uchar msec on d_mi nute,msec on d_sec on d,mseco nd_mseco nd,mseco nd_flag; // 秒表相关参数uint speak_c ount;uchar templ,temph,temp_flag;uchar t_b,t_s,t_g,t_x,temp_flag2; //从左到右分别存储温度百位,十位,个位,小数位上电时默认的uchar tab23[3]; 〃二{0x40,0x59,0x23,0x28,0x11,0x06,0x09};//时间//主程序void main(){P3 =0x00;flag1 =0;zancun3 =0;msecond_minute =0; //置秒表相关参数为0msecond_second =0;msec on d_msec ond =0;speak =1;//关闭蜂鸣器speak_co unt =0;clock_hour =0;clock_m inute =0;clock_flag =0;countdown_flag =0; //倒计时标志位为0clock_en =0;//开机时默认关闭闹钟ini t_t0();TR0 =1;//// set_ds1302();〃设置DS130的初始时间//接下来开始编写让数码管显示的程序while (1){get_ds1302();judge_dis(); // 显示处理judge_s1();judge_s2();judge_s3();judge_clock(); //闹钟处理程序} _}void timer0() interrupt 1{TH0=(65536-50000)/256;TL0=(65536- 50000)%256;t0_crycle ++;if (t0_crycle ==2) // 0.1 秒{t0_crycle =0;msec on d_flag =1;msec ond_count ++;if (msecond_count==10)//1 秒。

[整理]1602液晶DS1302时钟芯片DS18B20温度传感器

[整理]1602液晶DS1302时钟芯片DS18B20温度传感器

看看我做的万年历,1602液晶+DS1302时钟芯片+DS18B20温度传感器
文章发表于:2007-09-21 16:26。

有兴趣的朋友可以看看这个作品最好的地方是在proteus仿真软件里通过了,这个仿真软件什么都有,对学单片机的人来说是最好的,你什么元件都不用买,写好代码可以就可以仿真了,做出来的效果跟硬件一样,极力推荐大家使用这个仿真软件,我使用这个软件有2年了,我打算在我的小组里写一套教程,一步步上手学会仿真,51单片机爱好者,欢迎加入我创建的小组,以后大家可以一起交流,多提一些意见,有什么好的作品和思想都可以一起交流。

实物图:
实物图:
proteus仿真图:
硬件实物还加入了一个无线遥控模块,可以无线的修改时间内容。

如果你已经安装好proteus了,直接打开那个绿色的文件,就可以直接运行了。

效果跟实物图一样的。

源程序就用KEIL打开。

源程序压缩包:。

51单片机+ds1302+DS18b20温度时钟(电路图+C语言程序)

51单片机+ds1302+DS18b20温度时钟(电路图+C语言程序)

时钟电路图:PCB板:单片机程序:/*=================================================================== =调试要求:1.MCU:AT89S52芯片或AT89C522.晶振:12MHz功能:多功能时钟+温度计====================================================================* /#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit dis_bit1=P2^7;//定义数码管控制口sbit dis_bit2=P2^6;//定义数码管控制口sbit dis_bit3=P2^4;//定义数码管控制口sbit dis_bit4=P2^3;//定义数码管控制口sbit dis_bit5=P2^1;//定义数码管控制口sbit dis_bit6=P2^0;//定义数码管控制口sbit led1_bit=P2^2;//定时LED的控制口sbit led2_bit=P2^5;//定时LED的控制口sbit s1_bit=P1^0; //定义S1控制口sbit s2_bit=P1^1; //定义S2控制口sbit s3_bit=P1^2; //定义S3控制口sbit dq_ds18b20=P3^3;//定义控制DS18B20sbit speak=P3^7; //定义蜂鸣器控制口sbit clk_ds1302=P3^6;//定义控制DS1302的时钟线sbit io_ds1302=P3^5;//定义控制DS1302的串行数据sbit rest_ds1302=P3^4;#define smg_data P0//定义数码管数据口void delay_3us();//3US的延时程序void delay_8us(uint t);//8US延时基准程序void delay_50us(uint t);//延时50*T微妙函数的声明void display1(uchar dis_data);//数码管1显示子程序void display2(uchar dis_data);//数码管2显示子程序void display3(uchar dis_data);//数码管3显示子程序void display4(uchar dis_data);//数码管4显示子程序void display5(uchar dis_data);//数码管5显示子程序void display6(uchar dis_data);//数码管6显示子程序void init_t0();//定时器0初始化函数void dis_led();//LED处理函数void judge_s1();//S1按键处理函数void judge_s2();//S2按键处理函数void judge_s3();//S3按键处理函数void dis(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1);//显示子程序void dis_san(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1,uchar san);//闪烁显示子程序void judge_dis();//显示处理函数void judge_clock();//显示处理函数void set_ds1302();//设置时间void get_ds1302();//读取当前时间void w_1byte_ds1302(uchar t);//向DS1302写一个字节的数据uchar r_1byte_ds1302();//从DS1302读一个字节的数据//******************************************************************* ****//DS18B20测温函数定义void w_1byte_ds18b20(uchar value);//向DS18B20写一个字节uchar r_1byte_ds18b20(void);//从DS18B20读取一个字节的数据void rest_ds18b20(void);//DS18B20复位程序void readtemp_ds18b20(void);//读取温度void dis_temp();//温度显示函数//共阳数码管断码表const uchar tabl1[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,// 0 1 2 3 4 50x82,0xf8,0x80,0x90,0x86,0x87,0xFF,//6 7 8 9 E T B0xc6,0xbf,0xff};// C -const uchar tabl3[]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07, 0x08,0x08,0x09,0x09};uchar t0_crycle;uchar hour_count,minute_count,second_count,msecond_count;uchar clock_hour,clock_minute;uchar countdown_second;uchar countdown_hour,countdown_minute;uchar clock_en;//闹钟关闭和开启的标志,1开启,0关闭uchar flag1,second_flag,zancun1,zancun2,zancun3;uchar zancun4,zancun5,zancun6,zancun7;uchar clock_flag,countdown_flag;uchar msecond_minute,msecond_second,msecond_msecond,msecond_flag;//秒表相关参数uint speak_count;uchar templ,temph,temp_flag;uchar t_b,t_s,t_g,t_x,temp_flag2;//从左到右分别存储温度百位,十位,个位,小数位uchar tab23[3];//={0x40,0x59,0x23,0x28,0x11,0x06,0x09};//上电时默认的时间//主程序void main(){P3=0x00;flag1=0;zancun3=0;msecond_minute=0;//置秒表相关参数为0msecond_second=0;msecond_msecond=0;speak=1;//关闭蜂鸣器speak_count=0;clock_hour=0;clock_minute=0;clock_flag=0;countdown_flag=0;//倒计时标志位为0clock_en=0;//开机时默认关闭闹钟init_t0();TR0=1;//// set_ds1302();//设置DS1302的初始时间//接下来开始编写让数码管显示的程序while(1){get_ds1302();judge_dis();//显示处理judge_s1();judge_s2();judge_s3();judge_clock();//闹钟处理程序}}void timer0() interrupt 1{TH0=(65536-50000)/256;TL0=(65536-50000)%256;t0_crycle++;if(t0_crycle==2)// 0.1秒{t0_crycle=0;msecond_flag=1;msecond_count++;if(msecond_count==10)//1秒{msecond_count=0;second_flag=1;}}}//************************************************** //显示处理函数void judge_dis(){if(flag1==0){if(second_flag==1){zancun7++;second_flag=0;}if(zancun7<1){if(temp_flag2==1){readtemp_ds18b20();//读取温度temp_flag2=0;}dis_temp();//温度显示函数}if(zancun7>=1){temp_flag2=1;zancun4=hour_count&0xf0;zancun4>>=4;zancun5=minute_count&0xf0;zancun5>>=4;zancun6=second_count&0xf0;zancun6>>=4;dis(zancun4,hour_count&0x0f,zancun5,minute_count&0x0f,zancun6,second_ count&0x0f);dis_led();if(zancun7==5)zancun7=0;}}if(flag1!=0){switch(flag1){case 1:dis(5,10,11,1,12,12);//显示SET1led1_bit=1;led2_bit=1;break;case 2:dis(5,10,11,2,12,12);//显示SET2break;case 3:dis(5,10,11,3,12,12);//显示SET3break;case 4:dis(5,10,11,4,12,12);//显示SET4break;dis(5,10,11,5,12,12);//显示SET5break;case 6:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,1);break;case 7:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,2);break;case 8:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,3);break;case 9://进入修改时间,时间分位个位闪烁dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,4);break;case 10://进入修改闹钟,闹钟小时十位闪烁dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,1);break;case 11://进入修改闹钟,闹钟小时个位闪烁dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,2);break;case 12://进入修改闹钟,闹钟小时十位闪烁dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,3);break;case 13://进入修改闹钟,闹钟小时个位闪烁dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,4);break;case 14://进入修改闹钟的开关dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,6);break;case 15:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun 3%10,1);break;dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun 3%10,2);break;case 17:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun 3%10,3);break;case 18:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun 3%10,4);break;case 19:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun 3%10,5);break;case 20:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun 3%10,6);break;case 21:if(second_flag==1){second_flag=0;countdown_second--;if(countdown_second==255){countdown_second=59;countdown_minute--;if(countdown_minute==255){countdown_minute=59;countdown_hour--;if(countdown_hour==255){flag1=22;countdown_minute=0;countdown_hour=0;countdown_second=0;countdown_flag=1;}}}}dis(countdown_hour/10,countdown_hour%10,countdown_minute/10,countdown _minute%10,countdown_second/10,countdown_second%10);//break;case 22:if(countdown_flag>0 && countdown_flag<7){speak=0;if(second_flag==1){second_flag=0;countdown_flag++;}}else{speak=1;}dis(countdown_hour/10,countdown_hour%10,countdown_minute/10,countdown _minute%10,countdown_second/10,countdown_second%10);//break;case 23:dis(msecond_minute/10,msecond_minute%10,msecond_second/10,msecond_sec ond%10,msecond_msecond%10,12);break;case 24:if(msecond_flag==1){msecond_flag=0;msecond_msecond++;if(msecond_msecond==10){msecond_msecond=0;msecond_second++;if(msecond_second==60){msecond_second=0;msecond_minute++;if(msecond_minute==100){msecond_minute=99;flag1=23;}}}}dis(msecond_minute/10,msecond_minute%10,msecond_second/10,msecond_sec ond%10,msecond_msecond%10,12);break;case 25:dis(zancun3/10,zancun3%10,zancun2/10,zancun2%10,zancun1/10,zancun1%10 );break;default:break;}}}//**************************************************//S1按键处理函数void judge_s1(){s1_bit=1;//置IO为1,准备读入收据if(s1_bit==0)//判断是否有按键按下{delay_50us(1);// 延时,去除机械抖动if(s1_bit==0){switch(flag1){case 0:case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 10:case 11:case 12:case 13:case 15:case 16:case 17:case 18:case 19:flag1++;break;case 9:flag1=6;break;case 14:flag1=10;break;case 20:flag1=15;break;case 5:case 21:case 22:case 23://系统从秒表状态复位case 24://系统从秒表状态复位case 25://系统从计数器复位flag1=0;break;default:break;}while(s1_bit==0){judge_dis();}//等待按键释放}}}//************************************************** //S2按键处理函数void judge_s2(){s2_bit=1;//置IO为1,准备读入收据if(s2_bit==0)//判断是否有按键按下{delay_50us(1);// 延时,去除机械抖动if(s2_bit==0){switch (flag1){case 1: //在显示SET1状态下按S2件,进入修改时间 flag1=6;zancun4=hour_count&0xf0;zancun4>>=4;zancun6=hour_count&0x0f;zancun1=zancun4*10+zancun6;//zancun1=hour_count;zancun5=minute_count&0xf0;zancun5>>=4;zancun6=minute_count&0x0f;zancun2=zancun5*10+zancun6;// zancun2=minute_count;break;case 2://在显示SET2状态下按S2,进入设置闹钟zancun1=clock_hour;zancun2=clock_minute;flag1=10;break;case 6://修改时钟小时十位状态下按S2件case 7://修改时钟小时个位状态下按S2件case 8://修改时钟分钟十位状态下按S2件case 9://修改时钟分钟个位状态下按S2件//zancun4=zancun1/10;tab23[2]=zancun1/10*16+zancun1%10;//zancun5=zancun2&0xf0;//zancun5>>=4;tab23[1]=zancun2/10*16+zancun2%10;hour_count=tab23[2];minute_count=tab23[1];second_count=0;tab23[0]=0;set_ds1302();//设置DS1302的初始时间flag1=0;break;case 10://修改闹钟小时十位状态下按S2case 11://修改闹钟小时个位状态下按S2case 12://修改闹钟分钟十位状态下按S2case 13://修改闹钟分钟个位状态下按S2case 14://修改闹钟使能状态下按S2clock_hour=zancun1;clock_minute=zancun2;clock_en=zancun3;flag1=0;break;case 3:flag1=15;zancun1=countdown_hour;zancun2=countdown_minute;zancun3=countdown_second;break;case 15:case 16:case 17:case 18:case 19:case 20:countdown_hour=zancun1;countdown_minute=zancun2;countdown_second=zancun3;flag1=21;countdown_flag=0;break;case 22:flag1=21;break;case 21:flag1=22;break;case 4:flag1=23;//秒表暂停msecond_minute=0;msecond_second=0;msecond_msecond=0;break;case 23:flag1=24;break;case 24:flag1=23;break;flag1=25;//进入计数器模式zancun1=0;zancun2=0;zancun3=0;break;default:break;}while(s2_bit==0){judge_dis();}//等待按键释放}}}//**************************************************//S3按键处理函数void judge_s3(){s3_bit=1;//置IO为1,准备读入收据if(s3_bit==0)//判断是否有按键按下{delay_50us(1);// 延时,去除机械抖动if(s3_bit==0){switch (flag1){case 6://修改时间小时的十位数zancun1+=10;if(zancun1>=24)zancun1=zancun1%10;break;case 7://修改时间小时的个位数zancun1=zancun1/10*10+(zancun1%10+1)%10;if(zancun1>=24)zancun1=20;break;case 8://修改时间分钟的十位数zancun2+=10;if(zancun2>=60)zancun2-=60;break;case 9://修改时间分钟的个位数zancun2=zancun2/10*10+(zancun2%10+1)%10;case 10://修改闹钟小时的十位数zancun1+=10;if(zancun1>=24)zancun1=zancun1%10;break;case 11://修改闹钟小时的个位数zancun1=zancun1/10*10+(zancun1%10+1)%10;if(zancun1>=24)zancun1=20;break;case 12://修改闹钟分钟的十位数zancun2+=10;if(zancun2>=60)zancun2-=60;break;case 13://修改闹钟分钟的个位数zancun2=zancun2/10*10+(zancun2%10+1)%10;break;case 14:zancun3^=1;break;case 15://修改倒计时小时的十位数zancun1+=10;if(zancun1>=100)zancun1-=100;break;case 16: //修改倒计时小时的个位数zancun1=zancun1/10*10+(zancun1%10+1)%10;break;case 17://修改倒计时分钟的十位数zancun2+=10;if(zancun2>=60)zancun2-=60;break;case 18: //修改倒计时分钟的个位数zancun2=zancun2/10*10+(zancun2%10+1)%10;break;case 19://修改倒计时秒的十位数zancun3+=10;if(zancun3>=60)zancun3-=60;break;case 20: //修改倒计时秒的个位数zancun3=zancun3/10*10+(zancun3%10+1)%10;break;case 21:case 22://countdown_hour=zancun1;countdown_minute=zancun2;countdown_second=zancun3; flag1=21;break;case 23:case 24://秒表复位flag1=24;msecond_minute=0;msecond_second=0;msecond_msecond=0;break;case 25:zancun1++;if(zancun1==100){zancun1=0;zancun2++;if(zancun2==100){zancun2=0;zancun3++;}}break;default:break;}while(s3_bit==0){judge_dis();}//等待按键释放}}}//**************************************** //显示处理函数void judge_clock(){zancun4=hour_count&0xf0;zancun4>>=4;zancun6=hour_count&0x0f;zancun4*=10;zancun4+=zancun6;zancun5=minute_count&0xf0;zancun5>>=4;zancun6=minute_count&0x0f;zancun5*=10;zancun5+=zancun6;if(clock_hour==zancun4 && clock_minute==zancun5){if(clock_en==1 && clock_flag==0){speak_count=0;//开启蜂鸣器clock_flag=1;speak_count=0;}}else{clock_flag=0;}if(clock_flag==1 && speak_count<400){if(msecond_count<=5){speak=0;speak_count++;}else{speak=1;}}else{speak=1;}}//****************************************////闪烁显示子程序void dis_san(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1,uchar san){if(san==1){{display1(s6);}}else{display1(s6);}if(san==2){if(msecond_count<5){display2(s5);}}else{display2(s5);}if(san==3){if(msecond_count<5){display3(s4);}}else{display3(s4);}if(san==4){if(msecond_count<5){display4(s3);}}else{display4(s3);}if(san==5){{display5(s2);}}else{display5(s2);}if(san==6){if(msecond_count<5){display6(s1);}}else{display6(s1);}}//****************************************//时钟显示程序void dis(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1) {display1(s6);display2(s5);display3(s4);display4(s3);display5(s2);display6(s1);}//******************************************************************* *************************void init_t0(){TMOD=0x01;//设定定时器工作方式1,定时器定时50毫秒TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;//开总中断ET0=1;//允许定时器0中断t0_crycle=0;//定时器中断次数计数单元}//**************************************************//LED处理函数void dis_led(){if(msecond_count<5){led1_bit=1;led2_bit=1;}else{led1_bit=0;led2_bit=0;}}//*************************************************************** //功能:把数据1显示在数码管1上void display6(uchar dis_data){smg_data=tabl1[dis_data];//送显示断码dis_bit6=0;//锁存数据delay_50us(40);dis_bit6=1;}//*************************************************************** //功能:把数据1显示在数码管1上void display5(uchar dis_data){smg_data=tabl1[dis_data];//送显示断码dis_bit5=0;//锁存数据delay_50us(40);dis_bit5=1;}//*************************************************************** //功能:把数据1显示在数码管1上void display4(uchar dis_data){smg_data=tabl1[dis_data];//送显示断码dis_bit4=0;//锁存数据delay_50us(40);dis_bit4=1;}//*************************************************************** //功能:把数据1显示在数码管1上void display3(uchar dis_data){smg_data=tabl1[dis_data];//送显示断码dis_bit3=0;//锁存数据delay_50us(40);dis_bit3=1;}//***************************************************************//功能:把数据1显示在数码管1上void display1(uchar dis_data){smg_data=tabl1[dis_data];//送显示断码dis_bit1=0;//锁存数据delay_50us(40);dis_bit1=1;}//***************************************************************//功能:把数据1显示在数码管1上void display2(uchar dis_data){smg_data=tabl1[dis_data];//送显示断码dis_bit2=0;//锁存数据delay_50us(40);dis_bit2=1;}//******************************************************************* *******************************//函数名称:void delay_50US(unsigned int t)//功能:延时50*t(us)void delay_50us(uint t){unsigned char j;for(;t>0;t--){for(j=19;j>0;j--);}}//******************************************************************* ************//8微秒延时基准程序void delay_8us(uint t){while(--t);}//******************************************************************* ************//3微秒延时程序void delay_3us(){;;}//******************************************************************* ************//子程序功能:向DS18B20写一字节的数据void w_1byte_ds18b20(uchar value){uchar i=0;for(i=0;i<8;i++){dq_ds18b20=1;delay_3us();dq_ds18b20=0;delay_8us(2);if (value& 0x01) dq_ds18b20=1; //DQ = 1delay_50us(1); //延时50us 以上delay_8us(2);value>>=1;}dq_ds18b20=1; //DQ = 1}//读一个字节uchar r_1byte_ds18b20(void){uchar i=0;uchar value= 0;for (i=0;i<8;i++){value>>=1;dq_ds18b20=0;// DQ_L;delay_3us();dq_ds18b20=1; //DQ_H;delay_8us(2);if(dq_ds18b20==1) value|=0x80;delay_8us(6); //延时40us}dq_ds18b20=1;return value;}//;**************************************************//ds18b20复位子程序void rest_ds18b20(void){rest:delay_3us(); //稍做延时delay_3us();dq_ds18b20=1;delay_3us();dq_ds18b20=0;// DQ_L;delay_50us(11);//480us<T<960usdq_ds18b20=1;//拉高总线delay_8us(5);if(dq_ds18b20==1){return;}delay_50us(2); //延时90usif(dq_ds18b20==1){return;}else{goto rest;}}//****************************************************//读取温度void readtemp_ds18b20(void){uchar temp32;rest_ds18b20();w_1byte_ds18b20(0xcc); //跳过读序列号的操作w_1byte_ds18b20(0x44); //启动温度转换delay_8us(2);rest_ds18b20();w_1byte_ds18b20(0xcc); //跳过读序列号的操作w_1byte_ds18b20(0xbe); //读取温度寄存器等(共可读9个寄存器)前两个就是温度templ=r_1byte_ds18b20();temph=r_1byte_ds18b20();if((temph&0xf0))//判断温度的正负性{temp_flag=0;//温度为负数标志temph=-temph;templ=-templ;t_x=tabl3[templ & 0x0f];//计算温度的小数temp32=temph & 0x0f;temp32<<=4;templ>>=4;temp32=temp32 | templ;t_b=temp32/100%10;//计算温度的百位数据t_s=temp32/10%10;//计算温度的十位数据t_g=temp32%10;//计算温度的个位数据}else//为正数{t_x=tabl3[templ & 0x0f];//计算温度的小数temp32=temph & 0x0f;temp32<<=4;templ>>=4;temp32=temp32 | templ;t_b=temp32/100%10;//计算温度的百位数据t_s=temp32/10%10;//计算温度的十位数据t_g=temp32%10;//计算温度的个位数据temp_flag=1;}}void dis_temp()//温度显示函数{if(temp_flag=1){if(t_b==0){dis(12,12,t_s,t_g,13,12);}else{dis(12,t_b,t_s,t_g,13,12);}}else{dis(14,t_b,t_s,t_g,13,12);}}//;################################################################## ############//;子程序名:w_1byte_ds1302//;功能:向DS1302写一个字节的数据void w_1byte_ds1302(uchar t){uchar i;for(i=0;i<8;i++){if(t & 0x01){io_ds1302=1;}else{io_ds1302=0;}clk_ds1302=1;delay_3us();delay_3us();clk_ds1302=0;delay_3us();delay_3us();t>>=1;}}//;################################################################## ######//;子程序名:r_1byte_ds1302()//;功能:从DS1302读一个字节的数据uchar r_1byte_ds1302(){uchar i,temp11=0;io_ds1302=1;//置IO为1,准备读入数据for(i=0;i<8;i++){temp11>>=1;if(io_ds1302) temp11 |= 0x80;clk_ds1302=1;delay_3us();delay_3us();clk_ds1302=0;delay_3us();}return(temp11);}//;################################################################## ###############//;子程序名:setbds1302//;功能:设置DS1302初始时间,并启动计时void set_ds1302(){uchar i,j;rest_ds1302=0;delay_3us();clk_ds1302=0;delay_3us();rest_ds1302=1;delay_3us();w_1byte_ds1302(0x8e);//写控制命令字 delay_3us();w_1byte_ds1302(0x00);//写保护关闭 clk_ds1302=1;delay_3us();rest_ds1302=0;for(i=0,j=0x80;i<7;i++,j+=2){rest_ds1302=0;delay_3us();clk_ds1302=0;delay_3us();rest_ds1302=1;delay_3us();w_1byte_ds1302(j);delay_3us();w_1byte_ds1302(tab23[i]);delay_3us();delay_3us();clk_ds1302=1;delay_3us();rest_ds1302=0;delay_3us();delay_3us();}rest_ds1302=0;delay_3us();clk_ds1302=0;delay_3us();rest_ds1302=1;delay_3us();w_1byte_ds1302(0x8e);delay_3us();w_1byte_ds1302(0x80);clk_ds1302=1;delay_3us();rest_ds1302=0;delay_3us();}//;#################################################################-------//;子程序名:get1302void get_ds1302(){uchar temp11[7],i,j;for(i=0;i<7;i++){temp11[i]=0;}for(i=0,j=0x81;i<7;i++,j+=2){rest_ds1302=0;delay_3us();clk_ds1302=0;delay_3us();rest_ds1302=1;delay_3us();w_1byte_ds1302(j);temp11[i]=r_1byte_ds1302();delay_3us();clk_ds1302=1;delay_3us();rest_ds1302=0;delay_3us();}if(temp11[0]!=0xff){second_count=temp11[0];}if(temp11[1]!=0xff)// 数据验证{minute_count=temp11[1];}if(temp11[2]!=0xff)//数据验证{hour_count=temp11[2];}// date=temp[3];//month=temp[4];// week=temp[5];//year=temp[6];}/*=================================================================== =调试要求:1.MCU:AT89S52芯片或AT89C522.晶振:12MHz功能:多功能时钟+温度计====================================================================* /#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit dis_bit1=P2^7;//定义数码管控制口sbit dis_bit2=P2^6;//定义数码管控制口sbit dis_bit3=P2^4;//定义数码管控制口sbit dis_bit4=P2^3;//定义数码管控制口sbit dis_bit5=P2^1;//定义数码管控制口sbit dis_bit6=P2^0;//定义数码管控制口sbit led1_bit=P2^2;//定时LED的控制口sbit led2_bit=P2^5;//定时LED的控制口sbit s1_bit=P1^0; //定义S1控制口sbit s2_bit=P1^1; //定义S2控制口sbit s3_bit=P1^2; //定义S3控制口sbit dq_ds18b20=P3^3;//定义控制DS18B20sbit speak=P3^7; //定义蜂鸣器控制口sbit clk_ds1302=P3^6;//定义控制DS1302的时钟线sbit io_ds1302=P3^5;//定义控制DS1302的串行数据sbit rest_ds1302=P3^4;#define smg_data P0//定义数码管数据口void delay_3us();//3US的延时程序void delay_8us(uint t);//8US延时基准程序void delay_50us(uint t);//延时50*T微妙函数的声明void display1(uchar dis_data);//数码管1显示子程序void display2(uchar dis_data);//数码管2显示子程序void display3(uchar dis_data);//数码管3显示子程序void display4(uchar dis_data);//数码管4显示子程序void display5(uchar dis_data);//数码管5显示子程序void display6(uchar dis_data);//数码管6显示子程序void init_t0();//定时器0初始化函数void dis_led();//LED处理函数void judge_s1();//S1按键处理函数void judge_s2();//S2按键处理函数void judge_s3();//S3按键处理函数void dis(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1);//显示子程序void dis_san(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchars1,uchar san);//闪烁显示子程序void judge_dis();//显示处理函数void judge_clock();//显示处理函数void set_ds1302();//设置时间void get_ds1302();//读取当前时间void w_1byte_ds1302(uchar t);//向DS1302写一个字节的数据uchar r_1byte_ds1302();//从DS1302读一个字节的数据//******************************************************************* ****//DS18B20测温函数定义void w_1byte_ds18b20(uchar value);//向DS18B20写一个字节uchar r_1byte_ds18b20(void);//从DS18B20读取一个字节的数据void rest_ds18b20(void);//DS18B20复位程序void readtemp_ds18b20(void);//读取温度void dis_temp();//温度显示函数//共阳数码管断码表const uchar tabl1[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,// 0 1 2 3 4 50x82,0xf8,0x80,0x90,0x86,0x87,0xFF,//6 7 8 9 E T B0xc6,0xbf,0xff};// C -const uchar tabl3[]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07, 0x08,0x08,0x09,0x09};uchar t0_crycle;uchar hour_count,minute_count,second_count,msecond_count;uchar clock_hour,clock_minute;uchar countdown_second;uchar countdown_hour,countdown_minute;uchar clock_en;//闹钟关闭和开启的标志,1开启,0关闭uchar flag1,second_flag,zancun1,zancun2,zancun3;uchar zancun4,zancun5,zancun6,zancun7;uchar clock_flag,countdown_flag;uchar msecond_minute,msecond_second,msecond_msecond,msecond_flag;//秒表相关参数uint speak_count;uchar templ,temph,temp_flag;uchar t_b,t_s,t_g,t_x,temp_flag2;//从左到右分别存储温度百位,十位,个位,小数位uchar tab23[3];//={0x40,0x59,0x23,0x28,0x11,0x06,0x09};//上电时默认的时间//主程序void main(){P3=0x00;flag1=0;zancun3=0;msecond_minute=0;//置秒表相关参数为0msecond_second=0;msecond_msecond=0;speak=1;//关闭蜂鸣器speak_count=0;clock_hour=0;clock_minute=0;clock_flag=0;countdown_flag=0;//倒计时标志位为0clock_en=0;//开机时默认关闭闹钟init_t0();TR0=1;//// set_ds1302();//设置DS1302的初始时间//接下来开始编写让数码管显示的程序while(1){get_ds1302();judge_dis();//显示处理judge_s1();judge_s2();judge_s3();judge_clock();//闹钟处理程序}}void timer0() interrupt 1{TH0=(65536-50000)/256;TL0=(65536-50000)%256;t0_crycle++;if(t0_crycle==2)// 0.1秒{t0_crycle=0;msecond_flag=1;msecond_count++;if(msecond_count==10)//1秒{msecond_count=0;second_flag=1;}}}//**************************************************//显示处理函数void judge_dis(){if(flag1==0){if(second_flag==1){zancun7++;second_flag=0;}if(zancun7<1){if(temp_flag2==1){readtemp_ds18b20();//读取温度temp_flag2=0;}dis_temp();//温度显示函数}if(zancun7>=1){temp_flag2=1;zancun4=hour_count&0xf0;zancun4>>=4;zancun5=minute_count&0xf0;zancun5>>=4;zancun6=second_count&0xf0;zancun6>>=4;dis(zancun4,hour_count&0x0f,zancun5,minute_count&0x0f,zancun6,second_ count&0x0f);dis_led();if(zancun7==5)zancun7=0;}}if(flag1!=0){switch(flag1){case 1:dis(5,10,11,1,12,12);//显示SET1led1_bit=1;led2_bit=1;break;case 2:dis(5,10,11,2,12,12);//显示SET2break;case 3:dis(5,10,11,3,12,12);//显示SET3break;case 4:dis(5,10,11,4,12,12);//显示SET4break;case 5:dis(5,10,11,5,12,12);//显示SET5break;case 6:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,1);break;case 7:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,2);break;case 8:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,3);break;case 9://进入修改时间,时间分位个位闪烁dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,12,4);break;case 10://进入修改闹钟,闹钟小时十位闪烁dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,1);break;case 11://进入修改闹钟,闹钟小时个位闪烁dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,2);break;case 12://进入修改闹钟,闹钟小时十位闪烁dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,3);break;case 13://进入修改闹钟,闹钟小时个位闪烁dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,4);break;case 14://进入修改闹钟的开关dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,12,zancun3,6);break;case 15:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun 3%10,1);break;case 16:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun 3%10,2);break;case 17:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun 3%10,3);break;case 18:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun 3%10,4);break;case 19:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun 3%10,5);break;case 20:dis_san(zancun1/10,zancun1%10,zancun2/10,zancun2%10,zancun3/10,zancun 3%10,6);break;case 21:if(second_flag==1)。

基于ds1302的51单片机简易实时时钟-1602显示-源程序

基于ds1302的51单片机简易实时时钟-1602显示-源程序

==================主程序================= #include <reg51.h>。

#include "ds1302.h"#include "LCD1602.h"void change();uchar times[9];uchar date[9];main(){LCD_init();//LCD初始化init_1302(time_1302);gotoxy(1,1);LCD_display("Time:");gotoxy(1,2);LCD_display("Date:");times[8]='\0';//date[8]='\0';while(1){get_1302(time_1302);change();gotoxy(7,1);LCD_display(times);gotoxy(7,2);LCD_display(date);}}/*=========================== 转换子程序===========================*/void change(){// 时间的转换times[0]=time_1302[2]/10+'0';times[1]=time_1302[2]%10+'0';times[2]=':';times[3]=time_1302[1]/10+'0';times[4]=time_1302[1]%10+'0';times[5]=':';times[6]=time_1302[0]/10+'0';times[7]=time_1302[0]%10+'0';// 日期的转换date[0]=time_1302[6]/10+'0';date[1]=time_1302[6]%10+'0';date[2]='-';date[3]=time_1302[4]/10+'0';date[4]=time_1302[4]%10+'0';date[5]='-';date[6]=time_1302[3]/10+'0';date[7]=time_1302[3]%10+'0';}======================================================DS1302驱动程序=============#define uchar unsigned charuchar time_1302[7]={0x00,0x00,0x00,0x03,0x07,0x03,0x08};//设置时间初始值数组// 秒分时号月份星期年sbit T_IO=P1^0; //与硬件相关的连线clk为DS1302的时钟信号线sbit T_CLK=P1^1; //DAT为DS1302的I/O数据线sbit T_RST=P1^2; //RST为DS1302的RST信号线uchar bdata datbyte;sbit datbyte0=datbyte^0;sbit datbyte7=datbyte^7;void get_1302(uchar time[]);void write_ds1302(uchar dat);uchar r_1302(uchar add);void w_1302(uchar add,uchar dat);uchar read_ds1302(void);void init_1302(uchar *time);/*==========================================D S 1 3 0 2 初始化===========================================*/void init_1302(uchar *time){uchar i, add;//uchar time_bcd[7];add=0x80;//0写入,1读出w_1302(0x8e,0x00);for(i=0;i<7;i++){w_1302(add,*time);add+=2;time++;}w_1302(0x8e,0x80);}//===========================// 读取当前时间//===========================void get_1302(uchar time[]){uchar i;uchar add=0x81;w_1302(0x8e,0x00);for(i=0;i<7;i++){time[i]=r_1302(add);add+=2;}w_1302(0x8e,0x80);}/*================================= DS1302写入一个字节(上升沿有效)=================================*/void write_ds1302(uchar dat){uchar i;datbyte=dat;for(i=0;i<8;i++){T_IO=datbyte0;T_CLK=1;T_CLK=0;datbyte=datbyte>>1;}}/*======================================= DS1302读取一个字节(下降沿有效)=======================================*/uchar read_ds1302(void){uchar i;for(i=0;i<8;i++){datbyte=datbyte>>1;datbyte7=T_IO;T_CLK=1;T_CLK=0;}return(datbyte);}/*========================================= 指定位置读取数据=========================================*/uchar r_1302(uchar add){uchar temp,dat1,dat2;T_RST=0;T_CLK=0;T_RST=1;write_ds1302(add);temp=read_ds1302();T_CLK=1;T_RST=0;dat1=temp/16;dat2=temp%16;temp=dat1*10+dat2;return(temp);}/*========================================== 指定位置写入数据==========================================*/void w_1302(uchar add,uchar dat){T_RST=0;T_CLK=0;T_RST=1;write_ds1302(add);write_ds1302(dat/10<<4|dat%10);T_CLK=1;T_RST=0;}=========================================== =============LCD1602驱动程序================#define LCD_DB P0//定义LCD的数据端口sbit LCD_RS=P2^0;sbit LCD_RW=P2^1;sbit LCD_E=P2^2;#define uchar unsigned char#define uint unsigned int//===========延时子函数======================== void delay_lcd(uint x){uint i,j;for(i=x;i>0;i--)for(j=0;j<2;j++);}//==================写指令函数================= void LCD_write_command(uchar command){LCD_DB=command;LCD_RS=0;//指令LCD_RW=0;//写入LCD_E=1;LCD_E=0;delay_lcd(1);//等待执行完毕。

AVR单片机+DS1302与1602显示时间

AVR单片机+DS1302与1602显示时间
//DS1302引脚定义
//DS1302引脚定义
#define SCL_H PORTA|=0X80 //SCL定义为A口的第7位脚,连接DS1302SCL脚
#define SCL_L PORTA&=0X7F
#define SDA_H PORTA|=0X40 //SDA定义为A口的第6位脚,连接DS1302SDA脚
void Set_RTC(void) //设定 日历
{
unsigned char i,tmp;
for(i=0;i<7;i++){
tmp=l_tmpdate[i]/10;
l_tmpdate[i]=l_tmpdate[i]%10;
l_tmpdate[i]Байду номын сангаасl_tmpdate[i]+tmp*16;
Write_Ds1302_Byte(dat); //发送数据
RST_L; //恢复
}
/****************************************************************************/
unsigned char Read_Ds1302 ( unsigned char address )
for (i=0;i<8;i++) //循环8次 读取数据
{
temp>>=1; //右移一位
SCL_L;
_delay_us(1);
if(SDA_IN)
temp|=0x80; //每次传低位在前
SCL_H;
_delay_us(1);
}
Write_Ds1302(0x8E,0x80);

DS1302+DS18B20+LCD1602单片机c语言驱动程序案例

DS1302+DS18B20+LCD1602单片机c语言驱动程序案例

程有华老师MCS51系列单片机教学(C语言)源代码——“DS1302+DS18B20+LCD1602”实验【文档构成】第一部分:Proteus仿真原理图第三部分:Keil C程序源代码(可copy使用)(程有华单片机培训工作室制作)第一部分:Proteus仿真原理图第2 页/ 共16 页第二部分:Keil C程序源代码(可copy使用)#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit p20=P2^0;sbit p21=P2^1;sbit p22=P2^2;sbit p23=P2^3;sbit p24=P2^4;sbit p25=P2^5;sbit LCDRS = P2^7;sbit LCDE = P2^6;sbit SCLK = P1^0;sbit IO = P1^1;sbit REST = P1^2;sbit p34 = P3^4;sbit p17 = P1^7;sbit DQ = P1^6;float n;bit sanyear; bit sanmonth; bit sanday; bit sanweek;bit sanhour; bit sanmin; bit sansec;bit san;ucharseccs=0X55,mincs=0X59,hourcs=0X22,daycs=0X09,monthcs=0X10,yearcs=0X07,weekcs=0X01; uchar sec,min,hour,day,month,year,week;uchar key=0xaa;uchar rl=0; uint qq,time,yy;uint TEMPL,TEMPH,aa,bb;uchar code zimo[]={0x00,0x0E,0x00,0x0E,0x00,0x1F,0x00,0x00, // 三0x00,0x1F,0x15,0x15,0x1B,0x11,0x1F,0x00, // 四0x00,0x1E,0x08,0x1E,0x0A,0x0A,0x1F,0x00, // 五0x00,0x04,0x00,0x1F,0x0A,0x11,0x00,0x00, // 六0x04,0x0F,0x12,0x0F,0x0A,0x1F,0x02,0x02, // 年0x0F,0x09,0x0F,0x09,0x0F,0x09,0x13,0x00, // 月0x1F,0x11,0x11,0x1F,0x11,0x11,0x1F,0x00, // 日0x04,0x0E,0x1C,0x1F,0x1C,0x0E,0x04,0x00};uchar code lcdadd[]={0x86,0x8a,0x8e,0xc8,0xcb,0xce,0x82};uchar code sz[]={"0123456789"};void keyer(void)p20=1;p21=0;if(!p22) { while(!p22);key=0x01; }if(!p23) { while(!p23);key=0x02; }if(!p24) { while(!p24);key=0x03; }if(!p25) { while(!p25);key=0x04; }p20=0;p21=1;if(!p22) {while(!p22); key=0x05; }if(!p23) { while(!p23);key=0x06; }if(!p24) { while(!p24);key=0x07; }if(!p25) { while(!p25);key=0x08; }} /**************盼键*************/ void into0init(void){TMOD = 0X01;TH0 = 15536/256;TL0 = 5536%256;IE = 0X82;TR0 = 1;} /************ INTO0 INITIALIZTION ***/ void into0deal(void) interrupt 1{TH0 = (65536-50000)/256;TL0 = (65536-50000)%256;time=time+1;if(time==8){time=0;san=!san;}}void delayus(uchar n){while(--n);} /************ US DELAY *************/ void delay(uint m){uint i,j;for(i=0;i<m;i++)for(j=0;j<125;j++);} /************ MS DELAY ************/ void LCD_WC(uchar i){LCDRS = 0;LCDE = 1;P0 = i;delay(5);delay(1);} /************ LCD WTIRE COMMAND ****/ void LCD_WD(uchar i){LCDRS=1;LCDE=1;P0=i;delay(5);LCDE=0;delay(2);} /*********** LCD WTIRE DATA *******/ void LCD_WB(void){uchar i;LCD_WC(0x40);for(i=0;i<64;i++)LCD_WD(zimo[i]);} /************ LCD WTIRE WORD ******/ void LCD_CS(void){LCD_WC(0x01);LCD_WC(0x02);LCD_WC(0x06);LCD_WC(0x0C);LCD_WC(0x14);LCD_WC(0x38);delay(10);LCD_WB();} /************ LCD INITIALIZTION **/ bit DS18b20_CS(void){bit dp;DQ=0;delayus(237);DQ=1;delayus(27);dp=DQ;delayus(237);return(dp);} /*********** DS18b20 INITIALIZTION */ void wbit(bit bp){DQ=0;delayus(3);if(bp)DQ=bp;delayus(20);DQ=1;} /*********** DS18b20 WRITE BIT *****/ void wbyte(uchar m){uchar i;for(i=0;i<8;i++){wbit(m&0x01);m=m>>1;}} /*********** DS18b20 WRITE BYTE ***/ bit rbit(void){bit bp;DQ=0;delayus(3);DQ=1;if(DQ)bp=1;else bp=0;delayus(20);return(bp);} /*********** DS18b20 READ BIT *****/ uchar rbyte(void){uchar i,m=0;for(i=0;i<8;i++){m=m>>1;if(rbit())m=m|0x80;}return(m);} /*********** DS18b20 READ BYTE ****/ void STARTUPDS18b20(void){while(DS18b20_CS());wbyte(0xcc);wbyte(0x44);// delay(750);for (yy=0;yy<10;yy++){keyer();if(key!=0xaa)break;}} /*********** STARTUP DS18b20 ******/ void READTEMP(void){STARTUPDS18b20();while(DS18b20_CS());// delay(1);wbyte(0xcc);wbyte(0xbe);TEMPL=rbyte();TEMPH=rbyte();n=(TEMPL+TEMPH*256)*0.0625;n=n*100;} /*********** READ TEMP IN DS18b20 */ void DISPDS18b20(void){uint m;READTEMP();LCD_WC(0x0c0);m=(uint)n;LCD_WD(sz[m/1000]);aa=sz[m/1000];m=m%1000;LCD_WD(sz[m/100]);bb=sz[m/100];m=m%100;LCD_WD('.');LCD_WD(sz[m/10]);m=m%10;LCD_WD(sz[m]);LCD_WD('C');if((aa>=sz[2])&&(bb>=sz[5])){p17=!p17;}if((aa>=sz[2])&&(bb==sz[5]))p17=0;if((aa<=sz[2])&&(bb<sz[4]))p17=1;} /* DS18b20 TEMP DEAL WITH AND RENOVATE */ uchar DS1302read(uchar address){uint b,c,e;e = address;SCLK = 0; REST = 0; REST = 1;for (b=0;b<8;b++){SCLK = 0;IO = (bit)(e & 0x01);SCLK = 1;e = e >> 1;}for (b=0;b<8;b++){SCLK = 0;c = c >> 1;if(IO)c=c|0x80;SCLK = 1;}REST = 0;SCLK = 1;return (c);}void DS1302wirte(uchar address,uchar dataes){uint a,adddat;SCLK = 0; REST = 0; REST = 1;adddat = address;for(a=0;a<8;a++){SCLK = 0;IO = (bit)(adddat & 0x01); //adddat & 0x01;////ddress&0x01);SCLK = 1;adddat = adddat >> 1;}adddat = dataes;for(a=0;a<8;a++){SCLK = 0;IO = (bit)(adddat & 0x01); //adddat & 0x01;//dataes&0x01;SCLK = 1;adddat = adddat >> 1;}REST = 0;}void DS1302readrealtime(void){sec = DS1302read(0x81);min = DS1302read(0x83);hour = DS1302read(0x85);day = DS1302read(0x87);month= DS1302read(0x89);year = DS1302read(0x8d);week = DS1302read(0x8b);}void DS1302init (void){DS1302wirte(0x8e,0x00);DS1302wirte(0x90,0xa9);DS1302wirte(0x80,seccs);DS1302wirte(0x82,mincs);DS1302wirte(0x84,hourcs);DS1302wirte(0x86,daycs);DS1302wirte(0x88,monthcs);DS1302wirte(0x8a,weekcs);DS1302wirte(0x8c,yearcs);}void OnlyMeSee (void){seccs = sec; mincs = min; hourcs = hour; weekcs = week;daycs = day; monthcs = month; yearcs = year;}void realtimedisplay(void){LCD_WC(0x80);LCD_WD('2');LCD_WD('0');if(sanyear==0){LCD_WD(sz[year/16]);LCD_WD(sz[year%16]);}else{LCD_WD(' ');LCD_WD(' ');}LCD_WC(0x84);LCD_WD(4);LCD_WD(' ');if(sanmonth==0){LCD_WD(sz[month/16]);LCD_WD(sz[month%16]);}else{LCD_WD(' ');LCD_WD(' ');}LCD_WC(0x88);LCD_WD(5);LCD_WD(' ');if(sanday==0){LCD_WD(sz[day/16]);LCD_WD(sz[day%16]);}else{LCD_WD(' ');LCD_WD(' ');}LCD_WC(0x8C);LCD_WD(6);LCD_WD('<');if(sanweek==0){if (1==week%16)LCD_WD('-');if (2==week%16)LCD_WD('=');if (3==week%16)LCD_WD(0);if (4==week%16)LCD_WD(1);if (5==week%16)LCD_WD(2);if (6==week%16)LCD_WD(3);if (7==week%16)LCD_WD(6);}else{LCD_WD(' ');}LCD_WD('>');LCD_WC(0xc8);if(sanhour==0){LCD_WD(sz[hour/16]);LCD_WD(sz[hour%16]);}else{LCD_WD(' ');LCD_WD(' ');}LCD_WC(0xca);LCD_WD(':');if(sanmin==0){LCD_WD(sz[min/16]);LCD_WD(sz[min%16]);}else{LCD_WD(' ');LCD_WD(' ');}LCD_WC(0xcd);LCD_WD(':');if(sansec==0){LCD_WD(sz[sec/16]);LCD_WD(sz[sec%16]);}else{LCD_WD(' ');LCD_WD(' ');}}void OnlyMeSee1(void){EA=0;sanyear=0;sanmonth=0;sanday=0;sanweek=0;sanhour=0;sanmin=0;sansec=0;}void keywith (void){keyer();if(key==0x08){key=0xaa;EA=1;while(1){loop: realtimedisplay();if(rl==0){sanyear = san;sanmonth=0;sanday=0;sanweek=0;sanhour=0;sanmin=0;sansec=0; }if(rl==1){sanmonth= san;sanyear=0;sanday=0;sanweek=0;sanhour=0;sanmin=0;sansec=0; }if(rl==2){sanday = san;sanyear=0;sanmonth=0;sanweek=0;sanhour=0;sanmin=0;sansec=0; }if(rl==3){sanweek = san;sanyear=0;sanmonth=0;sanday=0;sanhour=0;sanmin=0;sansec=0; }if(rl==4){sanhour = san;sanyear=0;sanmonth=0;sanday=0;sanweek=0;sanmin=0;sansec=0; }if(rl==5){sanmin = san;sanyear=0;sanmonth=0;sanday=0;sanweek=0;sanhour=0;sansec=0; }if(rl==6){sansec = san;sanyear=0;sanmonth=0;sanday=0;sanweek=0;sanhour=0;sanmin=0; }keyer();if(key==0x08){break;}if(key==0x03){OnlyMeSee();DS1302init();break;}if(key==0x05){key=0xaa;rl=rl-1;if(rl==255)rl=6;goto loop;}if(key==0x07){key=0xaa;rl=rl+1;if(rl==7)rl=0;goto loop;}if(key==0x02){ key=0xaa;switch(rl){case 0: {LCD_WC(0x82); year=year+0x01;switch(year){case 0x0a :year=0x10; break;case 0x1a :year=0x20; break;case 0x2a :year=0x30; break;case 0x31 :year=0x00; break;}LCD_WD(sz[year/16]);LCD_WD(sz[year%16]);LCD_WC(0x82);goto loop;case 1: {LCD_WC(0x86);month = month+0x01;switch(month){case 0x0a :month=0x10; break;case 0x13 :month=0x01; break;}LCD_WD(sz[month/16]);LCD_WD(sz[month%16]);LCD_WC(0x86);goto loop;}case 2: {LCD_WC(0x8a);day = day+0x01;switch(day){case 0x0a :day=0x10; break;case 0x1a :day=0x20; break;case 0x2a :day=0x30; break;case 0x32 :day=0x01; break;}LCD_WD(sz[day/16]);LCD_WD(sz[day%16]);LCD_WC(0x8a);goto loop;}case 3: {LCD_WC(0x8e);week = week+1;if(week==8){week=1;if (1==week%16)LCD_WD('-');LCD_WC(0x8e);goto loop;}if (1==week%16)LCD_WD('-');if (2==week%16)LCD_WD('=');if (3==week%16)LCD_WD(0);if (4==week%16)LCD_WD(1);if (5==week%16)LCD_WD(2);if (6==week%16)LCD_WD(3);if (7==week%16)LCD_WD(6);LCD_WC(0x8e);goto loop;}LCD_WC(0xc8);hour = hour+0x01;switch(hour){case 0x0a :hour=0x10; break;case 0x1a :hour=0x20; break;case 0x24 :hour=0x00; break;}LCD_WD(sz[hour/16]);LCD_WD(sz[hour%16]);LCD_WC(0xc8);goto loop;}case 5: {LCD_WC(0xcb); min = min+0x01;switch(min){case 0x0a :min=0x10; break;case 0x1a :min=0x20; break;case 0x2a :min=0x30; break;case 0x3a :min=0x40; break;case 0x4a :min=0x50; break;case 0x5a :min=0x00; break;}LCD_WD(sz[min/16]);LCD_WD(sz[min%16]);LCD_WC(0xcb);goto loop;}case 6: {LCD_WC(0xce);sec = sec+0x01;switch(sec){case 0x0a :sec=0x10; break;case 0x1a :sec=0x20; break;case 0x2a :sec=0x30; break;case 0x3a :sec=0x40; break;case 0x4a :sec=0x50; break;case 0x5a :sec=0x00; break;}LCD_WD(sz[sec/16]);LCD_WD(sz[sec%16]);LCD_WC(0xce);goto loop;}}}if(key==0x06){ key=0xaa;switch(rl){case 0: {LCD_WC(0x82); year=year-0x01;switch(year){case 0xff :year=0x30; break;case 0x2f :year=0x29; break;case 0x1f :year=0x19; break;case 0x0f :year=0x09; break;}LCD_WD(sz[year/16]);LCD_WD(sz[year%16]);LCD_WC(0x82);goto loop;}case 1: {LCD_WC(0x86);month = month-0x01;switch(month){case 0x00 :month=0x12; break;case 0x0f :month=0x09; break;}LCD_WD(sz[month/16]);LCD_WD(sz[month%16]);LCD_WC(0x86);goto loop;}case 2: {LCD_WC(0x8a);day = day-0x01;switch(day){case 0x00 :day=0x31; break;case 0x2f :day=0x29; break;case 0x1f :day=0x19; break;case 0x0f :day=0x09; break;}LCD_WD(sz[day/16]);LCD_WD(sz[day%16]);LCD_WC(0x8a);goto loop;}case 3: {LCD_WC(0x8e);week = week-1;switch(week){}if (1==week%16)LCD_WD('-');if (2==week%16)LCD_WD('=');if (3==week%16)LCD_WD(0);if (4==week%16)LCD_WD(1);if (5==week%16)LCD_WD(2);if (6==week%16)LCD_WD(3);if (7==week%16)LCD_WD(6);LCD_WC(0x8e);goto loop;}case 4: {LCD_WC(0xc8);hour = hour-0x01;switch(hour){case 0xff :hour=0x23; break;case 0x1f :hour=0x19; break;case 0x0f :hour=0x09; break;}LCD_WD(sz[hour/16]);LCD_WD(sz[hour%16]);LCD_WC(0xc8);goto loop;}case 5: {LCD_WC(0xcb); min = min-0x01;switch(min){case 0xff :min=0x59; break;case 0x4f :min=0x49; break;case 0x3f :min=0x39; break;case 0x2f :min=0x29; break;case 0x1f :min=0x19; break;case 0x0f :min=0x09; break;}LCD_WD(sz[min/16]);LCD_WD(sz[min%16]);LCD_WC(0xcb);goto loop;}case 6: {LCD_WC(0xce);sec = sec-0x01;switch(sec){case 0xff :sec=0x59; break;case 0x4f :sec=0x49; break;case 0x2f :sec=0x29; break;case 0x1f :sec=0x19; break;case 0x0f :sec=0x09; break;}LCD_WD(sz[sec/16]);LCD_WD(sz[sec%16]);LCD_WC(0xce);goto loop;}}}}}key=0xaa;OnlyMeSee1();rl=0;}void main(void){into0init(); EA=0;DS18b20_CS(); LCD_CS(); DS1302init();while(1){DS1302readrealtime();realtimedisplay();DISPDS18b20();keywith();}}。

51单片机的18B20、1302和LCM1602液晶显示温度与万年历显控制

51单片机的18B20、1302和LCM1602液晶显示温度与万年历显控制

摘要本设计以数字集成电路技术为基础,单片机技术为核心。

软件设计采用模块化结构,C语言编程。

系统通过LCD显示数据,可以显示日期(年、月、日、时、分、秒)以及温度。

在内容安排上首先描述系统硬件工作原理,着重介绍了各硬件接口技术和各个接口模块的功能;其次,详细的阐述了程序的各个模块和实现过程。

前言电子时钟是实现对年,月,日,时,分,秒数字显示的计时装置,广泛用于个人家庭,车站,码头,办公室,银行大厅等场所,成为人们日常生活中的必需品。

数字集成电路的发展和石英晶体振荡器的广泛应用,使得数字钟的精度远远超过老式钟表。

钟表的数字化给人们生产生活带来了极大的方便,在此基础上完成的电子时钟精度高,功能易于扩展。

可扩展成为诸如定时自动报警、按时自动打铃、时间程序自动控制、定时广播、自动起闭路灯、定时开关烘箱、通断动力设备、甚至各种定时电气的自动启用等电路。

所有这些,都是以钟表数字化为基础的。

因此,研究数字时钟及扩大其应用有着非常现实的意义。

本设计就是数字时钟简单的扩展应用。

1.1设计目标:利用单片机技术,以及模拟电子技术和数字电子技术的理论知识,设计实现MCS-51单片机对LCM1602液晶输出显示控制的这一基本要求。

1.2设计要求:本设计利用DS1302;DS18B20;LCD1602实现以下功能:(1) 显示日期功能(年、月、日、时、分、秒以及星期)(2) 可通过按键切换年、月、日及时、分、秒的显示状态(3) 可随时调校年、月、日或时、分、秒(4) 可每次增减一进行时间调节(5) 可动态完整显示年份,实现真正的万年历显示(6) 可显示温度2 设计方案2.1 控制器硬件控制电路主要用了AT89C52芯片处理器、LCD显示器等。

根据各自芯片的功能互相连接成电子万年历的控制电路。

软件控制程序主要有主控程序、电子万年历的时间控制程序、时间显示及星期显示和温度采集程序等组成。

主控程序中对整个程序进行控制,进行了初始化程序及计数器、还有键盘功能程序、以及显示程序等工作,时间控制程序是电子万年历中比较重要的部分。

基于DS1302和LCD1602的万年历,闹钟,时钟,用开发版直接显示的程序 - 副本

基于DS1302和LCD1602的万年历,闹钟,时钟,用开发版直接显示的程序 - 副本

实时时钟芯片DS1302应用,DS18B20应用实例——可调时钟,LCD1602显示:(时间+温度)说明:需要按程序中定义的接口。

按自己接口,只要在程序中修改接口定义即可。

1、DS1302引脚排列:如下图引脚说明:1)Vcc1:后备电源,VCC2:主电源。

在主电源关闭的情况下,也能保持时钟的连续运行。

DS1302由Vcc1或Vcc2两者中的较大者供电。

当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电。

当Vcc2小于Vcc1时,DS1302由Vcc1供电。

2)X1、X2:振荡源,外接32.768kHz 晶振。

3)RST:复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。

RST输入有两种功能:首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。

当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。

如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。

上电运行时,在Vcc>2.0V之前,RST必须保持低电平。

只有在SCLK为低电平时,才能将RST置为高电平。

4)I/O为串行数据输入输出端(双向)。

5)SCLK为时钟输入端。

2、 DS1302的控制字节DS1302 的控制字如下图所示。

控制字节的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1指示操作单元的地址;最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出。

3、数据输入输出(I/O)在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。

同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。

51单片机+ds1302+DS18b20温度时钟(电路图+C语言程序)

51单片机+ds1302+DS18b20温度时钟(电路图+C语言程序)

时钟电路图:*■11PCB板:酱时井務ft是用诵m-pdfMerisi 口叵因Fjr 齐舱 C :s ® 工细理沖缶皿ndm - * TfS ' 4' 包田U i > 'ir ft ZS:MZ fH钟些fl是用说町-Pdf Wirrcf闻礒雜sbit dis_ bitlsbit dis_ bit2sbit dis_ bit3sbit dis_ bit4sbit dis_ bit5sbit dis_ bit6sbit ledl _bitsbit led2 ! bit=P2A7; II定义数码管控制口=P2A6; II定义数码管控制口=卩2八4; II定义数码管控制口=卩2八3; II定义数码管控制口=P2A1; II定义数码管控制口=P2A0; II定义数码管控制口=P2A2; II定时LED勺控制口=P2A5; II定时LED勺控制口单片机程序:/*===================================================================调试要求:1. MCU:AT89S52 芯片或AT89C522. 晶振:12MHz功能:多功能时钟+温度计/#inelude <reg52. h>#inelude vintrins . h>訂开始 LJ-雲匕®务如1痒3月计ttVl. •呈T』d"吐拠席射■ w耳pg文宇■[豹…SS时軽件思冃说#define uehar #define uint unsigned char unsigned intsbit s1_bit =P1A 0; // 定义S1 控制口 sbit s2_bit =P01; // 定义 S2控制口 sbit s3_bit =P02; // 定义 S3控制口 sbit dq_ds18b20 =P3A3;// 定义控制 DS18B20 sbit speak =P3A7; //定义蜂鸣器控制口sbit clk_ds1302 =P3A6; // 定义控制 DS1302勺时钟线 sbit io_ds1302 =P3A5;//定义控制DS1302勺串行数据 sbit rest_ds1302 =P3A4;#define smg_data P0 //定义数码管数据口void delay_3us(); //3US 的延时程序 void delay_8us(ui nt t);//8US 延时基准程序void delay_50us(ui nt t); //void display1(uchar dis_data); void display2(uchar dis_data); void display3(uchar dis_data); void display4(uchar dis_data); void display5(uchar dis_data); void display6(uchar dis_data);void init_t0(); //定时器0初始化函数 void dis_led(); //LED 处理函数 void judge_s1(); //S1 按键处理函数void judge_s2(); //S2 按键处理函数 void judge_s3(); //S3 按键处理函数void dis(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1); 示子程序 void dis_sa n( uchar s6,uchar s5,uchar s4,uchar s3,uchar s1,uchar san); 〃闪烁显示子程序 void judge_dis(); //显示处理函数 void judge_clock(); // 显示处理函数 void set_ds1302(); // 设置时间void get_ds1302();// 读取当前时间void w_1byte_ds1302(uchar t); // 向 DS130写一个字节的数据 uchar r_1byte_ds1302(); // 从DS130读一个字节的数据//DS18B20测温函数定义延时50*T 微妙函数的声明//数码管1显示子程序 //数码管2显示子程序 //数码管3显示子程序 //数码管4显示子程序 //数码管5显示子程序 //数码管6显示子程序//显 s2,ucharvoid w_1byte_ds18b20(uchar value); // 向DS18B2写一个字节ucharr_1byte_ds18b20( void ); // 从DS18B2读取一个字节的数据voidrest_ds18b20( void ); //DS18B20复位程序void readtemp_ds18b20( void ); // 读取温度void dis_temp(); //温度显示函数//共阳数码管断码表const uchar tabl1[16] ={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,// 0 1 2 3 4 50x82,0xf8,0x80,0x90,0x86,0x87,0xFF,//6 7 8 9 E T B0xc6,0xbf,0xff };// C -const uchar tabl3[] ={ 0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09 };uchar t0_crycle;uchar hour_co un t, minu te_c oun t,sec on d_co un t,msec ond_count;uchar clock_hour,clock_m inu te;uchar coun tdow n_sec ond;uchar coun tdow n_hour,co un tdow n_min ute;uchar clock_en; //闹钟关闭和开启的标志,1开启,0关闭uchar flag1,sec on d_flag,za ncun 1,za ncun 2,za ncun3;uchar zancun4 ,za ncun 5,za ncun 6,za ncun7;uchar clock_flag,co un tdow n_flag;uchar msec on d_mi nute,msec on d_sec on d,mseco nd_mseco nd,mseco nd_flag; // 秒表相关参数uint speak_c ount;uchar templ,temph,temp_flag;uchar t_b,t_s,t_g,t_x,temp_flag2; //从左到右分别存储温度百位,十位,个位,小数位uchar tab23[3]; 〃二{0x40,0x59,0x23,0x28,0x11,0x06,0x09};// 上电时默认的时间//主程序void main(){P3 =0x00;flag1 =0;zancun3 =0;msecond_minute =0; //置秒表相关参数为0msecond_second =0;msec on d_msec ond =0;speak =1;//关闭蜂鸣器speak_co unt =0;clock_hour =0;clock_m inute =0;clock_flag =0;countdown_flag =0; //倒计时标志位为0clock_en =0;//开机时默认关闭闹钟ini t_t0();TRO =1;//// set_ds1302();〃设置DS1302勺初始时间//接下来开始编写让数码管显示的程序while (1){get_ds1302();judge_dis(); // 显示处理judge_s1();judge_s2();judge_s3();judge_clock(); //闹钟处理程序} _}void timerO() interrupt 1{TH0=(65536-50000)/256;TL0=(65536 - 50000)%256; t0_crycle ++;if (t0_crycle ==2) // 0.1 秒{t0_crycle =0;msec on d_flag =1;msec ond_count ++;if (msecond_count==10)//1 秒{ _msec on d_co unt =0;sec on d_flag =1;}}}//**************************************************//显示处理函数void judge_dis(){if (flag1 ==0){if (second_flag ==1){ _zancun7 ++;sec on d_flag =0;} _if (zancun7 <1){if (temp_flag2 ==1){ 一readtemp_ds18b20(); // 读取温度temp_flag2 =0;厂dis_temp(); //温度显示函数}if (zancun7 >=1){temp_flag2 =1;zancun4 =hour_count &0xf0;zancun4 >>=4;zancun5 =minute_count&0xf0;zancun5 >>=4;zancun6 =sec on d_co unt&0xf0;zancun6 >>=4;dis(za ncun4 ,hour_co unt &0x0f,za ncun5,minu te_co unt &0x0f,za ncun 6,sec ond_ cou nt &0x0f);dis_led();if (zancun7 ==5)zancun7 =0;}}if (flag1 !=0){switch (flag1){case 1:dis(5,10,11,1,12,12); // 显示SET1led1_bit =1;led2_bit =1;break;case 2:dis(5,10,11,2,12,12); // 显示SET2break;case 3:dis(5,10,11,3,12,12); // 显示SET3break;case 4:dis(5,10,11,4,12,12); // 显示SET4break;case 5:dis(5,10,11,5,12,12); // 显示SET5break;case 6:dis_san(zancun1 / 10,zancunl %10,zancun2/ 10,zancun2 %0,12,12,1); break;case 7:dis_san(zancun1 / 10,zancunl %10,zancun2/ 10,zancun2 %0,12,12,2); break;case 8:dis_san(zancun1 / 10,zancunl %10,zancun2/ 10,zancun2 %0,12,12,3); break;case 9: //进入修改时间,时间分位个位闪烁dis_san(zancun1 / 10,zancunl %10,zancun2/ 10,zancun2 %0,12,12,4); break;case 10: //进入修改闹钟,闹钟小时十位闪烁dis_san(zancunl / 10,zancunl %10,zancun2/ 10,zancun2 %0,12,zancun3,1); break;case 11://进入修改闹钟,闹钟小时个位闪烁dis_san(zancun1 / 10,zancunl %10,zancun2/ 10,zancun2%0,12,zancun3,2); break;case 12: //进入修改闹钟,闹钟小时十位闪烁dis_sa n(zan cu n1 / 10,za ncun1 %10,za ncun 2/ 10,za ncu n2%0,12,za ncun 3,3);break;case 13: //进入修改闹钟,闹钟小时个位闪烁dis_sa n(zan cu n1 / 10,za ncun1 %10,za ncun 2/ 10,za ncu n2%0,12,za ncun 3,4);break;case 14: //进入修改闹钟的开关dis_sa n(zan cu n1 / 10,za ncun1 %10,za ncun 2/ 10,za ncu n2%0,12,za ncun 3,6);break;case 15:dis_sa n(zancun1 / 10,za ncun1 %10,za ncun 2/ 10,za ncun 2%0,za ncun3/ 10,za ncun 3%10,1);break;case 16:dis_san(zancun1 / 10,zancunl %10,zancun2/10,zancun2%0,zancun3/ 10,zancun3%10,2);break;case 17:dis_san(zancun1 / 10,zancunl %10,zancun2/ 10,zancun2%0,zancun3/ 10,zancun 3%10,3);break;case 18:dis_sa n(zancun1 / 10,za ncun1 %10,za ncun 2/ 10,za ncun 2%0,za ncun3/ 10,za ncun 3%10,4);break;case 19:dis_sa n(zancun1 / 10,za ncun1 %10,za ncun 2/ 10,za ncun 2%0,za ncun3/ 10,za ncun 3%10,5);break;case 20:dis_sa n(zancun1 / 10,za ncun1 %10,za ncun 2/ 10,za ncun 2%0,za ncun3/ 10,za ncun 3%10,6);break;case 21:if (second_flag ==1){ _sec on d_flag =0;countdown_second --;if (countdown_second ==255){ _coun tdow n_sec ond =59;countdown_minute --;if (countdown_minute ==255){ _coun tdow n_min ute =59;countdown_hour --;if (countdown_hour ==255){flag1 =22;coun tdow n_min ute =0;coun tdow n_hour =0;coun tdow n_sec ond =0;coun tdow n_flag=1;_ } } } }dis(countdown_hour / 10,countdown_hour %10,countdown_minute / 10,countdown _minute%10,countdown_second/ 10,countdown_second%10); //break; case 22:{ speak =1;}dis(countdown_hour / 10,countdown_hour %10,countdown_minute / 10,countdown _minute%10,countdown_second/ 10,countdown_second%10); //break; case 23: dis(msecond_minute / 10,msecond_minute%10,msecond_second/ 10,msecond_sec on d%10,mseco nd_msec on d%0,12);break; case 24:if (msecond_flag ==1) { _msec on d_flag =0; msec on d_msec ond ++;if (msecond_msecon (==10){msec on d_msec ond =0; msec on d_sec ond ++;if (msecond_second==60) { _msecond_second =0; msec ond_minute ++;if (countdown_flag { _speak=0;if (second_flag { _sec on d_flag coun tdow n_flag} _ } else>0 &&countdown_flag <7)==1) =0; ++;if (msecond_minute==1OO) { _msec ond_minute =99;flagl =23;}}}}dis(msecond_minute / 10,msecond_minute%10,msecond_second/ 10,msecond_sec on d%10,mseco nd_msec on d%0,12);break;case 25:dis(zancun3 / 10,zancun3 %0,zancun2 / 10,zancun2 %10,zancun1 /10,zancun1 %0 );break;default :break;}}}//**************************************************〃S1按键处理函数void judge_s1(){ _s1_bit =1;//置IO为1,准备读入收据if (s1_bit ==0)//判断是否有按键按下{delay_50us(1); //延时,去除机械抖动if (s1_bit ==0){switch (flag1){case 0:case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 10:case 11:case 12:case 13:case 15:case 16:case 17:case 18:case 19: flag1++;break;case 9: flag1=6;break;case 14: flag1=10;break;case 20: flag1=15;break;case 5:case 21:case 22:case 23: //系统从秒表状态复位case 24: //系统从秒表状态复位case 25: //系统从计数器复位flag1 =0;break;default :break;}while (s1_bit ==0){ _judge_dis();}〃等待按键释放}}}〃************************************************** 〃S2按键处理函数void judge_s2(){ _s2_bit =1; //置IO为1,准备读入收据if (s2_bit ==0)//判断是否有按键按下=0;{delay_50us(1); //延时,去除机械抖动 if (s2_bit ==0) { switch (flagl) { flag1 =6; zancun4 =hour_count &0xf0;zancun4 >>=4; zancun6 =hour_count &0x0f;zancun1=zancun4*10+zancun6; //zancun 1=hour_co unt; zancun5 =minute_count &0xf0; zancun5 >>=4; zancun6 =minute_count &0x0f; zancun2 =za ncun5* 10+za ncun6; case 1: //在显示SET 状态下按S2牛,进入修改时间 // zancun2=minu te_co unt; break; case 2: //在显示SET2犬态下按S2,进入设置闹钟 zancunl =clock_hour; zancun2 =clock_m inu te; flagl =10; break; case 6: //修改时钟小时十位状态下按 case 7: //修改时钟小时个位状态下按 case 8: //修改时钟分钟十位状态下按 case 9: //修改时钟分钟个位状态下按 〃zancun4=za ncun 1/10; 测S:SM tab23[2] =zancun1/10* 16+za ncu n1%10; tab23[1] hour_c ount minu te_c ount sec ond_co unt tab23[0]set_ds1302(); flag1//zancun 5=za ncun2&0 xf0; //zancun 5>>=4; =zancun2/10* 16+za ncu n2%10; =tab23[2]; =tab23[1]; =0; //设置DS130的初始时间 =0;break; case 10: //修改闹钟小时十位状态下按S2case 11: //修改闹钟小时个位状态下按S2case 12: //修改闹钟分钟十位状态下按S2 case 13: //修改闹钟分钟个位状态下按S2 case 14: //修改闹钟使能状态下按S2clock_hour clock_m inute clock_e n flag1=zancun1; =zancun2; =zancun3;=0;break;case 3:flagl =15;zancunl =co un tdow n_hour;zancun2 =co un tdow n_minu te;zancun3 =co un tdow n_sec ond;break;case 15:case 16:case 17:case 18:case 19:case 20:coun tdow n_hour =zancun1;coun tdow n_minute =za ncun2;coun tdow n_sec ond =za ncun3;flag1 =21;coun tdow n_flag =0;break;case 22:flag1 =21;break;case 21:flag1 =22;break;case 4:flag1 =23; //秒表暂停msec ond_minute =0;msecond_second =0;msec on d_msec ond =0;break;case 23:flag1 =24;break;case 24:flag1 =23;break;case 5:flagl =25;//进入计数器模式zancunl =0;zancun2 =0;zancun3 =0;break; default :break;}while (s2_bit ==0){ _judge_dis();}//等待按键释放}}}//**************************************************//S3按键处理函数void judge_s3(){ _s3_bit =1;//置IO为1,准备读入收据if (s3_bit ==0)//判断是否有按键按下{delay_50us(1); //延时,去除机械抖动if (s3_bit ==0){ _switch (flag1){case 6: //修改时间小时的十位数zancun1 +=10;if (zancun1 >=24)zancun1 =zancun 1%10;break;case 7: //修改时间小时的个位数za ncun1 =za ncu n1/10* 10+(za ncun1 %10+1) %10;if (zancun1 >=24)zancun1 =20;break;case 8: //修改时间分钟的十位数zancun2 +=10;if (zancun2 >=60)zancun2-=60;break;case 9: //修改时间分钟的个位数za ncun2 =za ncun2/10* 10+(za ncun2 %10+1) %10;break;case 10: //修改闹钟小时的十位数zancunl +=10;if (zancunl >=24)zancunl =zancun 1%10; break;case 11: //修改闹钟小时的个位数zancunl =za ncu n1/10* 10+(za ncun1 %10+1) %10;if (zancun1 >=24)zancun1 =20;break;case 12: //修改闹钟分钟的十位数zancun2 +=10;if (zancun2 >=60)zancun2-=60; break;case 13: //修改闹钟分钟的个位数zan cu n2 =za ncun2/10* 10+(za ncun2 %10+1) %10;break;case 14:zancun3 A=1;break;case 15: //修改倒计时小时的十位数zancun1 +=10;if (zancun1 >=100)zancun 1 -=100; break;case 16: //修改倒计时小时的个位数zancun1 =za ncu n1/10* 10+(za ncun1 %10+1) %10;break;case 17: //修改倒计时分钟的十位数zancun2 +=10;if (zancun2 >=60)zancun2-=60; break;case 18: //修改倒计时分钟的个位数zan cu n2 =za ncun2/10* 10+(za ncun2 %10+1) %10;break;case 19: //修改倒计时秒的十位数zancun3 +=10;if (zancun3 >=60)zancun3-=60; break;case 20: //修改倒计时秒的个位数zan cu n3 =za ncun3/10* 10+(za ncun3 %10+1) %10;break;case 21:case 22: //coun tdow n_hour =zancun1;coun tdow n_minute =za ncun2;coun tdow n_sec ond =za ncun3;flagl =21;break;case 23:case 24: //秒表复位flag1 =24;msec ond_minute =0;msecond_second =0;msec on d_msec ond =0;break;case 25:zancun1 ++;if (zancun1 ==100){zancun1 =0;zancun2 ++;if (zancun2 ==100){zancun2 =0;zancun3 ++;}}break;default : break;}while (s3_bit ==0){ _judge_dis();}〃等待按键释放}}} //显示处理函数void judge_clock() {zancun4 =hour_count &0xf0;zancun4 >>=4;zancun6 =hour_count &0x0f;zancun4 *=10;zancun4 +=za ncun6;zancun5=minute_count &0xf0;if (san ==1){zancun5 >>=4;zancun6 =minute_count &0x0f;zancun5 *=10;zancun5 +=za ncun6;if (msecond_count<=5) {speak =0; speak_co unt ++;}else{speak =1;}}else{speak =1;}}〃****************************************////闪烁显示子程序void dis_sa n( uchar s6,uchar s5,uchar s4,uchar s3,uchars1,uchar san){if (clock_hour ==zancun4 &&clock_minute ==zancun5){ 一 一if (clock_en { _ speak_co unt clock_flag speak_co unt} _ } else{clock_flag =0;} _if{ (clock_flag ==1 ==1&&clock_flag ==0)=0; //开启蜂鸣器=1;=0;&&speak_count <400)s2,ucharif (msecond_count<5) { _ display1(s6);}}else{display1(s6);}if (san ==2){if (msecond_count<5) { _ display2(s5);}}else{display2(s5);}if (san ==3){if (msecond_count<5) { _ display3(s4);}}else{display3(s4);}if (san ==4){if (msecond_count<5) { _ display4(s3);}}else{display4(s3);}if (san ==5){if (msecond_count<5){ _ display5(s2);}}else{display5(s2);}if (san ==6){if (msecond_count<5){ _ display6(s1);}}else{ display6(s1);}}〃****************************************//时钟显示程序void dis(uchar s6,uchar s5,uchar s4,uchar s3,uchar s2,uchar s1) { display1(s6);display2(s5);display3(s4);display4(s3);display5(s2);display6(s1);}〃********************************************************************************************void init_tO(){ _TMOD0x01;〃设定定时器工作方式1,定时器定时50毫秒TH0=(65536-50000)/256;TL0=(65536- 50000)%256;EA=1; //开总中断ET0=1; //允许定时器0中断t0_crycle =0; //定时器中断次数计数单元}//LED处理函数void dis_led(){if (msecond_count<5){ _Ied1_bit =1;Ied2_bit =1;}else{led1_bit =0;led2_bit =0;}}〃***************************************************************//功能:把数据1显示在数码管1上void display6(uchar dis_data){ _smg_data =tabl1[dis_data]; // 送显示断码dis_bit6 =0; // 锁存数据delay_50us(40); dis_bit6 =1;}〃***************************************************************//功能:把数据1显示在数码管1上void display5(uchar dis_data){ _smg_data =tabl1[dis_data]; // 送显示断码dis_bit5 =0; // 锁存数据delay_50us(40);dis_bit5 =1;} _〃***************************************************************//功能:把数据1显示在数码管1上void display4(uchar dis_data){ _smg_data =tabl1[dis_data]; // 送显示断码dis_bit4 =0; // 锁存数据delay_50us(40);dis_bit4 =1;} 〃***************************************************************//功能:把数据1显示在数码管1上void display3(uchar dis_data){ _smg_data =tabl1[dis_data]; // 送显示断码dis_bit3 =0; // 锁存数据delay_50us(40);dis_bit3 =1;}〃***************************************************************//功能:把数据1显示在数码管1上void display1(uchar dis_data){ _smg_data =tabl1[dis_data]; // 送显示断码dis_bit1 =0; // 锁存数据delay_50us(40);dis_bit1 =1;}〃***************************************************************//功能:把数据1显示在数码管1上void display2(uchar dis_data){ _smg_data =tabl1[dis_data]; // 送显示断码dis_bit2 =0; // 锁存数据delay_50us(40);dis_bit2 =1;}〃******************************************************************* *******************************// 函数名称:void delay_50US(unsigned int t)//功能:延时50*t(us)void delay_50us(uint t){ _unsigned char j;for (;t >0;t --){for (j =19;j >0;j --);}}〃******************************************************************* ************〃8微秒延时基准程序void delay_8us(uint t){while (-- t);}************〃3微秒延时程序void delay_3us() {}〃******************************************************************* ************//子程序功能:向DS18B2写一字节的数据void w_1byte_ds18b20(uchar value){uchar i =0;for (i =0;i <8;i ++){dq_ds18b20 =1;delay_3us();dq_ds18b20 =0; delay_8us(2);if ( value & 0x01) dq_ds18b20 =1; 〃DQ = 1 delay_50us(1); // 延时50us 以上delay_8us(2);value >>=1;}dq_ds18b20 =1; //DQ = 1}//读一个字节uchar r_1byte_ds18b20( void){ 一一uchar i =0;uchar value = 0;for (i =0;i <8;i ++){value >>=1;dq_ds18b20 =0;// DQ_L;delay_3us();dq_ds18b20 =1; 〃DQ_H;delay_8us(2);if (dq_ds18b20==1) value |= 0x80;delay_8us(6); // 延时40us}dq_ds18b20 =1;return value ;}11 ・**************************************************〃ds18b20复位子程序void rest_ds18b20( void){rest:delay_3us(); // 稍做延时delay_3us();dq_ds18b20 =1;delay_3us();dq_ds18b20 =0;// DQ_L; delay_50us(11); 〃480us<T<960usdq_ds18b20 =1; // 拉高总线delay_8us(5);if (dq_ds18b20==1){return ;}delay_50us(2); // 延时90usif (dq_ds18b20==1){return ;}else{goto rest;}}〃****************************************************//读取温度void readtemp_ds18b20( void){ _uchar temp32;rest_ds18b20();w_1byte_ds18b20(0xcc); //跳过读序列号的操作w_1byte_ds18b20(0x44); // 启动温度转换delay_8us(2);rest_ds18b20();w_1byte_ds18b20(0xcc); //跳过读序列号的操作w_1byte_ds18b20(0xbe); //读取温度寄存器等(共可读9个寄存器)前两个就是温度templ =r_1byte_ds18b20();temph =r_1byte_ds18b20();if ((temph &0xf0)) //判断温度的正负性{temp_flag =0; //温度为负数标志temph =-temph;tempi =-templ;t_x =tabl3[templ & OxOf]; // 计算温度的小数temp32 =temph & OxOf;temp32 <<=4;tempi >>=4;temp32 =temp32 | tempi;t_b =temp32/100%10; //计算温度的百位数据t_s =temp32/10%0;〃计算温度的十位数据t_g =temp32%0;〃计算温度的个位数据5else //为正数{t_x =tabl3[templ & 0x0f]; // 计算温度的小数temp32 =temph & 0x0f;temp32 <<=4;templ >>=4;temp32 =temp32 | templ;t_b =temp32/100%10; //计算温度的百位数据t_s =temp32/10%0;〃计算温度的十位数据t_g =temp32%0;〃计算温度的个位数据temp_flag =1;} _}void dis_temp() //温度显示函数{ _if (temp_flag =1){ _if (t_b ==0){dis(12,12,t_s,t_g,13,12);}else{dis(12,t_b,t_s,t_g,13,12);}}else{dis(14,t_b,t_s,t_g,13,12);}}/ / """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" / / , ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ############ //;子程序名:w_1byte_ds1302//;功能:向DS130写一个字节的数据void w_1byte_ds1302(uchar t){uchar i;for (i =0;i <8;i ++){if (t & 0x01){io_ds1302=1;}else{io_ds1302 =0;}clk_ds1302 =1;delay_3us();delay_3us();clk_ds1302 =0;delay_3us();delay_3us();t >>=1;}}/ / , ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ######//;子程序名:r_1byte_ds1302()//;功能:从DS130读一个字节的数据uchar r_1byte_ds1302(){ 一一uchar i,temp11 =0;io_ds1302 =1;//置10为1,准备读入数据for (i =0;i <8;i ++){temp11 >>=1;if (io_ds1302) temp11 |= 0x80;clk_ds1302 =1;delay_3us();delay_3us();clk_ds1302 =0;delay_3us();}return (temp11);}/ / """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""/ / , JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ JJ """""""""""""""ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff//;子程序名:setbds1302//;功能:设置DS130初始时间,并启动计时void set_ds1302(){uchar i,j;rest_ds1302 =0;delay_3us();clk_ds1302 =0;delay_3us();rest_ds1302 =1;delay_3us();w_1byte_ds1302(0x8e); // 写控制命令字delay_3us();w_1byte_ds1302(0x00); // 写保护关闭clk_ds1302 =1;delay_3us();for (i =0,j =0x80;i <7;i ++,j +=2){rest_ds1302 =0;delay_3us();clk_ds1302 =0;delay_3us();rest_ds1302 =1;delay_3us();w_1byte_ds1302(j);delay_3us();w_1byte_ds1302(tab23[i]);delay_3us();delay_3us();clk_ds1302 =1;delay_3us();rest_ds1302 =0;delay_3us();delay_3us();} _rest_ds1302 =0;delay_3us();clk_ds1302 =0;delay_3us();rest_ds1302 =1;delay_3us();w_1byte_ds1302(0x8e); delay_3us();w_1byte_ds1302(0x80); clk_ds1302 =1;delay_3us();rest_ds1302 =0;delay_3us();}/ / """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" / / , ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff //;子程序名:get1302void get_ds1302(){ _uchar temp11[7],i,j;for (i =0;i <7;i ++){temp11[i] =0;}for (i =0,j =0x81;i <7;i ++,j +=2){rest_ds1302 =0;delay_3us();clk_ds1302 =0;delay_3us();delay_3us();w_1byte_ds1302(j);temp11[i] =r_1byte_ds1302();delay_3us();clk_ds1302 =1;delay_3us();rest_ds1302 =0;delay_3us();} _if (temp11[0] != 0xff){second_count =temp11[0]; }if (temp11[1] != 0xff) // 数据验证{minute_count =temp11[1]; }if (temp11[2] != 0xff) // 数据验证{hour_count =temp11[2]; }// date=temp[3];//mon th=temp[4];// week=temp[5];//year=temp[6];}/*===================================================================调试要求:1. MCU:AT89S52 芯片或AT89C522. 晶振:12MHz功能:多功能时钟+温度计/#inelude <reg52. h>#inelude vintrins . h>sbit dis_bit1 =P2A 7; //定义数码管控制口sbit dis_bit2 =卩2八6;//定义数码管控制口sbit dis_bit3 =卩2八4;//定义数码管控制口sbit dis_bit4 =卩2八3;//定义数码管控制口sbit dis_bit5 =卩2八1; //定义数码管控制口sbit dis_bit6 =P2A0; //定义数码管控制口sbit led1_bit =卩2八2; // 定时 LED 勺控制口sbit led2_bit =卩2八5; // 定时 LED 勺控制口sbit s1_bit =P1A0; // 定义S1 控制口sbit s2_bit =P01; // 定义 S2空制口sbit s3_bit =P02; // 定义 S3控制口sbit dq_ds18b20 =P3A3;// 定义控制 DS18B20 sbit speak =P3A7; //定义蜂鸣器控制口sbit clk_ds1302 =P3A6; // 定义控制 DS1302勺时钟线 sbit io_ds1302 =P3A5;//定义控制DS1302勺串行数据sbit rest_ds1302 =P3A4;#define smg_data P0 //定义数码管数据口 void delay_3us(); //3US 的延时程序 void delay_8us(ui nt t); //8US 延时基准程序void delay_50us(ui nt t); // void display1(uehardis_data); voiddisplay2(uehar dis_data); void display3(uehar dis_data); void display4(uehar dis_data); void display5(uehar dis_data); void display6(uehar dis_data);void init_t0(); //定时器0初始化函数void dis_led(); //LED 处理函数void judge_s1();//S1 按键处理函数 void judge_s2(); //S2 按键处理函数void judge_s3(); //S3 按键处理函数 void dis(uehar s6,uehar s5,uehar s4,uehar s3,uehar s2,uehar s1); 示子程序 void dis_sa n( uchar s6,uehar s5,uehar s4,uehar s3,uehars1,uchar san); 〃闪烁显示子程序void judge_dis(); //显示处理函数void judge_clock(); // 显示处理函数void set_ds1302(); // 设置时间void get_ds1302(); // 读取当前时间#define uehar#define uintunsigned char unsigned int延时50*T 微妙函数的声明//数码管1显示子程序 //数码管2显示子程序 //数码管3显示子程序//数码管4显示子程序//数码管5显示子程序//数码管6显示子程序 //显s2,ueharvoid w_1byte_ds1302(uchar t); // 向DS130写一个字节的数据uchar r_1byte_ds1302(); // 从DS130读一个字节的数据〃*******************************************************************//DS18B20测温函数定义void w_1byte_ds18b20(uchar value); // 向DS18B2写一个字节ucharr_1byte_ds18b20( void ); // 从DS18B2读取一个字节的数据voidrest_ds18b20( void ); //DS18B20复位程序void readtemp_ds18b20( void ); // 读取温度void dis_temp(); //温度显示函数//共阳数码管断码表const uchar tabl1[16] ={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,// 0 1 2 3 4 50x82,0xf8,0x80,0x90,0x86,0x87,0xFF,//6 7 8 9 E T B0xc6,0xbf,0xff };// C -const uchar tabl3[] ={ 0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09 };uchar t0_crycle;uchar hour_co un t, minu te_c oun t,sec on d_co un t,msec ond_count;uchar clock_hour,clock_m inu te;uchar coun tdow n_sec ond;uchar coun tdow n_hour,co un tdow n_min ute;uchar clock_en; //闹钟关闭和开启的标志,1开启,0关闭uchar flag1,sec on d_flag,za ncun 1,za ncun 2,za ncun3;uchar zancun4 ,za ncun 5,za ncun 6,za ncun7;uchar clock_flag,co un tdow n_flag;uchar msec on d_mi nute,msec on d_sec on d,mseco nd_mseco nd,mseco nd_flag; // 秒表相关参数uint speak_c ount;uchar templ,temph,temp_flag;uchar t_b,t_s,t_g,t_x,temp_flag2; //从左到右分别存储温度百位,十位,个位,小数位上电时默认的uchar tab23[3]; 〃二{0x40,0x59,0x23,0x28,0x11,0x06,0x09};//时间//主程序void main(){P3 =0x00;flag1 =0;zancun3 =0;msecond_minute =0; //置秒表相关参数为0msecond_second =0;msec on d_msec ond =0;speak =1;//关闭蜂鸣器speak_co unt =0;clock_hour =0;clock_m inute =0;clock_flag =0;countdown_flag =0; //倒计时标志位为0clock_en =0;//开机时默认关闭闹钟ini t_t0();TR0 =1;//// set_ds1302();〃设置DS130的初始时间//接下来开始编写让数码管显示的程序while (1){get_ds1302();judge_dis(); // 显示处理judge_s1();judge_s2();judge_s3();judge_clock(); //闹钟处理程序} _}void timer0() interrupt 1{TH0=(65536-50000)/256;TL0=(65536- 50000)%256;t0_crycle ++;if (t0_crycle ==2) // 0.1 秒{t0_crycle =0;msec on d_flag =1;msec ond_count ++;if (msecond_count==10)//1 秒。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

以下为AVR系列单片机之ATMAGE128单片机写的程序,可以实现读取DS1302/18B02数据并在LCD1602显示,代码简单,易懂,给想想学1302/18C02/1602的朋友分一下,关健之处在于本程备注清晰,如果想学的朋友可以和小弟联系,一块学习!/********************************************************项目名称: 读取DS18B20温度/DS1302时间,通过1602液晶显示。

说明:CPU型号: Atmage128A主频: 12MHz日期:2013/08/20联系方法: ************************************************************************************/#include <avr/io.h>#include <avr/interrupt.h>///DS18B20宏定义#define DE0 DDRE &= 0xbf //设置输入#define DE1 DDRE |= 0x40 //设置输出#define E0 PORTE &= 0xbf //置低电平#define E1 PORTE |= 0x40 //置高电平#define PIN PINE & 0x40 //读了电平//LCD1602宏定义#define EN_1 PORTB |= 1<<PD7#define EN_0 PORTB &= ~(1<<PD7)//LCD读写控制引脚#define RW_1 PORTB |= 1<<PD6#define RW_0 PORTB &= ~(1<<PD6)//LCD指令或数据选择引脚#define RS_1 PORTB |= 1<<PD5#define RS_0 PORTB &= ~(1<<PD5)#define maichong EN_1,delay_ms(1),EN_0//////////////////////////////////////////////////////////////////#define ds1302_rst1 PORTE |= 1<<PE4 //复位端置1#define ds1302_rst0 PORTE &= ~(1<<PE4) //复位端清0#define ds1302_io_DDR1 DDRE |= 1<<PE3 //数据端置为输出#define set_ds1302_io PORTE |= 1<<PE3 //数据端置1#define clr_ds1302_io PORTE &= ~(1<<PE3) //数据端清0#define clr_ds1302_io_DDR0 DDRE &= ~(1<<PE3) //数据端置为输入#define in_ds1302_io PINE & (1<<PE3) //数据端输入数据#define set_ds1302_sclk_DDR1 DDRE|=1<<PE2 //时钟端置为输出#define set_ds1302_sclk PORTE|=1<<PE2 //时钟端置1#define clr_ds1302_sclk PORTE &=~(1<<PE2) //时钟端清#define miao 0x80 //秒数据地址#define fen 0x82 //分数据地址#define shi 0x84 //时数据地址#define ri 0x86 //日数据地址#define yue 0x88 //月数据地址#define zhou 0x8a //星期数据地址#define nian 0x8c //年数据地址#define ds1302_control_add 0x8e //控制数据地址#define ds1302_charger_add 0x90#define ds1302_clkburst_add 0xbe/****************************/unsigned char Table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};unsigned char duanma[] ={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; unsigned char DS18B20_temperature[5];unsigned char s[32];unsigned char timer[8]; //时钟数据unsigned int temperature;void delay_us(unsigned char i){for(;i;i--);}void delay_ms(unsigned int i) //在1M时钟下为i ms{unsigned char j;for(;i;i--)for(j=220;j;j--);}/************************************** DS1302操作函数组**************************************///写入1302数据函数://入口:add为写入地址码,data为写入数据//返回:无void ds1302_write(unsigned char add,unsigned char data){unsigned char i=0;ds1302_io_DDR1; //配置IO为输出delay_us(20);ds1302_rst0; //清复位,停止所有操作delay_us(20);clr_ds1302_sclk; //清时钟,准备操作delay_us(20);ds1302_rst1; //置复位,开始操作delay_us(20);for(i = 8; i > 0; i--) //此循环写入控制码{if(add & 0x01)set_ds1302_io; //当前位为1,置数据位elseclr_ds1302_io; //当前位为0,清数据位delay_us(20);set_ds1302_sclk; //产生时钟脉冲,写入数据delay_us(1);clr_ds1302_sclk;delay_us(20);add >>= 1; //移位,准备写入下1位}for(i=8;i>0;i--) //此循环写入数据码{if(data & 0x01)set_ds1302_io;elseclr_ds1302_io;delay_us(20);set_ds1302_sclk;delay_us(20);clr_ds1302_sclk;delay_us(20);data>>=1;}ds1302_rst0;delay_us(20);clr_ds1302_io_DDR0; //清输出状态delay_us(20);}//从1302中读出数据://入口:add为读数据所在地址//返回:读出的数据dataunsigned char ds1302_read(unsigned char add){unsigned char data = 0;unsigned char i = 0;add += 1; //读标志ds1302_io_DDR1; //端口输出delay_us(20);ds1302_rst0;; //清复位delay_us(20);clr_ds1302_sclk; //清时钟delay_us(20);ds1302_rst1; //置复位delay_us(20);for(i = 8; i > 0; i--) //此循环写入地址码{if(add&0x01) {set_ds1302_io;}else {clr_ds1302_io;}delay_us(20);set_ds1302_sclk;delay_us(20);clr_ds1302_sclk;delay_us(20);add >>= 1;}clr_ds1302_io_DDR0; //端口输入delay_us(20);for(i = 8; i > 0; i--) //此循环读出1302的数据{data>>=1;if(in_ds1302_io){data|=0x80;}delay_us(20);set_ds1302_sclk;delay_us(20);clr_ds1302_sclk;delay_us(20);}ds1302_rst0;delay_us(20);return(data);}//检查1302状态// unsigned char check_ds1302(void)// {// ds1302_write(ds1302_control_add,0x80);// if(ds1302_read(ds1302_control_add) == 0x80)// return 1;// return 0;// }//向1302中写入时钟数据void ds1302_write_time(void){ds1302_write(ds1302_control_add,0x00); //关闭写保护ds1302_write(miao,0x80); //暂停ds1302_write(ds1302_charger_add,0xa9); //涓流充电ds1302_write(nian,timer[0]); //年ds1302_write(yue, timer[1]); //月ds1302_write(ri, timer[2]); //日ds1302_write(zhou,timer[3]); //周ds1302_write(shi, timer[4]); //时ds1302_write(fen, timer[5]); //分ds1302_write(miao,timer[6]); //秒ds1302_write(ds1302_control_add,0x80); //打开写保护}void ds_1302_read_time(void) //从1302中读出当前时钟{timer[0] = ds1302_read(nian); //读年timer[1] = ds1302_read(yue); //读月timer[2] = ds1302_read(ri); //读日timer[3] = ds1302_read(zhou); //读周timer[4] = ds1302_read(shi); //读时timer[5] = ds1302_read(fen); //读分timer[6] = ds1302_read(miao); //读秒s[12] = ((timer[0] & 0xf0)>>4) + 0x30; //年转换s[11] = (timer[0] & 0x0f) + 0x30; //年转换s[10] = ((timer[1] & 0xf0)>>4) + 0x30; //月转换s[9] = (timer[1] & 0x0f) + 0x30; //月转换s[8] = ((timer[2] & 0xf0)>>4) + 0x30; //日转换s[7] = (timer[2] & 0x0f) + 0x30; //日转换s[6] = (timer[3] & 0x0f) + 0x30; //周转换s[5] = ((timer[4] & 0xf0)>>4) + 0x30; //时转换s[4] = (timer[4] & 0x0F) + 0x30; //时转换s[3] = ((timer[5] & 0xF0)>>4) + 0x30; //分转换s[2] = (timer[5] & 0x0F) + 0x30; //分转换s[1] = ((timer[6] & 0xF0)>>4) + 0x30; //秒转换s[0] = ((timer[6] & 0x0F) + 0x30); //秒转换}DS1302_time_init(){timer[0] = 0X13; //写年timer[1] = 0X09; //写月timer[2] = 0X04; //写日timer[3] = 0X03; //写周timer[4] = 0X01; //写时timer[5] = 0X41; //写分timer[6] = 0X50; //写秒}/*************************************** 扫描显示函数组***************************************///延时函数1//////////////////////////////////////////////////////////////////void MCU_init(void) //单片机初初化程序{DDRE = 0xFF;PORTE = 0xff;DDRA = 0XFF; //LED IO口设为输出PORTA = 0XFF;DDRB &= 0xEf;EN_1;RW_1;RS_1;}void LCD_init(void) //LCD1602液晶初始化{delay_ms(1);DDRA = 0xFF;DDRB |= 0xe0; //端口B5、6、7、置为输出write_onechar(0x38,0); //高置显示格式为16*2个字符5*7点阵write_onechar(0x01,0); //01清屏指行令write_onechar(0x0F,0); //显示关闭0000 1DCB D显示开关,C光标显示开关,B 光标闪烁开关*/write_onechar(0x06,0); //显示光标移动设置*/delay_ms(1);write_onechar(0x0C,0); //显示开机光标设置*/}//////////////////////////////////void LCD_ready(void) /*功能描述:判断LCD忙标志*/{DDRA = 0X00; //D7设为输判断LCD忙标志//1为忙入,准备0为空闲RS_0;RW_1; //读EN_1;delay_ms(2);while(PINC & 0X80);EN_0;RS_1;DDRA=0xFF;}void LCD_xieshuju(unsigned char X,unsigned char Y,unsigned char *string)//X坐标位置,Y坐标位置,*string要写的内容{unsigned char address;if (Y == 0) address = 0x80 + X; //第一行X列else address = 0xc0 + X; //第二行X列write_onechar( address, 0 );while (*string){write_onechar(0,*string );string ++; //指向下一显示字符地址}}void write_onechar(unsigned char COMM,unsigned char DA T){LCD_ready(); //等待LCD空闲RW_0; //写if(COMM == 0) //写数据{RS_1; //RS高电平向LCD写数据PORTA=DAT;}else //写命令{RS_0;PORTA=COMM;}maichong;delay_ms(1);RW_1;RS_1;}////////////////////////////DS18B20复位函数DS18B20_reset(void){unsigned char i;DE1;E0;delay_us(500); /*延时500uS(480-960)*/E1;DE0;delay_us(500); /*延时500uS(保持>480uS)*/}DS18B20_read(){unsigned char i;unsigned char value = 0;for (i = 8; i != 0; i--){value >>= 1;DE1;E0;asm("nop"); /*延时4uS*/asm("nop");asm("nop");asm("nop");E1;DE0;delay_us(1); /*延时10uS*/if (PIN)value |= 0x80;delay_us(50); /*延时60uS*/}return(value);}void DS18B20_write(unsigned char value){unsigned char i;for (i = 8; i != 0; i--){DE1;E0;asm("nop");asm("nop");asm("nop");asm("nop"); /*延时4uS*/if (value & 0x01) E1;delay_us(70); /*延时80uS*/E1; /*位结束*/value >>= 1;}}unsigned int DS18B20_read_temperature(void){unsigned int i;unsigned char buf[9];unsigned char DS18B20_temperature[5];DS18B20_reset();DS18B20_write(0xCC); /*勿略地址*/DS18B20_write(0xBE); /*读取温度*/for(i = 0; i < 9; i++){buf[i] = DS18B20_read();}i = buf[1];i <<= 8;i |= buf[0];return i;}DS18B20_zhuanhuan(){DS18B20_reset(); //DS18B20_write(0xCC); //勿略地址DS18B20_write(0x44); //启动转换temperature = DS18B20_read_temperature();temperature = (temperature*100) >> 4;DS18B20_temperature[4] =temperature/10000, temperature = temperature%10000;DS18B20_temperature[3] =temperature/1000, temperature = temperature%1000;DS18B20_temperature[2] =temperature/100, temperature = temperature%100;DS18B20_temperature[1] =temperature/10, temperature = temperature%10;DS18B20_temperature[0] =temperature%10;}void main(void){unsigned int m;unsigned long i,i1;unsigned char start1[]={" 2013/08/31 6 "};unsigned char start2[]={" I LOVE YOU "};MCU_init;LCD_init();DS18B20_reset(); //复位D18B20write_onechar(0X01,0);LCD_xieshuju(0,1,start1);delay_ms(5000);LCD_xieshuju(0,1,start2);delay_ms(100000);DS1302_time_init();//ds1302_write_time(); //写入初始时钟while(1){DS18B20_zhuanhuan(); //启动转换ds_1302_read_time(); //读出当前时钟write_onechar(0x80,0); //首地址write_onechar(0,0x32); //01----2write_onechar(0,0x30); //02----0write_onechar(0,s[12]); //03----1write_onechar(0,s[11]); //04----3write_onechar(0,0x2F); //05----/write_onechar(0,s[10]); //06----0write_onechar(0,s[9]); //07----8write_onechar(0,0x2F); //08----/write_onechar(0,s[8]); //09----3write_onechar(0,s[7]); //09----1write_onechar(0,0X20); //10write_onechar(0,s[6]); //11----5write_onechar(0,0x20);write_onechar(0,0x36);write_onechar(0,0x38);write_onechar(0xC0,0);write_onechar(0,s[5]); //12write_onechar(0,s[4]); //13write_onechar(0,0X3A); //14write_onechar(0,s[3]); //15write_onechar(0,s[2]); //16write_onechar(0,0X3A); //读出当前时钟write_onechar(0,s[1]); //读出当前时钟write_onechar(0,s[0]); //读出当前时钟if(DS18B20_temperature[4] == 0) write_onechar(0,0x20);else write_onechar(0,DS18B20_temperature[4]+0x30);write_onechar(0,DS18B20_temperature[3]+0x30);write_onechar(0,DS18B20_temperature[2]+0x30);write_onechar(0,0X2E);write_onechar(0,DS18B20_temperature[1]+0x30);write_onechar(0,DS18B20_temperature[0]+0x30);write_onechar(0,0xdf);write_onechar(0,0x43);write_onechar(0X80,0);}}。

相关文档
最新文档