找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3259|回复: 8
收起左侧

单片机DS1302时钟芯片的闹钟程序,想加一个整点报时滴滴十秒

[复制链接]
ID:610666 发表于 2019-9-20 11:52 | 显示全部楼层 |阅读模式
想加一个整点报时滴滴十秒的一个程序,不知道怎么写,写好了加在整个程序的哪个位置,请各位大佬不吝赐教,小弟感激不尽!
X(3~BJW{T3A)}OL$[YXH720.png
单片机源程序如下:
//1602显示时钟,按K3进入时钟设置,按K1选择设置的时分秒日月,按K2加1。//
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #define lcd1602data P0
  4. typedef unsigned char u8;
  5. typedef unsigned int u16;
  6. sbit E=P2^7;   //设置液晶端口    使能信号
  7. sbit RW=P2^5;  //读写选择  读:H/写:L
  8. sbit RS=P2^6;  //数据命令选择  数据:H/命令:L
  9. sbit  key1=P3^1;
  10. sbit  key2=P3^0;
  11. sbit  key3=P3^2;
  12. sbit  spk=P1^7;

  13. sbit SCLK=P3^6;   //设置时钟端口
  14. sbit IO=P3^4;
  15. sbit RST=P3^5;  
  16. u16 read[]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};   //设置秒分时日月周年读寄存器
  17. u16 write[]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};  //设置秒分时日月周年写寄存器
  18. u8 time[]={0x30,0x30,0x23,0x13,0x09,0x04,0x19};    //存放初始时间
  19. u16 setmark,setplace;      //setmark检测key3是否按下,setplace选择要调整的时间块。
  20. void delay_ms(u16 n);
  21. void initConfiguration();
  22. void lcdDisplay();
  23. void lcdwrite_com(u8 datas);
  24. void lcdwrite_datas(u8 datas);
  25. void lcdinit();
  26. void writebyte(u8 address,u8 datas);
  27. u8 readbyte(u8 address);
  28. void ds1302init();
  29. void read_time();
  30. void DIDI(u16);
  31. void main()
  32. {
  33.   u16 i;
  34.   initConfiguration();   //初始化
  35.   lcdinit();
  36.   ds1302init();
  37.   while(1)
  38.   {
  39.    if(setmark==0)    //时钟正常运作
  40.    {
  41.     read_time();
  42.    }
  43.    else        //调整时间
  44.    {
  45.      if(key1==0)
  46.     {
  47.      delay_ms(1);
  48.     if(key1==0)
  49.     {
  50.        setplace++;     //按下key1要调整的时间块加一
  51.       setplace%=7;
  52.     }
  53.     while(i<50&&key1==0)    //等待key1松开
  54.      {
  55.      i++;
  56.      delay_ms(10);
  57.      }
  58.      i=0;
  59.     }

  60.     if(key2==0)
  61.     {
  62.       delay_ms(1);
  63.      if(key2==0)        //按下key2对应的初始时间加一
  64.      {
  65.        time[setplace]++;
  66.      if((time[setplace]&0x0f)>9)      //换成BCD码。
  67.      {
  68.       time[setplace]=time[setplace]+6;
  69.      }
  70.      if((time[setplace]>=0x60)&&(setplace<2))  //分秒只能到59
  71.      {
  72.       time[setplace]=0;
  73.      }
  74.      if((time[setplace]>=0x24)&&(setplace==2))  //小时只能到23
  75.      {
  76.       time[setplace]=0;
  77.      }
  78.      if((time[setplace]>=0x32)&&(setplace==3))  //日只能到31
  79.      {
  80.       time[setplace]=1;
  81.      }
  82.      if((time[setplace]>=0x13)&&(setplace==4))  //月只能到12
  83.      {
  84.       time[setplace]=1;
  85.      }
  86.      if((time[setplace]>=0x8)&&(setplace==5))  //周只能到7
  87.      {
  88.      time[setplace]=1;
  89.      }
  90.                   
  91.      }
  92.      while((i<50)&&(0==key2))
  93.      {
  94.       i++;
  95.      delay_ms(10);
  96.      }
  97.      i=0;
  98.     }
  99.    }
  100.    lcdDisplay();
  101.   }
  102. }



  103. void delay_ms(u16 n)    //准确延时一毫秒,晶振12M
  104. {
  105. u16 a,b;
  106. for(;n>0;n--)
  107. {
  108.   for(a=199;a>0;a--)
  109.   {
  110.    for(b=1;b>0;b--)
  111.    {
  112.      ;
  113.    }
  114.   }
  115. }
  116. }


  117. void initConfiguration()  //初始化外部中断0
  118. {
  119. EA=1;
  120. IT0=1;
  121. EX0=1;
  122. }
  123. void init0() interrupt 0  //按下key3时间保持不变
  124. {
  125.   delay_ms(10);
  126.   if(key3==0)
  127.   {
  128.    setmark=~setmark;
  129.   setplace=0;
  130.   ds1302init();
  131.   }
  132. }
  133. void lcdDisplay()      //显示函数
  134. {

  135. lcdwrite_com(0x80+0x00);    //确定写数据的位置
  136. lcdwrite_datas('2');
  137. lcdwrite_datas('0');
  138. lcdwrite_datas('0'+time[6]/16);    //写入年份的高位
  139. lcdwrite_datas('0'+(time[6]&0x0f));  //低位
  140. lcdwrite_datas('-');
  141. lcdwrite_datas('0'+time[4]/16);
  142. lcdwrite_datas('0'+(time[4]&0x0f));  //里面的小括号很重要
  143. lcdwrite_datas('-');  
  144. lcdwrite_datas('0'+time[3]/16);
  145. lcdwrite_datas('0'+(time[3]&0x0f));
  146.   
  147. lcdwrite_com(0x8c);
  148. lcdwrite_datas('0'+(time[5]&0x07));
  149. lcdwrite_com(0xc0);        //跳线帽Joe接vcc
  150. lcdwrite_datas('0'+time[2]/16);
  151. lcdwrite_datas('0'+(time[2]&0x0f));
  152. lcdwrite_datas('-');
  153. lcdwrite_datas('0'+time[1]/16);
  154. lcdwrite_datas('0'+(time[1]&0x0f));
  155. lcdwrite_datas('-');
  156. lcdwrite_datas('0'+time[0]/16);   
  157. lcdwrite_datas('0'+(time[0]&0x0f));
  158. }
  159. void lcdwrite_com(u8 datas)    //lcd液晶写入指令操作        模拟时序
  160. {
  161. E=0;
  162. RW=0;
  163. RS=0;
  164. lcd1602data=datas;
  165. delay_ms(1);
  166. E=1;
  167. //delay_ms(1);
  168. E=0;

  169. }
  170. void lcdwrite_datas(u8 datas)   //lcd液晶写入数据操作
  171. {
  172. E=0;
  173. RW=0;
  174. RS=1;
  175. lcd1602data=datas;
  176. delay_ms(1);       //延时不能太长否则调整不灵敏
  177. E=1;
  178. //delay_ms(1);
  179. E=0;

  180. }
  181. void lcdinit()       //LCD液晶初始化
  182. {
  183. lcdwrite_com(0x38);   //8位总线,显示两行,5x7点阵
  184. lcdwrite_com(0x0c);    //开显示功能,无关标
  185. lcdwrite_com(0x06);    //光标右移,即数据依次右移
  186. lcdwrite_com(0x01);    //清屏
  187. lcdwrite_com(0x80);    //第一个数据位置
  188. }


  189. void writebyte(u8 address,u8 datas)     //在寄存器里写时间数据,模拟时序
  190. {
  191. u8 i;
  192. RST=0;
  193. _nop_();
  194. SCLK=0;
  195. _nop_();
  196. RST=1;
  197. _nop_();
  198. for(i=0;i<8;i++)
  199. {
  200.   IO=address&0x01;
  201.   address>>=1;
  202.   SCLK=1;
  203.   _nop_();
  204.   SCLK=0;
  205.   _nop_();
  206. }
  207. for(i=0;i<8;i++)
  208. {
  209.   IO=datas&0x01;
  210.   datas>>=1;
  211.   SCLK=1;
  212.   _nop_();
  213.   SCLK=0;
  214.   _nop_();
  215. }
  216. RST=0;
  217. }
  218. u8 readbyte(u8 address)     //读寄存器里的时间数据
  219. {
  220. u8 i,datas,dat;
  221. RST=0;
  222. //_nop_();
  223. SCLK=0;
  224. //_nop_();
  225. RST=1;
  226. //_nop_();
  227. for(i=0;i<8;i++)
  228. {
  229.   IO=address&0x01;
  230.   address>>=1;
  231.   SCLK=1;
  232.   _nop_();
  233.   SCLK=0;
  234.   _nop_();
  235. }
  236. //_nop_();
  237. for(i=0;i<8;i++)
  238. {
  239.   dat=IO;
  240.   datas=(datas>>1)|(dat<<7);
  241.   SCLK=1;
  242.   _nop_();
  243.   SCLK=0;
  244.   _nop_();
  245. }
  246. RST=0;
  247. //_nop_();
  248. SCLK=1;
  249. //_nop_();
  250. IO=0;
  251. //_nop_();
  252. IO=1;
  253. //_nop_();
  254. return datas;
  255. }
  256. void ds1302init()      //在寄存器里写入初始时间
  257. {
  258. u8 i;
  259. writebyte(0x8e,0x00);    //关闭写保护寄存器
  260. for(i=0;i<7;i++)
  261. {
  262.   writebyte(write[i],time[i]);
  263. }
  264. writebyte(0x8e,0x80);     //打开写保护寄存器
  265. }
  266. void read_time()       //读取时钟时间    time数组存储
  267. {
  268. u8 i;
  269. for(i=0;i<7;i++)
  270. {
  271.   time[i]=readbyte(read[i]);
  272. }
  273. }
复制代码


回复

使用道具 举报

ID:307020 发表于 2019-9-20 16:51 | 显示全部楼层
假设BUZ1上接VCC,在小时位增加1时P1.7输出一定频率的高电位脉冲(101010),Q1按频率通断,BUZ1出声;秒加十后P1.7输出低电位0关掉Q1便可。
回复

使用道具 举报

ID:610666 发表于 2019-9-20 21:27 | 显示全部楼层
wj_yuq 发表于 2019-9-20 16:51
假设BUZ1上接VCC,在小时位增加1时P1.7输出一定频率的高电位脉冲(101010),Q1按频率通断,BUZ1出声;秒加 ...

就是BUZ1上接Vcc,从23点到0点,会响吗?
具体程序该怎么写,加在哪个位置?
请赐教
回复

使用道具 举报

ID:123289 发表于 2019-9-21 08:59 | 显示全部楼层
只要你不抄别人的程序,你就能办到。
回复

使用道具 举报

ID:610666 发表于 2019-9-21 23:42 | 显示全部楼层
yzwzfyz 发表于 2019-9-21 08:59
只要你不抄别人的程序,你就能办到。

因为不太懂,这个是参照别人的程序写的,望指点
回复

使用道具 举报

ID:307020 发表于 2019-9-23 13:13 | 显示全部楼层
即便是参照别人程序写的,也要整明白,你代码中“u8 time[]={0x30,0x30,0x23,0x13,0x09,0x04,0x19};    //存放初始时间”保存了从DS1302模块读来的实时数据,对照DS1302的Data Sheet,研读你程序代码,找到”小时“”秒“数据在time[]中的具体位置,在代码中增加”小时缓存“、”BUZ计数“变量,比较”小时缓存“与time[]中小时数据;当time[]中小时数据=”小时缓存“+1时,按顺序进行如下内容:1”BUZ计数“==10(BUZ秒数);2P1.7输出一定频率的高电位脉冲(101010),Q1按频率通断,BUZ1出声;3”BUZ计数“=”BUZ计数“-1直到”BUZ计数“=0;4P1.7输出低电位0关掉Q1;”小时缓存“=”小时缓存“+1。具体放在什么位置无所谓,学单片机的乐趣在于搞明白,然后实现自己的想法。
回复

使用道具 举报

ID:610666 发表于 2019-9-23 21:53 | 显示全部楼层
wj_yuq 发表于 2019-9-23 13:13
即便是参照别人程序写的,也要整明白,你代码中“u8 time[]={0x30,0x30,0x23,0x13,0x09,0x04,0x19};    // ...

您好,我才开始学,能明白您说的意思,但是自己学疏才浅不能实现您指点的这些,望您写个范例,供我参考、学习,感激不尽
回复

使用道具 举报

ID:429156 发表于 2019-9-26 14:38 | 显示全部楼层
程序中加个判断不就搞定?
回复

使用道具 举报

ID:610666 发表于 2019-9-26 19:59 | 显示全部楼层
xiaomi_51hei 发表于 2019-9-26 14:38
程序中加个判断不就搞定?

关键是不会呀
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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