- 打卡等级:偶尔看看I
 
				- 打卡总天数:12
 
				
				
				- 最近打卡:2023-12-18 15:13:58
 
				  
高级会员 
 
 
	- 积分
 - 886
 
 
 
 
 | 
 
STC8H3K64S2单片机芯片+OLED12832+DS3231+USB时间校准, 
18B20---小巧时钟时钟所有资料在附件,欢迎学习交流! 
 
先看制作出来的实物: 
 
 
 
 
 
 
 
可以插手机充电器,也可以插电脑USB,也可以插tpye-c手机数据线进行供电及时间校准。校准用串口助手。 
有温度,时间,日期,星期显示。特点是小巧,可视角度大。亮度高,可以在代码里设置时间关屏幕。 
电路原理图: 
 
 
 
 
PCB图: 
 
 
 
 
 
 
部分单片机代码: 
- #include "STC8xxxx.H"
 - #include "oled.h"
 - #include "bmp.h"
 - #include        "config.h"
 - #include        "gpio.h"
 - #include        "delay.h"
 - #include<intrins.h>
 - #include<stdlib.h>
 - #define uchar unsigned char
 - #define uint unsigned int
 - /*实物端口定义*/
 - sbit DQ=P3^7;                                 //18b20
 - sbit TSDA=P1^2;                             //ds32321            //模拟I2C数据传送位SDA
 - sbit TSCL=P1^1;                                                                           //模拟I2C时钟控制位SCL
 - sbit SDA=P3^4;                             //OLED12832            //模拟I2C数据传送位SDA
 - sbit SCL=P3^3;                                  //模拟I2C时钟控制位SCL
 - sbit bg=P3^2;    //控制OLED打开与关闭;
 - //***按键功能****//
 - ////***K1停止时间显示****//
 - ////***K2选择修改位置****//
 - ////***K3进行加1的修改****//
 - ////***K4将修改写入ds3231,同时启动时间显示****//
 -    sbit K1=P1^0;
 -    sbit K2=P1^6;
 -    sbit K3=P1^7;
 -    sbit K4=P5^4;
 - /*开发板端口定义*/
 - //sbit LCD_RS=P3^5;
 - //sbit LCD_RW=P3^6;
 - //sbit LCD_EN=P3^4;
 - //sbit LCD_PSB=P2^3;
 - //sbit DQ=P2^2;                                 //18b20
 - //sbit SDA=P1^0;                             //ds32321            //模拟I2C数据传送位SDA
 - //sbit SCL=P1^1;
 - //sbit bg=P2^4;                                  //模拟I2C时钟控制位SCL
 - ////***按键功能****//
 - //////***K1停止时间显示****//
 - //////***K2选择修改位置****//
 - //////***K3进行加1的修改****//
 - //////***K4将修改写入ds3231,同时启动时间显示****//
 - //sbit K1=P3^0;
 - //sbit K2=P3^1;
 - //sbit K3=P3^2;
 - //sbit K4=P3^3;
 - //定义变量
 - uchar numbr[10]="0123456789";                        //字模
 - uchar i=0;
 - bit        flag=0,flag1=0;  //串口接收完成标志
 - uchar dis4[]="   ";                                                           //          第四行显示   自己添加
 - uchar t[]="  . ℃" ;                                          //18b20
 - uint  sdata,xiaoshu1,xiaoshu2;                                  //整数、小数1位、小数2位
 - bit  fg=1;                                   //温度正负标志
 - uchar tempL=0,tempH=0;                                                           // 变量
 - uchar year,month,date,hour,min,sec,day;                                 //        ds3231
 - uchar a[]="2021.01.31";
 - uchar b[]="16时20分00秒";
 - uchar c[]="周一周二周三周四周五周六周日";
 - uchar ndate,nmonth,nyear;
 - uchar buffer[21]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  //设置数据串口接收缓存数组 7e开头  0d结尾  一共有15个字节
 -       /*农历、、、、*/
 -           struct SPDATE {  //阴历结构体
 -    uchar year;  //年
 -     uchar mon;   //月
 -     uchar day;   //日
 - };
 -           struct SPDATE SpDate;//阴历
 - /********阳历转换阴历表************************************/
 - code uchar year_code[597]={
 -                     0x04,0xAe,0x53,    //1901 0
 -                     0x0A,0x57,0x48,    //1902 3
 -                     0x55,0x26,0xBd,    //1903 6
 -                     0x0d,0x26,0x50,    //1904 9
 -                     0x0d,0x95,0x44,    //1905 12
 -                     0x46,0xAA,0xB9,    //1906 15
 -                     0x05,0x6A,0x4d,    //1907 18
 -                     0x09,0xAd,0x42,    //1908 21
 -                     0x24,0xAe,0xB6,    //1909
 -                     0x04,0xAe,0x4A,    //1910
 -                     0x6A,0x4d,0xBe,    //1911
 -                     0x0A,0x4d,0x52,    //1912
 -                     0x0d,0x25,0x46,    //1913
 -                     0x5d,0x52,0xBA,    //1914
 -                     0x0B,0x54,0x4e,    //1915
 -                     0x0d,0x6A,0x43,    //1916
 -                     0x29,0x6d,0x37,    //1917
 -                     0x09,0x5B,0x4B,    //1918
 -                     0x74,0x9B,0xC1,    //1919
 -                     0x04,0x97,0x54,    //1920
 -                     0x0A,0x4B,0x48,    //1921
 -                     0x5B,0x25,0xBC,    //1922
 -                     0x06,0xA5,0x50,    //1923
 -                     0x06,0xd4,0x45,    //1924
 -                     0x4A,0xdA,0xB8,    //1925
 -                     0x02,0xB6,0x4d,    //1926
 -                     0x09,0x57,0x42,    //1927
 -                     0x24,0x97,0xB7,    //1928
 -                     0x04,0x97,0x4A,    //1929
 -                     0x66,0x4B,0x3e,    //1930
 -                     0x0d,0x4A,0x51,    //1931
 -                     0x0e,0xA5,0x46,    //1932
 -                     0x56,0xd4,0xBA,    //1933
 -                     0x05,0xAd,0x4e,    //1934
 -                     0x02,0xB6,0x44,    //1935
 -                     0x39,0x37,0x38,    //1936
 -                     0x09,0x2e,0x4B,    //1937
 -                     0x7C,0x96,0xBf,    //1938
 -                     0x0C,0x95,0x53,    //1939
 -                     0x0d,0x4A,0x48,    //1940
 -                     0x6d,0xA5,0x3B,    //1941
 -                     0x0B,0x55,0x4f,    //1942
 -                     0x05,0x6A,0x45,    //1943
 -                     0x4A,0xAd,0xB9,    //1944
 -                     0x02,0x5d,0x4d,    //1945
 -                     0x09,0x2d,0x42,    //1946
 -                     0x2C,0x95,0xB6,    //1947
 -                     0x0A,0x95,0x4A,    //1948
 -                     0x7B,0x4A,0xBd,    //1949
 -                     0x06,0xCA,0x51,    //1950
 -                     0x0B,0x55,0x46,    //1951
 -                     0x55,0x5A,0xBB,    //1952
 -                     0x04,0xdA,0x4e,    //1953
 -                     0x0A,0x5B,0x43,    //1954
 -                     0x35,0x2B,0xB8,    //1955
 -                     0x05,0x2B,0x4C,    //1956
 -                     0x8A,0x95,0x3f,    //1957
 -                     0x0e,0x95,0x52,    //1958
 -                     0x06,0xAA,0x48,    //1959
 -                     0x7A,0xd5,0x3C,    //1960
 -                     0x0A,0xB5,0x4f,    //1961
 -                     0x04,0xB6,0x45,    //1962
 -                     0x4A,0x57,0x39,    //1963
 -                     0x0A,0x57,0x4d,    //1964
 -                     0x05,0x26,0x42,    //1965
 -                     0x3e,0x93,0x35,    //1966
 -                     0x0d,0x95,0x49,    //1967
 -                     0x75,0xAA,0xBe,    //1968
 -                     0x05,0x6A,0x51,    //1969
 -                     0x09,0x6d,0x46,    //1970
 -                     0x54,0xAe,0xBB,    //1971
 -                     0x04,0xAd,0x4f,    //1972
 -                     0x0A,0x4d,0x43,    //1973
 -                     0x4d,0x26,0xB7,    //1974
 -                     0x0d,0x25,0x4B,    //1975
 -                     0x8d,0x52,0xBf,    //1976
 -                     0x0B,0x54,0x52,    //1977
 -                     0x0B,0x6A,0x47,    //1978
 -                     0x69,0x6d,0x3C,    //1979
 -                     0x09,0x5B,0x50,    //1980
 -                     0x04,0x9B,0x45,    //1981
 -                     0x4A,0x4B,0xB9,    //1982
 -                     0x0A,0x4B,0x4d,    //1983
 -                     0xAB,0x25,0xC2,    //1984
 -                     0x06,0xA5,0x54,    //1985
 -                     0x06,0xd4,0x49,    //1986
 -                     0x6A,0xdA,0x3d,    //1987
 -                     0x0A,0xB6,0x51,    //1988
 -                     0x09,0x37,0x46,    //1989
 -                     0x54,0x97,0xBB,    //1990
 -                     0x04,0x97,0x4f,    //1991
 -                     0x06,0x4B,0x44,    //1992
 -                     0x36,0xA5,0x37,    //1993
 -                     0x0e,0xA5,0x4A,    //1994
 -                     0x86,0xB2,0xBf,    //1995
 -                     0x05,0xAC,0x53,    //1996
 -                     0x0A,0xB6,0x47,    //1997
 -                     0x59,0x36,0xBC,    //1998
 -                     0x09,0x2e,0x50,    //1999 294
 -                     0x0C,0x96,0x45,    //2000 297
 -                     0x4d,0x4A,0xB8,    //2001
 -                     0x0d,0x4A,0x4C,    //2002
 -                     0x0d,0xA5,0x41,    //2003
 -                     0x25,0xAA,0xB6,    //2004
 -                     0x05,0x6A,0x49,    //2005
 -                     0x7A,0xAd,0xBd,    //2006
 -                     0x02,0x5d,0x52,    //2007
 -                     0x09,0x2d,0x47,    //2008
 -                     0x5C,0x95,0xBA,    //2009
 -                     0x0A,0x95,0x4e,    //2010
 -                     0x0B,0x4A,0x43,    //2011
 -                     0x4B,0x55,0x37,    //2012
 -                     0x0A,0xd5,0x4A,    //2013
 -                     0x95,0x5A,0xBf,    //2014
 -                     0x04,0xBA,0x53,    //2015
 -                     0x0A,0x5B,0x48,    //2016
 -                     0x65,0x2B,0xBC,    //2017
 -                     0x05,0x2B,0x50,    //2018
 -                     0x0A,0x93,0x45,    //2019
 -                     0x47,0x4A,0xB9,    //2020
 -                     0x06,0xAA,0x4C,    //2021
 -                     0x0A,0xd5,0x41,    //2022
 -                     0x24,0xdA,0xB6,    //2023
 -                     0x04,0xB6,0x4A,    //2024
 -                     0x69,0x57,0x3d,    //2025
 -                     0x0A,0x4e,0x51,    //2026
 -                     0x0d,0x26,0x46,    //2027
 -                     0x5e,0x93,0x3A,    //2028
 -                     0x0d,0x53,0x4d,    //2029
 -                     0x05,0xAA,0x43,    //2030
 -                     0x36,0xB5,0x37,    //2031
 -                     0x09,0x6d,0x4B,    //2032
 -                     0xB4,0xAe,0xBf,    //2033
 -                     0x04,0xAd,0x53,    //2034
 -                     0x0A,0x4d,0x48,    //2035
 -                     0x6d,0x25,0xBC,    //2036
 -                     0x0d,0x25,0x4f,    //2037
 -                     0x0d,0x52,0x44,    //2038
 -                     0x5d,0xAA,0x38,    //2039
 -                     0x0B,0x5A,0x4C,    //2040
 -                     0x05,0x6d,0x41,    //2041
 -                     0x24,0xAd,0xB6,    //2042
 -                     0x04,0x9B,0x4A,    //2043
 -                     0x7A,0x4B,0xBe,    //2044
 -                     0x0A,0x4B,0x51,    //2045
 -                     0x0A,0xA5,0x46,    //2046
 -                     0x5B,0x52,0xBA,    //2047
 -                     0x06,0xd2,0x4e,    //2048
 -                     0x0A,0xdA,0x42,    //2049
 -                     0x35,0x5B,0x37,    //2050
 -                     0x09,0x37,0x4B,    //2051
 -                     0x84,0x97,0xC1,    //2052
 -                     0x04,0x97,0x53,    //2053
 -                     0x06,0x4B,0x48,    //2054
 -                     0x66,0xA5,0x3C,    //2055
 -                     0x0e,0xA5,0x4f,    //2056
 -                     0x06,0xB2,0x44,    //2057
 -                     0x4A,0xB6,0x38,    //2058
 -                     0x0A,0xAe,0x4C,    //2059
 -                     0x09,0x2e,0x42,    //2060
 -                     0x3C,0x97,0x35,    //2061
 -                     0x0C,0x96,0x49,    //2062
 -                     0x7d,0x4A,0xBd,    //2063
 -                     0x0d,0x4A,0x51,    //2064
 -                     0x0d,0xA5,0x45,    //2065
 -                     0x55,0xAA,0xBA,    //2066
 -                     0x05,0x6A,0x4e,    //2067
 -                     0x0A,0x6d,0x43,    //2068
 -                     0x45,0x2e,0xB7,    //2069
 -                     0x05,0x2d,0x4B,    //2070
 -                     0x8A,0x95,0xBf,    //2071
 -                     0x0A,0x95,0x53,    //2072
 -                     0x0B,0x4A,0x47,    //2073
 -                     0x6B,0x55,0x3B,    //2074
 -                     0x0A,0xd5,0x4f,    //2075
 -                     0x05,0x5A,0x45,    //2076
 -                     0x4A,0x5d,0x38,    //2077
 -                     0x0A,0x5B,0x4C,    //2078
 -                     0x05,0x2B,0x42,    //2079
 -                     0x3A,0x93,0xB6,    //2080
 -                     0x06,0x93,0x49,    //2081
 -                     0x77,0x29,0xBd,    //2082
 -                     0x06,0xAA,0x51,    //2083
 -                     0x0A,0xd5,0x46,    //2084
 -                     0x54,0xdA,0xBA,    //2085
 -                     0x04,0xB6,0x4e,    //2086
 -                     0x0A,0x57,0x43,    //2087
 -                     0x45,0x27,0x38,    //2088
 -                     0x0d,0x26,0x4A,    //2089
 -                     0x8e,0x93,0x3e,    //2090
 -                     0x0d,0x52,0x52,    //2091
 -                     0x0d,0xAA,0x47,    //2092
 -                     0x66,0xB5,0x3B,    //2093
 -                     0x05,0x6d,0x4f,    //2094
 -                     0x04,0xAe,0x45,    //2095
 -                     0x4A,0x4e,0xB9,    //2096
 -                     0x0A,0x4d,0x4C,    //2097
 -                     0x0d,0x15,0x41,    //2098
 -                     0x2d,0x92,0xB5,    //2099
 - };
 - ///月份数据表
 - code uchar day_code1[9]={0x0,0x1f,0x3b,0x5a,0x78,0x97,0xb5,0xd4,0xf3};
 - code uint day_code2[3]={0x111,0x130,0x14e};
 - /*
 - 函数功能:输入BCD阳历数据,输出BCD阴历数据(只允许1901-2099年)
 - 调用函数示例:Conversion(c_sun,year_sun,month_sun,day_sun)
 - 如:计算2004年10月16日Conversion(0,0x4,0x10,0x16);
 - c_sun,year_sun,month_sun,day_sun均为BCD数据,c_sun为世纪标志位,c_sun=0为21世
 - 纪,c_sun=1为19世纪
 - 调用函数后,原有数据不变,读c_moon,year_moon,month_moon,day_moon得出阴历BCD数据
 - */
 - bit c_moon;
 - //子函数,用于读取数据表中农历月的大月或小月,如果该月为大返回1,为小返回0
 - bit get_moon_day(uchar month_p,uint table_addr)
 - {
 -         uchar temp10;
 -     switch (month_p){
 -         case 1:{temp10=year_code[table_addr]&0x08;
 -              if (temp10==0)return(0);else return(1);}
 -         case 2:{temp10=year_code[table_addr]&0x04;
 -              if (temp10==0)return(0);else return(1);}
 -         case 3:{temp10=year_code[table_addr]&0x02;
 -              if (temp10==0)return(0);else return(1);}
 -         case 4:{temp10=year_code[table_addr]&0x01;
 -              if (temp10==0)return(0);else return(1);}
 -         case 5:{temp10=year_code[table_addr+1]&0x80;
 -              if (temp10==0) return(0);else return(1);}
 -         case 6:{temp10=year_code[table_addr+1]&0x40;
 -              if (temp10==0)return(0);else return(1);}
 -         case 7:{temp10=year_code[table_addr+1]&0x20;
 -              if (temp10==0)return(0);else return(1);}
 -         case 8:{temp10=year_code[table_addr+1]&0x10;
 -              if (temp10==0)return(0);else return(1);}
 -         case 9:{temp10=year_code[table_addr+1]&0x08;
 -              if (temp10==0)return(0);else return(1);}
 -         case 10:{temp10=year_code[table_addr+1]&0x04;
 -              if (temp10==0)return(0);else return(1);}
 -         case 11:{temp10=year_code[table_addr+1]&0x02;
 -              if (temp10==0)return(0);else return(1);}
 -         case 12:{temp10=year_code[table_addr+1]&0x01;
 -              if (temp10==0)return(0);else return(1);}
 -         case 13:{temp10=year_code[table_addr+2]&0x80;
 -              if (temp10==0)return(0);else return(1);}
 -                 default:return(2);
 -     }
 - }
 - /*
 - 函数功能:输入BCD阳历数据,输出BCD阴历数据(只允许1901-2099年)
 - 调用函数示例:Conversion(c_sun,year_sun,month_sun,day_sun)
 - 如:计算2004年10月16日Conversion(0,0x4,0x10,0x16);
 - c_sun,year_sun,month_sun,day_sun均为BCD数据,c_sun为世纪标志位,c_sun=0为21世
 - 纪,c_sun=1为19世纪
 - 调用函数后,原有数据不变,读c_moon,year_moon,month_moon,day_moon得出阴历BCD数据
 - */
 - void Conversion(bit c,uchar year,uchar month,uchar day)
 - {                         //c=0 为21世纪,c=1 为19世纪 输入输出数据均为BCD数据
 -     uchar temp1,temp2,temp3,month_p;
 -     uint temp4,table_addr;
 -     bit flag2,flag_y;
 -     temp1=year/16;   //BCD->hex 先把数据转换为十六进制
 -     temp2=year%16;
 -     year=temp1*10+temp2;
 -         //year=temp1*16+temp2;
 -     temp1=month/16;
 -     temp2=month%16;
 -     month=temp1*10+temp2;
 -         //month=temp1*16+temp2;
 -     temp1=day/16;
 -     temp2=day%16;
 -     day=temp1*10+temp2;
 -         //day=temp1*16+temp2;
 -     //定位数据表地址
 -     if(c==0){
 -         table_addr=(year+0x64-1)*0x3;
 -     }
 -     else {
 -         table_addr=(year-1)*0x3;
 -     }
 -     //定位数据表地址完成
 -     //取当年春节所在的公历月份
 -     temp1=year_code[table_addr+2]&0x60;
 -     temp1=_cror_(temp1,5);
 -     //取当年春节所在的公历月份完成
 -     //取当年春节所在的公历日
 -     temp2=year_code[table_addr+2]&0x1f;
 -     //取当年春节所在的公历日完成
 -     // 计算当年春年离当年元旦的天数,春节只会在公历1月或2月
 -     if(temp1==0x1){
 -         temp3=temp2-1;
 -     }
 -     else{
 -         temp3=temp2+0x1f-1;
 -     }
 -     // 计算当年春年离当年元旦的天数完成
 -     //计算公历日离当年元旦的天数,为了减少运算,用了两个表
 -     //day_code1[9],day_code2[3]
 -     //如果公历月在九月或前,天数会少于0xff,用表day_code1[9],
 -     //在九月后,天数大于0xff,用表day_code2[3]
 -     //如输入公历日为8月10日,则公历日离元旦天数为day_code1[8-1]+10-1
 -     //如输入公历日为11月10日,则公历日离元旦天数为day_code2[11-10]+10-1
 -     if (month<10){
 -         temp4=day_code1[month-1]+day-1;
 -     }
 -     else{
 -         temp4=day_code2[month-10]+day-1;
 -     }
 -     if ((month>0x2)&&(year%0x4==0)){  //如果公历月大于2月并且该年的2月为闰月,天数加1
 -         temp4+=1;
 -     }
 -     //计算公历日离当年元旦的天数完成
 -     //判断公历日在春节前还是春节后
 -     if (temp4>=temp3){ //公历日在春节后或就是春节当日使用下面代码进行运算
 -         temp4-=temp3;
 -         month=0x1;
 -         month_p=0x1;  //month_p为月份指向,公历日在春节前或就是春节当日month_p指向首月
 -         flag2=get_moon_day(month_p,table_addr); //检查该农历月为大小还是小月,大月返回1,小月返回0
 -         flag_y=0;
 -         if(flag2==0)temp1=0x1d; //小月29天
 -         else temp1=0x1e; //大小30天
 -         temp2=year_code[table_addr]&0xf0;
 -         temp2=_cror_(temp2,4);  //从数据表中取该年的闰月月份,如为0则该年无闰月
 -         while(temp4>=temp1){
 -             temp4-=temp1;
 -             month_p+=1;
 -             if(month==temp2){
 -             flag_y=~flag_y;
 -             if(flag_y==0)month+=1;
 -             }
 -             else month+=1;
 -             flag2=get_moon_day(month_p,table_addr);
 -             if(flag2==0)temp1=0x1d;
 -             else temp1=0x1e;
 -         }
 -         day=temp4+1;
 -     }
 -     else{  //公历日在春节前使用下面代码进行运算
 -         temp3-=temp4;
 -         if (year==0x0){year=0x63;c=1;}
 -         else year-=1;
 -         table_addr-=0x3;
 -         month=0xc;
 -         temp2=year_code[table_addr]&0xf0;
 -         temp2=_cror_(temp2,4);
 -         if (temp2==0)
 -                         month_p=0xc;
 -         else
 -                         month_p=0xd; //
 -                 //month_p为月份指向,如果当年有闰月,一年有十三个月,月指向13,无闰月指向12
 -         flag_y=0;
 -         flag2=get_moon_day(month_p,table_addr);
 -         if(flag2==0)temp1=0x1d;
 -         else temp1=0x1e;
 -         while(temp3>temp1){
 -             temp3-=temp1;
 -             month_p-=1;
 -             if(flag_y==0)month-=1;
 -             if(month==temp2)flag_y=~flag_y;
 -             flag2=get_moon_day(month_p,table_addr);
 -             if(flag2==0)temp1=0x1d;
 -             else temp1=0x1e;
 -          }
 -         day=temp1-temp3+1;
 -     }
 - //    c_moon=c;
 -               //HEX->BCD ,运算结束后,把数据转换为BCD数据
 -     temp1=year/10;
 -     temp1=_crol_(temp1,4);
 -     temp2=year%10;
 -     SpDate.year=temp1|temp2;
 -     temp1=month/10;
 -     temp1=_crol_(temp1,4);
 -     temp2=month%10;
 -     SpDate.mon=temp1|temp2;
 -     temp1=day/10;
 -     temp1=_crol_(temp1,4);
 -     temp2=day%10;
 -     SpDate.day=temp1|temp2;
 - }
 -                                     ///函数
 - //******************延时子程序 *******************************
 - //这个延时程序的具体延时时间是time=i*8+10,适用于小于2ms的延时
 - //************************************************************
 - void delay(unsigned int i)
 - {
 - for(i;i>0;i--);
 - }
 - //***********************************************************
 - //                     延时子程序
 - //************************************************************
 - void delay1ms(uint j)
 - {
 - while(j!=0)
 - {uchar i;
 - for(i=124;i>0;i--);  //延时124*8+10=1002us
 - j--;
 - }
 - }
 - void Delayxms(uint ms)                        //@33.1776MHz   1ms
 - {
 -         unsigned char i, j;
 -     while(ms--)
 -            {
 -                 unsigned char i, j;
 -         _nop_();
 -         _nop_();
 -         i = 44;
 -         j = 19;
 -         do
 -         {
 -                 while (--j);
 -         } while (--i);
 -          }
 - }
 - /***************************************************************/
 - /**********************************18b20************************************************/
 - /**********************************18b20************************************************/
 - void Init_DS18B20(void)                                                                                 //初始化
 - {
 - uchar x=0;
 -          EA = 0;
 - DQ=1; //DQ先置高
 - delay(80); //稍延时
 - DQ=0; //发送复位脉冲
 - delay(2000); //延时(>480us)
 - DQ=1; //拉高数据线
 - delay(100); //等待(15~60us)
 - x=DQ; //用X的值来判断初始化有没有成功,18B20存在的话X=0,否则X=1
 - delay(400);
 -          EA = 1;
 - }
 - //**********读一个字节************//
 - ReadOneChar(void)  //主机数据线先从高拉至低电平1us以上,再使数据线升为高电平,从而产生读信号
 - {
 - unsigned char i=0; //每个读周期最短的持续时间为60us,各个读周期之间必须有1us以上的高电平恢复期
 - unsigned char dat=0;
 -         EA = 0;
 - for (i=8;i>0;i--) //一个字节有8位
 - {
 - DQ=1;
 - delay(30);
 - DQ=0;
 - dat>>=1;
 - delay(3); //涉及单片机频率
 - DQ=1;
 -   delay(1);         //读取时间没那么快,经验,33mhz的1t单片机都需要调整时序
 - if(DQ)
 - dat|=0x80;
 - delay(120);
 - }         EA = 1;
 - return(dat);
 - }
 - //*********************** **写一个字节**************************//
 - void WriteOneChar(unsigned char dat)
 - {
 -   unsigned char i=0; //数据线从高电平拉至低电平,产生写起始信号。15us之内将所需写的位送到数据线上,
 -           EA = 0;
 -   for(i=8;i>0;i--) //在15~60us之间对数据线进行采样,如果是高电平就写1,低写0发生。
 -   {
 -    DQ=0; //在开始另一个写周期前必须有1us以上的高电平恢复期。
 -     delay(3);//涉及单片机频率
 -    DQ=dat&0x01;
 -    delay(190);
 -    DQ=1;
 -    dat>>=1;         delay(1);
 -   }         EA = 1;
 -   delay(40);
 - }
 - void ReadTemperature(void)                                                                          //读温度值(低位放tempL;高位放tempH;)//
 -         {
 -          Init_DS18B20(); //初始化
 -          WriteOneChar(0xcc); //跳过读序列号的操作
 -          WriteOneChar(0x44); //启动温度转换
 -          delay(2000); //转换需要一点时间,延时
 -          Init_DS18B20(); //初始化
 -          WriteOneChar(0xcc); //跳过读序列号的操作
 -          WriteOneChar(0xbe); //读温度寄存器(头两个值分别为温度的低位和高位)
 -          tempL=ReadOneChar(); //读出温度的低位LSB
 -          tempH=ReadOneChar(); //读出温度的高位MSB
 -                 if(tempH>0x7f)      //最高位为1时温度是负
 -                 {
 -                  tempL=~tempL;         //补码转换,取反加一
 -                  tempH=~tempH+1;
 -                  fg=0;      //读取温度为负时fg=0
 -        }
 -                 sdata = tempL/16+tempH*16;      //整数部分
 -                 xiaoshu1 = (tempL&0x0f)*10/16; //小数第一位
 -                 xiaoshu2 = (tempL&0x0f)*100/16%10;//小数第二位
 -         }
 - /*****************************************ds3231********************************************/
 - #define ADDRTW          0xD0    //器件写地址
 - #define ADDRTD          0xD1 //器件读地址
 - #define DS3231_SEC      0x00    //秒
 - #define DS3231_MIN      0x01    //分
 - #define DS3231_HOUR     0x02    //时
 - #define DS3231_DAY      0x03    //星期
 - #define DS3231_DATE     0x04    //日
 - #define DS3231_MONTH    0x05    //月
 - #define DS3231_YEAR     0x06    //年
 - //闹铃1
 - #define DS3231_Al1SEC   0x07    //秒
 - #define DS3231_AL1MIN   0x08    //分
 - #define DS3231_AL1HOUR  0x09    //时
 - #define DS3231_AL1DAY   0x0A    //星期/日
 - //闹铃2
 - #define DS3231_AL2MIN   0x0b    //分
 - #define DS3231_AL2HOUR  0x0c    //时
 - #define DS3231_AL2DAY   0x0d    //星期/日
 - #define DS3231_CONTROL  0x0e    //控制寄存器
 - #define DS3231_STATUS   0x0f    //状态寄存器
 - bit ack;
 - uchar BCD2HEX(uchar val)           //BCD转换为Byte
 - {        uchar i;
 -     i= val&0x0f;
 -     val >>= 4;
 -     val &= 0x0f;
 -     val *= 10;
 -     i += val;
 -     return i;
 - }
 - uchar HEX2BCD(uchar val)//B码转换为BCD码
 -         {
 -         uchar i,j,k;
 -           i=val/10;
 -           j=val%10;
 -           k=j+(i<<4);
 -           return k;
 -         }
 - void Start()
 - {
 -     TSDA=1;                  //发送起始条件的数据信号
 -     delay(1);
 -     TSCL=1;
 -     delay(5);             //起始条件建立时间大于4.7us,延时
 -            TSDA=0;                  //发送起始信号
 -     delay(5);             // 起始条件锁定时间大于4μs
 -     TSCL=0;                  //钳住I2C总线,准备发送或接收数据
 -     delay(2);
 - }
 - void Stop()
 - {
 -     TSDA=0;                  //发送结束条件的数据信号
 -     delay(1);             //发送结束条件的时钟信号
 -     TSCL=1;                  //结束条件建立时间大于4us
 -     delay(5);
 -     TSDA=1;                  //发送I2C总线结束信号
 -     delay(4);
 - }
 - /********************************************************/
 - /*******************************************************************
 -                   字节数据发送函数
 - 函数原型:     void   SendByte(uchar Dat);
 - 功能:      将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
 -            此状态位进行操作.(不应答或非应答都使ack=0)
 -            ack=1        发送数据正常,
 -            ack=0        被控器无应答或损坏。
 - ********************************************************************/
 - void SendByte(uchar Dat)
 - {
 - uchar BitCnt;
 -     for(BitCnt=0;BitCnt<8;BitCnt++)         //要传送的数据长度为8位
 -     {
 -         if((Dat<<BitCnt)&0x80)
 -             TSDA=1;                          //判断发送位
 -         else
 -             TSDA=0;
 -           delay(1);
 -           TSCL=1;                            //置时钟线为高,通知被控器开始接收数据位
 -           delay(5);                       //保证时钟高电平周期大于4μs
 -           TSCL=0;
 -     }
 -     delay(2);
 -     TSDA=1;                                  //8位发送完后释放数据线,准备接收应答位
 -     delay(2);
 -     TSCL=1;
 -     delay(3);
 -     if(TSDA==1)
 -         ack=0;
 -     else
 -         ack=1;                              //判断是否接收到应答信号
 -     TSCL=0;
 -     delay(2);
 - }
 - uchar RcvByte()                                                                        // 功能:      用来接收从器件传来的数据,并判断总线错误(不发应答信号),发完后请用应答函数应答从机。
 - {
 - uchar retc;
 - uchar BitCnt;
 -    retc=0;
 -    TSDA=1;                           //置数据线为输入方式
 -    for(BitCnt=0;BitCnt<8;BitCnt++)
 -    {
 -         delay(1);
 -         TSCL=0;                      //置时钟线为低,准备接收数据位
 -         delay(5);                 //时钟低电平周期大于4.7μs
 -         TSCL=1;                      //置时钟线为高使数据线上数据有效
 -         delay(3);
 -         retc=retc<<1;
 -         if(TSDA==1)
 -             retc=retc+1;            //读数据位,接收的数据位放入retc中
 -         delay(2);
 -    }
 -    TSCL=0;
 -    delay(2);
 -    return(retc);
 - }
 - void I2CACK(bit a)                         // 功能:       主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
 - {
 -     if(a==0)
 -         TSDA=0;              //在此发出应答或非应答信号
 -     else
 -         TSDA=1;
 -     delay(3);
 -     TSCL=1;
 -     delay(5);             //时钟低电平周期大于4μs
 -     TSCL=0;                  //清时钟线,钳住I2C总线以便继续接收
 -     delay(2);
 - }
 - uchar I2CRead()                                                                         /************从DS3231当前地址读一个字节************/
 - {
 - uchar read_data;
 -         Start();
 -     SendByte(ADDRTD);
 -     if(ack==0)
 -     {
 -   return(0);
 -     }
 -     read_data = RcvByte();
 -     I2CACK(1);
 -     Stop();
 -     return read_data;
 - }
 - uchar I2CReadAdd(uchar addr)                                                 /************从DS3231指定地址读一个字节************/
 -         {
 -             Start();
 -             SendByte(ADDRTW);
 -             if(ack==0)
 -             {
 -           return(0);
 -             }
 -             SendByte(addr);
 -             if(ack==0)
 -             {
 -           return(0);
 -             }
 -             return(I2CRead());
 -         }
 - void Readtime()                                                                                 /*********************读取时间**********************/
 -         {
 -          uchar temp;
 -          temp=I2CReadAdd(DS3231_SEC);//秒
 -          sec=BCD2HEX(temp);
 -          temp=I2CReadAdd(DS3231_MIN);//分
 -          min=BCD2HEX(temp);
 -          temp=I2CReadAdd(DS3231_HOUR);  //时
 -          hour=BCD2HEX(temp);
 -          temp=I2CReadAdd(DS3231_DATE);  //日
 -          date=BCD2HEX(temp);
 -          temp=I2CReadAdd(DS3231_MONTH); //月
 -          month=BCD2HEX(temp);
 -          temp=I2CReadAdd(DS3231_YEAR);  //年
 -          year=BCD2HEX(temp);
 -          temp=I2CReadAdd(DS3231_DAY);
 -          day=BCD2HEX(temp);//星期
 -          }
 -          void Readtimenongli()                                                                                 /*********************读取时间为了阳历转农历**********************/
 -         {
 -          ndate=I2CReadAdd(DS3231_DATE);  //日
 -         // date=BCD2HEX(temp);
 -         nmonth=I2CReadAdd(DS3231_MONTH); //月
 -          //month=BCD2HEX(temp);
 -         nyear=I2CReadAdd(DS3231_YEAR);  //年
 -          }
 - void InitDS3231()                                                                                                 //ds3231初始化
 -         {    TSCL=1;
 -          delay(5);
 -          TSDA=1;
 -          delay(5);
 -         }
 - void TimeDisplay(uchar Dhour,uchar Dmin,uchar Dsec)                                //时分秒数组赋值
 -         {        b[0]=(hour / 10)+'0';        // 时十位
 -             b[1]=numbr[Dhour % 10];        // 时个位
 -             b[4]=numbr[Dmin / 10];         // 分十位
 -             b[5]=numbr[Dmin % 10];         // 分个位
 -             b[8]=numbr[Dsec / 10];         // 秒十位
 -             b[9]=numbr[Dsec % 10];         // 秒个位
 -         }
 - void DateDisplay(uchar Dyear,uchar Dmonth,uchar Dday)                        //年月天数组赋值
 -         {        a[2]=numbr[Dyear / 10];        // 年十位
 -             a[3]=numbr[Dyear % 10];        // 年个位
 -             a[5]=numbr[Dmonth / 10];       // 月十位
 -             a[6]=numbr[Dmonth % 10];       // 月个位
 -             a[8]=numbr[Dday / 10];         // 天十位
 -             a[9]=numbr[Dday % 10];         // 天个位
 -         }
 - void Start_I2C()
 - {
 -     TSDA=1;                  //发送起始条件的数据信号
 -     delay(1);
 -     TSCL=1;
 -     delay(5);             //起始条件建立时间大于4.7us,延时
 -     TSDA=0;                  //发送起始信号
 -     delay(5);             // 起始条件锁定时间大于4μs
 -     TSCL=0;                  //钳住I2C总线,准备发送或接收数据
 -     delay(2);
 - }
 - void Stop_I2C()
 - {
 -     TSDA=0;                  //发送结束条件的数据信号
 -     delay(1);             //发送结束条件的时钟信号
 -     TSCL=1;                  //结束条件建立时间大于4us
 -     delay(5);
 -     TSDA=1;                  //发送I2C总线结束信号
 -     delay(4);
 - }
 - uchar write_byte(uchar addr, uchar write_data)
 - {
 -     Start_I2C();
 -     SendByte(ADDRTW);                //////*******************************************************************///////////
 -     if (ack == 0)
 -         return 0;
 -     SendByte(addr);
 -     if (ack == 0)
 -         return 0;
 -     SendByte(write_data);
 -     if (ack == 0)
 -         return 0;
 -     Stop_I2C();
 -      delay1ms(10);
 -     return 1;
 - }
 - void ModifyTime(uchar yea,uchar mon,uchar da,uchar hou,uchar min,uchar sec,uchar w)          //函数功能:修改时间、日期和星期
 - {          uchar temp=0;
 -     temp=HEX2BCD(yea);
 -     write_byte(DS3231_YEAR,temp);   //修改年
 -     temp=HEX2BCD(mon);
 -     write_byte(DS3231_MONTH,temp);  //修改月
 -     temp=HEX2BCD(da);                                                                           /////////////////////
 -     write_byte(DS3231_DATE,temp);    //修改日
 -     temp=HEX2BCD(hou);
 -     write_byte(DS3231_HOUR,temp);   //修改时
 -     temp=HEX2BCD(min);
 -     write_byte(DS3231_MIN,temp); //修改分
 -     temp=HEX2BCD(sec);
 -     write_byte(DS3231_SEC,temp); //修改秒
 -          temp=HEX2BCD(w);
 -     write_byte(DS3231_DAY,temp);  //修改星期
 - }
 - void nongli()
 -     {
 -           uchar SetDatyue,SetDat;
 -           Readtimenongli();
 -          Conversion(0,nyear,nmonth,ndate);
 -           SetDatyue = BCD2HEX(SpDate.mon);
 - //        if (SetDatyue==1){LCD1602_Dis_Str(3, 0, "正");}
 - //        if (SetDatyue==2){LCD1602_Dis_Str(3, 0, "二");}
 - //        if (SetDatyue==3){LCD1602_Dis_Str(3, 0, "三");}
 - //        if (SetDatyue==4){LCD1602_Dis_Str(3, 0, "四");}
 - //        if (SetDatyue==5){LCD1602_Dis_Str(3, 0, "五");}
 - //        if (SetDatyue==6){LCD1602_Dis_Str(3, 0, "六");}
 - //        if (SetDatyue==7){LCD1602_Dis_Str(3, 0, "七");}
 - //        if (SetDatyue==8){LCD1602_Dis_Str(3, 0, "八");}
 - //        if (SetDatyue==9){LCD1602_Dis_Str(3, 0, "九");}
 - //        if (SetDatyue==10){LCD1602_Dis_Str(3, 0, "十");}
 - //        if (SetDatyue==11){LCD1602_Dis_Str(3, 0, "冬");}
 - //        if (SetDatyue==12){LCD1602_Dis_Str(3, 0, "腊");}
 - //        LCD1602_Dis_Str(3, 1, "月");
 - //         SetDat = BCD2HEX(SpDate.day);
 - //    if (SetDat==1){LCD1602_Dis_Str(3, 2, "初一");}
 - //        if (SetDat==2){LCD1602_Dis_Str(3, 2, "初二");}
 - //        if (SetDat==3){LCD1602_Dis_Str(3, 2, "初三");}
 - //        if (SetDat==4){LCD1602_Dis_Str(3, 2, "初四");}
 - //        if (SetDat==5){LCD1602_Dis_Str(3, 2, "初五");}
 - //        if (SetDat==6){LCD1602_Dis_Str(3, 2, "初六");}
 - //        if (SetDat==7){LCD1602_Dis_Str(3, 2, "初七");}
 - //        if (SetDat==8){LCD1602_Dis_Str(3, 2, "初八");}
 - //        if (SetDat==9){LCD1602_Dis_Str(3, 2, "初九");}
 - //        if (SetDat==10){LCD1602_Dis_Str(3, 2, "初十");}
 - //        if (SetDat==11){LCD1602_Dis_Str(3, 2, "十一");}
 - //        if (SetDat==12){LCD1602_Dis_Str(3, 2, "十二");}
 - //        if (SetDat==13){LCD1602_Dis_Str(3, 2, "十三");}
 - //        if (SetDat==14){LCD1602_Dis_Str(3, 2, "十四");}
 - //        if (SetDat==15){LCD1602_Dis_Str(3, 2, "十五");}
 - //        if (SetDat==16){LCD1602_Dis_Str(3, 2, "十六");}
 - //        if (SetDat==17){LCD1602_Dis_Str(3, 2, "十七");}
 - //        if (SetDat==18){LCD1602_Dis_Str(3, 2, "十八");}
 - //        if (SetDat==19){LCD1602_Dis_Str(3, 2, "十九");}
 - //        if (SetDat==20){LCD1602_Dis_Str(3, 2, "二十");}
 - //        if (SetDat==21){LCD1602_Dis_Str(3, 2, "廿一");}
 - //        if (SetDat==22){LCD1602_Dis_Str(3, 2, "廿二");}
 - //        if (SetDat==23){LCD1602_Dis_Str(3, 2, "廿三");}
 - //        if (SetDat==24){LCD1602_Dis_Str(3, 2, "廿四");}
 - //        if (SetDat==25){LCD1602_Dis_Str(3, 2, "廿五");}
 - //        if (SetDat==26){LCD1602_Dis_Str(3, 2, "廿六");}
 - //        if (SetDat==27){LCD1602_Dis_Str(3, 2, "廿七");}
 - //        if (SetDat==28){LCD1602_Dis_Str(3, 2, "廿八");}
 - //        if (SetDat==29){LCD1602_Dis_Str(3, 2, "廿九");}
 - //        if (SetDat==30){LCD1602_Dis_Str(3, 2, "三十");}
 -                                     //显示到液晶上
 - }
 - void xianshi(void)
 -      {
 -                      OLED_ShowNum(48,0,hour,2,32); //显示时
 -            if(sec%2==1) {OLED_ShowString(80,0,":",32);}
 -         if(sec%2==0) {OLED_ShowString(80,0," ",32);}
 -                  OLED_ShowNum(96,0,min/10,1,32);         //显示分
 -                                  OLED_ShowNum(112,0,min%10,1,32);         //显示分   // OLED_ShowNum(97,0,sec,2,32);
 -                                         /*显示星期*/
 -                      OLED_ShowString(0,2,"W",16);
 -                     OLED_ShowNum(10,2,day,1,16);
 -                         OLED_ShowString(0,0,"D",16);
 -                     OLED_ShowNum(8,0,month,2,16);         //显示月
 -                            OLED_ShowString(24,0,".",16);
 -                         OLED_ShowNum(32,0,date/10,1,16);
 -                     OLED_ShowNum(40,0,date%10,1,16); //显示日
 -                                 ReadTemperature();                        //显示温度
 -                         OLED_ShowString(22,2,"T",16);
 -                     OLED_ShowNum(32,2,sdata,2,16);
 -                         }
 - void shuaxin(void)
 -         {
 -                      OLED_ShowNum(48,0,hour,2,32); //显示时
 -            if(sec%2==1) {OLED_ShowString(80,0,":",32);}
 -         if(sec%2==0) {OLED_ShowString(80,0," ",32);}
 -                  OLED_ShowNum(96,0,min/10,1,32);         //显示分
 -                                  OLED_ShowNum(112,0,min%10,1,32);         //显示分   // OLED_ShowNum(97,0,sec,2,32);
 -                                         /*显示星期*/
 -                      OLED_ShowString(0,2,"W",16);
 -                     OLED_ShowNum(10,2,day,1,16);
 -                         OLED_ShowString(0,0,"D",16);
 -                     OLED_ShowNum(8,0,month,2,16);         //显示月
 -                            OLED_ShowString(24,0,".",16);
 -                         OLED_ShowNum(32,0,date/10,1,16);
 -                     OLED_ShowNum(40,0,date%10,1,16); //显示日
 -                                 ReadTemperature();                        //显示温度
 -                         OLED_ShowString(22,2,"T",16);
 -                     OLED_ShowNum(32,2,sdata,2,16);
 -         }
 -   void xiugai()           //设置时间
 - {
 -           if(flag==1&&flag1==1)
 -       {  ES=0;
 -                   flag=0;
 -                 flag1=0;
 -            year=(buffer[1]-0x30)*10+(buffer[2]-0x30);
 -            month=(buffer[3]-0x30)*10+(buffer[4]-0x30);
 -            date=(buffer[5]-0x30)*10+(buffer[6]-0x30);
 -            hour=(buffer[7]-0x30)*10+(buffer[8]-0x30);
 -            min=(buffer[9]-0x30)*10+(buffer[10]-0x30);
 -            sec=(buffer[11]-0x30)*10+(buffer[12]-0x30);
 -            day=(buffer[13]-0x30);
 -            ModifyTime(year,month,date,hour,min,sec,day);
 -                   ES=1;
 -            flag=0;
 -            flag1=0;
 -            }
 -           else
 -            {
 -               //   Get_Current1();
 -                                Readtime();
 - //                         nongli();
 -                      xianshi();
 -                          shuaxin();
 -                          flag=0;
 -                  flag1=0;
 -            }
 - }
 -   /*串口 函数*/
 - void UartInit(void)                //9600bps@33.1776MHz
 - {
 -         SCON = 0x50;                //8位数据,可变波特率
 -         AUXR |= 0x01;                //串口1选择定时器2为波特率发生器
 -         AUXR &= 0xFB;                //定时器时钟12T模式
 -         T2L = 0xB8;                        //设置定时初始值
 -         T2H = 0xFF;                        //设置定时初始值
 -         AUXR |= 0x10;                //定时器2开始计时
 -                 EA=1;                        //打开总中断
 -             ES=1;                        //打开接收中断
 - }
 - main()                                          /*主程序*/
 - {
 -         bg=0;
 -                            P3M1 = 0x00;
 -             P3M0 = 0x00;
 -                          P1M1 = 0x00;
 -             P1M0 = 0x00;
 -                          UartInit();
 -                 InitDS3231();
 -                  OLED_Init();//初始化OLED
 -              OLED_ColorTurn(0);//0正常显示,1 反色显示
 -          OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
 -                OLED_Clear();
 -                 // OLED_ShowString(0,0,"12:12:12",32);
 -           //         ModifyTime(23,12,7,12,34,56,4)        ;
 -          while(1)
 -          {
 -         Delayxms(200);
 -     xiugai();
 -     Delayxms(200);
 - }  }
 - void Uart() interrupt 4 using 1        //串口1中断处理
 - {
 -           buffer=SBUF;
 -         if(buffer==0x7E)          //接收的报文以#开头(即0x7E)
 -                 {          flag1=1; //进入设置界面
 -                         i=0;
 -                         buffer=SBUF;           //开始接收
 -                 }
 -         RI=0;
 -         i++;
 -         if(buffer[i-1]==0x21) //接收的报文以!结尾(即0x21)
 -         {
 -                 i=0;
 -                 flag=1;
 -     }
 - }
 
 
 
  
json文件:
 
json文件.7z
(89.92 KB, 下载次数: 171)
 
 
 
代码:
 
程序12832液晶 DS3231程序20231208已实现时钟显示 串口同步时间.zip
(339.25 KB, 下载次数: 182)
 
 
 |   
 
1
喜欢他/她就送朵鲜花吧,赠人玫瑰,手有余香!
 
- 
 
+2 
楼主威武~ 
 
 
 
 
 
 |