找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 18224|回复: 18
打印 上一主题 下一主题
收起左侧

51单片机OLED时钟显示源码

  [复制链接]
跳转到指定楼层
楼主
ID:55815 发表于 2018-6-6 15:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
oled时钟单片机源程序如下:

  1. #include "REG52.h"
  2. #include "oled.h"

  3. #define uchar unsigned char
  4. #define uint  unsigned int
  5. #include <intrins.h>
  6. sbit         DQ = P3^6;                       //数据口define interface
  7. /***********************DS1302端口定义*******************************************/
  8. sbit clock_rst=P3^5;  //1302复位管脚定义
  9. sbit clock_dat=P1^3;  //1302I/O管脚定义
  10. sbit clock_clk=P1^2;  //1302时钟管脚定义  
  11. /***************寄存器定义(用于记录1302IO的输入和输出)*************************/
  12. sbit a0=ACC^0;
  13. sbit a1=ACC^1;
  14. sbit a2=ACC^2;
  15. sbit a3=ACC^3;
  16. sbit a4=ACC^4;
  17. sbit a5=ACC^5;
  18. sbit a6=ACC^6;
  19. sbit a7=ACC^7;

  20. /**********************1302全局变量定义******************************************/
  21. uchar sec,min,hour,day,month,year1,year2=20;//秒,分,时,日,月,星期,年
  22. /************************蜂鸣器端口定义******************************************/
  23. sbit beep=P3^7;
  24. /***********************按键定义*************************************************/
  25. sbit key1=P1^0;
  26. sbit key2=P1^1;
  27. sbit key3=P3^4;
  28. uchar status=0;//按键功能选择定义(年0,月1,日2,时3,分4 )



  29. uint tmp;                           //温度值 variable of temperature
  30. uint Temp_Buffer = 0;
  31. uint t1;
  32. uint  t2;
  33. uint   t3;
  34. float tt;
  35. void delay2(unsigned char i)           //延时函数
  36. {
  37.         while(--i);
  38. }
  39. /**********************延时函数*************************************************/
  40. void delay(uint t)  
  41. {
  42. uint b;
  43. for(;t;t--)
  44.   for(b=0;b<121;b++);
  45. }


  46. void Init_Ds18b20(void)     //DS18B20初始化send reset and initialization command
  47. {
  48.         DQ = 1;                     //DQ复位,不要也可行。
  49.         delay2(1);                  //稍做延时
  50.         DQ = 0;                    //单片机拉低总线
  51.         delay2(250);                //精确延时,维持至少480us
  52.         DQ = 1;                    //释放总线,即拉高了总线
  53.         delay2(100);                //此处延时有足够,确保能让DS18B20发出存在脉冲。
  54. }
  55. uchar Read_One_Byte()       //读取一个字节的数据read a byte date
  56.                             //读数据时,数据以字节的最低有效位先从总线移出
  57. {
  58.         uchar i   = 0;
  59.         uchar dat = 0;
  60.         for(i=8;i>0;i--)
  61.         {
  62.            DQ = 0;                 //将总线拉低,要在1us之后释放总线
  63.                                    //单片机要在此下降沿后的15us内读数据才会有效。
  64.            _nop_();                 //至少维持了1us,表示读时序开始
  65.            dat >>= 1;               //让从总线上读到的位数据,依次从高位移动到低位。
  66.            DQ = 1;                  //释放总线,此后DS18B20会控制总线,把数据传输到总线上
  67.            delay2(1);                 //延时7us,此处参照推荐的读时序图,尽量把控制器采样时间放到读时序后的15us内的最后部分
  68.            if(DQ)                   //控制器进行采样
  69.            {
  70.             dat |= 0x80;    //总线为1, DQ为1,那就把dat的最高位置1;若为0,不处理,保持0
  71.            }        
  72.            delay2(10);               //此延时不能少,确保读时序的长度60us。
  73.         }
  74.         return (dat);
  75. }
  76. void Write_One_Byte(uchar dat)
  77. {
  78.         uchar i = 0;
  79.         for(i=8;i>0;i--)
  80.         {
  81.            DQ = 0;                        //拉低总线
  82.            _nop_();                       //至少维持了1us,表示写时序(包括写0时序或写1时序)开始
  83.            DQ = dat&0x01;                 //从字节的最低位开始传输
  84.                                          //指令dat的最低位赋予给总线,必须在拉低总线后的15us内,
  85.                                          //因为15us后DS18B20会对总线采样。
  86.            delay2(10);                     //必须让写时序持续至少60us
  87.            DQ = 1;                        //写完后,必须释放总线,
  88.            dat >>= 1;
  89.            delay2(1);
  90.         }
  91. }
  92. uint Get_Tmp()                   //获取温度get the temperature
  93. {
  94.        
  95.     uchar a=0,b=0;
  96.        
  97.         Init_Ds18b20();                //初始化
  98.         Write_One_Byte(0xcc);          //忽略ROM指令
  99.         Write_One_Byte(0x44);          //温度转换指令
  100.         Init_Ds18b20();                 //初始化
  101.         Write_One_Byte(0xcc);          //忽略ROM指令
  102.         Write_One_Byte(0xbe);          //读暂存器指令
  103.         a = Read_One_Byte();           //读取到的第一个字节为温度LSB
  104.         b = Read_One_Byte();           //读取到的第一个字节为温度MSB
  105.         tmp = b;                      //先把高八位有效数据赋于temp
  106.         tmp <<= 8;                    //把以上8位数据从temp低八位移到高八位
  107.         tmp = tmp|a;                //两字节合成一个整型变量
  108.         tt = tmp*0.0625;           //得到真实十进制温度值,DS18B20可以精确到0.0625度
  109.     tmp =(uint)( tt*10+0.5);   //放大十倍,目的是将小数点后第一位也转换为可显示数字                              
  110.         return (tmp);
  111. }
  112. void Display_Temp()
  113. {
  114.        
  115.         Temp_Buffer = Get_Tmp() ;                                          //读取DS18B20的值
  116.         t1=(Temp_Buffer%1000/100);           //显示温度十位值
  117.         t2=(Temp_Buffer%100/10);           //显示温度个位值
  118.                                                   
  119.         t3=(Temp_Buffer%10);                   //显示温度十分位值
  120.                                                   
  121.                
  122. }

  123. /*******************************************************************************/
  124. /*************************DS1302子函数******************************************/
  125. /************************1302写驱动函数*****************************************/
  126. void write_clock(uchar dat)
  127. {
  128. ACC=dat;
  129. clock_dat=a0; clock_clk=1; clock_clk=0; //数据在上升沿变化
  130. clock_dat=a1; clock_clk=1; clock_clk=0; //下降沿写入1302
  131. clock_dat=a2; clock_clk=1; clock_clk=0;
  132. clock_dat=a3; clock_clk=1; clock_clk=0;
  133. clock_dat=a4; clock_clk=1; clock_clk=0;
  134. clock_dat=a5; clock_clk=1; clock_clk=0;
  135. clock_dat=a6; clock_clk=1; clock_clk=0;
  136. clock_dat=a7; clock_clk=1; clock_clk=0;
  137. }
  138. /************************1302读驱动函数*****************************************/
  139. uchar read_clock()
  140. {
  141. clock_dat=1;   //输出赋1
  142. a0=clock_dat;clock_clk=1; clock_clk=0;  //位0为1,读1302
  143. a1=clock_dat;clock_clk=1; clock_clk=0; //下降沿读出有效
  144. a2=clock_dat;clock_clk=1; clock_clk=0;
  145. a3=clock_dat;clock_clk=1; clock_clk=0;
  146. a4=clock_dat;clock_clk=1; clock_clk=0;
  147. a5=clock_dat;clock_clk=1; clock_clk=0;
  148. a6=clock_dat;clock_clk=1; clock_clk=0;
  149. a7=clock_dat;clock_clk=1; clock_clk=0;
  150. return(ACC);
  151. }
  152. /***************************写数据入1302****************************************/
  153. void write_dat_clock(uchar add,uchar dat)
  154. {
  155. clock_clk=0;
  156. clock_rst=0; //时钟脉冲为低时
  157. clock_rst=1; //复位端才能置高
  158. write_clock(add); //写入地址(命令字节)
  159. write_clock(dat); //写入数据
  160. clock_rst=0; //终止数据传送
  161. clock_clk=1;
  162. }
  163. /***************************从1302读出数据**************************************/
  164. uchar read_dat_clock(uchar add)
  165. {
  166. uchar dat=0; //定义数据储存变量
  167. clock_clk=0;
  168. clock_rst=0;
  169. clock_rst=1;
  170. write_clock(add); //写入要读数据的地址
  171. dat=read_clock(); //读出数据
  172. clock_rst=0; //终止数据传送
  173. clock_clk=1;
  174. return dat;  //返回数据
  175. }
  176. /**************************设置初始时间函数*************************************/
  177. void set_time()
  178. {
  179. read_dat_clock(0x81);    //读取秒
  180. if(sec==0x80)          //sec为秒读出的数值,如果最高位为1,则初始化
  181. write_dat_clock(0x8e,0x00);  //允许写操作
  182. write_dat_clock(0x8c,0x13);  //年
  183. write_dat_clock(0x8a,0x03);  //星期
  184. write_dat_clock(0x88,0x10);  //月
  185. write_dat_clock(0x86,0x14);  //日
  186. write_dat_clock(0x84,0x21);  //小时
  187. write_dat_clock(0x82,0x56);  //分
  188. write_dat_clock(0x80,0x00);  //秒,且振荡器工作
  189. write_dat_clock(0x90,0xa5);  //充电
  190. write_dat_clock(0x8e,0x80);  //禁止写操作
  191. }

  192. void get_time()
  193. {
  194. sec=read_dat_clock(0x81);    //读取秒
  195. sec=(sec>>4)*10+(sec&0x0f);  //秒二进制转换
  196. delay(1);
  197. min=read_dat_clock(0x83);    //读取分钟
  198. min=(min>>4)*10+(min&0x0f);  //分二进制转换
  199. delay(1);
  200. hour=read_dat_clock(0x85);   //读取小时
  201. hour=(hour>>4)*10+(hour&0x0f);//小时二进制转换
  202. delay(1);
  203. day=read_dat_clock(0x87);     //读取日期
  204. day=(day>>4)*10+(day&0x0f);   //日期二进制转换
  205. delay(1);
  206. month=read_dat_clock(0x89);   //读取月份
  207. month=(month>>4)*10+(month&0x0f);//月二进制转换
  208. delay(1);
  209. //week=read_dat_clock(0x8b);    //读取星期
  210. //week=(week>>4)*10+(week&0x0f);//星期二进制转换
  211. delay(1);
  212. year1=read_dat_clock(0x8d);     //读取年份
  213. year1=(year1>>4)*10+(year1&0x0f); //年份二进制转换
  214. }         

  215. /******************************************************************************/
  216. /*****************************按键功能函数*************************************/
  217. void key_1()     //选择变量函数
  218. {
  219. key1=1;
  220. if(key1==0)
  221.   delay(10);                                                                                                                                                                                                                               
  222. {
  223.   if(key1==0)
  224.   {
  225.    if(++status>5)status=0; //1控制年的变化,2控制月的变化,3控制日的变化
  226.   }       //4控制时的变化,5控制分的变化
  227.   while(key1==0);
  228. }
  229. }
  230. /******************************************************************************/
  231. void key_2()       //加函数
  232. {
  233. key2=1;
  234. if(key2==0)
  235. {
  236.   delay(10);
  237.   if(key2==0)
  238.   {
  239.    switch(status)
  240.    {
  241.     case 1:if(++year1>99)year1=0;break;
  242.     case 2:if(++month>12)month=1;break;
  243.     case 3:if(++day>31)day=1;break;
  244.     case 4:if(++hour>=24)hour=0;break;
  245.     case 5:if(++min>=60)min=0;break;
  246.    }
  247.   }
  248. while(key2==0);
  249. }
  250. }
  251. /*****************************************************************************/
  252. void key_3()//减函数
  253. {
  254.   key3=1;
  255. if(key3==0)
  256. {
  257.   delay(10);
  258.   if(key3==0)
  259.   {
  260.    switch(status)
  261.    {
  262.     case 1:if((year1--)<=0)year1=99;break;
  263.     case 2:if((month--)<=1)month=12;break;
  264.     case 3:if((day--)<=1)day=31;break;
  265.     case 4:if((hour--)<=0)hour=23;break;
  266.     case 5:if((min--)<=0)min=59;break;
  267.    }
  268.   }
  269.   while(key3==0);
  270. }
  271. }

  272. /*****************************************************************************/
  273. void key_time()    //按键设置时间的处理
  274. {
  275. if(status>0)
  276. {
  277. write_dat_clock(0x8e,0x00);  //允许写操作
  278. write_dat_clock(0x8c,(year1/10)*16+year1%10);  //年
  279. //write_dat_clock(0x8a,(week/10)*16+week%10);  //星期
  280. write_dat_clock(0x88,(month/10)*16+month%10);  //月
  281. write_dat_clock(0x86,(day/10)*16+day%10);  //日
  282. write_dat_clock(0x84,(hour/10)*16+hour%10);  //小时
  283. write_dat_clock(0x82,(min/10)*16+min%10);  //分
  284. write_dat_clock(0x8e,0x80);  //禁止写操作
  285. }
  286. }

  287. void  main()
  288. {          
  289.             OLED_Init();                        //初始化OLED  
  290.                 OLED_Clear();
  291.                 Init_Ds18b20();
  292.                 Get_Tmp();
  293.                  delay(10);
  294.                  set_time();
  295.                  
  296.         while(1)
  297.         {               
  298.                
  299.                
  300.                 Display_Temp();
  301.                 //OLED_Clear();
  302.                 OLED_ShowCHinese(0,0,0);//软
  303.                 OLED_ShowCHinese(18,0,1);//件
  304.                 OLED_ShowCHinese(36,0,2);//设
  305.                 OLED_ShowCHinese(54,0,3);//计
  306.                 OLED_ShowCHinese(72,0,4);//田
  307.                 OLED_ShowCHinese(90,0,5);//增
  308.                 OLED_ShowCHinese(108,0,6);//良
  309.                
  310.                 //OLED_ShowString(8,2,"Design by TZL");  
  311.                  //OLED_ShowString(0,4,"Tel:15083395396");  
  312.                
  313.                 OLED_ShowCHinese(0,2,7);//实
  314.             OLED_ShowCHinese(18,2,8);//测
  315.                 OLED_ShowCHinese(36,2,9);//温
  316.                 OLED_ShowCHinese(54,2,10);//度
  317.                  OLED_ShowCHinese(36,4,11);//年
  318.                  OLED_ShowCHinese(74,4,12);//月
  319.                  OLED_ShowCHinese(110,4,13);//日
  320.                   get_time();
  321. ……………………

  322. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
OLED时钟显示.zip (90.82 KB, 下载次数: 570)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏11 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:375014 发表于 2018-7-19 17:07 | 只看该作者
支持楼主DDDDDDD
回复

使用道具 举报

板凳
ID:449272 发表于 2019-1-3 21:28 | 只看该作者
请问STC8A8K64S12A能用吗?
回复

使用道具 举报

地板
ID:461448 发表于 2019-1-3 23:29 | 只看该作者
支持楼主,赞!!!!
回复

使用道具 举报

5#
ID:80243 发表于 2019-3-2 11:16 | 只看该作者
谢谢!
回复

使用道具 举报

6#
ID:79544 发表于 2020-2-2 10:04 | 只看该作者
感谢分享,学习啦!!!
回复

使用道具 举报

7#
ID:689267 发表于 2020-2-2 12:25 | 只看该作者
感谢分享
回复

使用道具 举报

8#
ID:294123 发表于 2020-2-11 20:18 | 只看该作者
你这个还有DS18B20测温呀, 你有proteus仿真图吗,我自己画一个试试
回复

使用道具 举报

9#
ID:692891 发表于 2020-2-13 20:23 | 只看该作者
楼主有没有ds1302的呢
回复

使用道具 举报

10#
ID:767738 发表于 2020-6-6 16:17 | 只看该作者
学习了!
回复

使用道具 举报

11#
ID:653353 发表于 2020-11-27 07:06 | 只看该作者
感谢楼主
回复

使用道具 举报

12#
ID:581979 发表于 2020-12-1 21:02 | 只看该作者
怎么都在MAIN文件
回复

使用道具 举报

13#
ID:47634 发表于 2021-5-31 21:36 | 只看该作者
这个很好,下载学习,感谢楼主
回复

使用道具 举报

14#
ID:486840 发表于 2021-5-31 22:12 | 只看该作者
STC12可以用吗
回复

使用道具 举报

15#
ID:624685 发表于 2021-5-31 23:01 | 只看该作者
感谢分享,慢慢理解。谢谢
回复

使用道具 举报

16#
ID:905929 发表于 2021-6-1 14:33 | 只看该作者
程序复杂,下来慢慢看
回复

使用道具 举报

17#
ID:964692 发表于 2021-9-8 17:08 | 只看该作者
oled.h是自己写的吗
回复

使用道具 举报

18#
ID:65369 发表于 2022-4-3 08:48 | 只看该作者
挺好的例子,多谢!
回复

使用道具 举报

19#
ID:65369 发表于 2022-4-3 08:50 | 只看该作者
请问OLED有 模拟I2C驱动方式的吗,不是用硬件本身资源的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表