找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机自动打铃器仿真 pcf8563时钟源程序+电路原理图

[复制链接]
跳转到指定楼层
楼主

51单片机自动打铃器仿真电路原理图(工程文件清晰版请下载本帖最后的附件),采用实时日历时钟芯片pcf8563提供准确的时钟.

下面是51单片机自动打铃器pcf8563芯片的驱动程序:
  1. #include <AT89X52.h>
  2. #include <stdio.h>     
  3. bit bclassFlg = 0;
  4. sbit FMQ = P3 ^ 7;

  5. unsigned char stringtemp[10]="";

  6. struct time
  7. {
  8.         unsigned char        second;
  9.         unsigned char        minute;
  10.         unsigned char        hour;
  11.         unsigned char        day;
  12.         unsigned char        weekday;
  13.         unsigned char        month;
  14.         unsigned int        year;
  15. } time;

  16. sbit tim_sda=P2^6;
  17. sbit tim_scl=P2^7;

  18. sbit        lcd16rs        =        P2^0;
  19. sbit        lcd16rw        =        P2^1;
  20. sbit        lcd16en        =        P2^2;

  21. unsigned char        lcd16_1[16];
  22. unsigned char        lcd16_2[16] = {"welcome"};


  23. bit         tim_ack;                // i2c slave ack.
  24. bit         tim_err;
  25. unsigned char tim_rd_buffer[16];
  26. unsigned char tim_wr_buffer[16];

  27. /*****************11us延时函数*************************/
  28. void delay11us(unsigned char t)
  29. {
  30.   for (;t>0;t--);
  31. }



  32. void delay(unsigned int x)
  33. {
  34.         unsigned int a,b;
  35.         for(a=x;a>5;a--);
  36.                 for(b=10;b>0;b--);
  37. }



  38. //写指令
  39. void write_com(unsigned char com)
  40. {
  41.         P1=com;// 将指令值写到数据线上
  42.         lcd16rs=0;//写指令
  43.         lcd16en=0;//给一个LCD 使能脉冲
  44.         delay(10);
  45.         lcd16en=1;
  46.         delay(10);
  47.         lcd16en=0;
  48.        
  49. }

  50. //写数据
  51. void write_date(unsigned char date)
  52. {
  53.         P1=date;    //将数据写到数据线上
  54.         lcd16rs=1;    //写数据
  55.         lcd16en=0;    //给一个LCD 使能脉冲
  56.         delay(10);
  57.         lcd16en=1;
  58.         delay(10);
  59.         lcd16en=0;
  60.        
  61. }


  62. //初始化LCD
  63. void lcd_init()
  64. {
  65.         lcd16rw = 0;
  66.         write_com(0x38);//显示模式设置
  67.         delay(20);
  68.         write_com(0x0f);//开显示,显示光标、光标闪烁
  69.         delay(20);
  70.         write_com(0x06);//光标和显示指针加一,屏幕不移动
  71.         delay(20);
  72.         write_com(0x01);//清显示屏
  73.         delay(20);       
  74. }


  75. //在第N行显示第M个字
  76. void lcd16_n_line_n_byte(unsigned char n_line,unsigned char n_byte)
  77. {
  78.         unsigned char j;
  79.         unsigned char com;
  80.         unsigned char *dat1;
  81.         unsigned char *dat2;

  82.         dat1 = lcd16_1;
  83.         dat2 = lcd16_2;

  84.         if(n_line==0)                                   //显示第一行。
  85.         {
  86.                 for(j=0;j<n_byte;j++)
  87.                 {
  88.                         com = 0x80+j;
  89.                         write_com(com);
  90.                         write_date(*dat1);
  91.                         dat1++;
  92.                 }       
  93.         }
  94.         if(n_line==1)                           //显示第二行。
  95.         {
  96.                 for(j=0;j<n_byte;j++)
  97.                 {
  98.                         com = 0xc0+j;
  99.                         write_com(com);
  100.                         write_date(*dat2);
  101.                         dat2++;
  102.                 }       
  103.         }
  104. }

  105. // i2c start.
  106. void PCF8563_start()        //start flag is when tim_scl 1, tim_sdafrom 1 to 0.
  107. {
  108.         tim_sda = 1;
  109.         delay11us(1);
  110.         tim_scl = 1;
  111.         delay11us(1);
  112.         tim_sda = 0;
  113.         delay11us(1);
  114. }

  115. // i2c stop.
  116. void PCF8563_stop()                         //start flag is when tim_scl 1, tim_sdafrom 0 to 1.
  117. {
  118.         tim_sda = 0;
  119.         delay11us(1);
  120.         tim_scl = 1;
  121.         delay11us(1);
  122.         tim_sda = 0;
  123. }

  124. //i2c slave respons.
  125. void PCF8563_respons()
  126. {
  127.         unsigned char i;
  128.         tim_scl = 1;
  129.         delay11us(1);
  130.         while((tim_sda)&&(i<250))  i++;
  131.         if(!tim_sda)
  132.                 tim_ack = 1;
  133.         else
  134.                 tim_ack = 0;
  135.         tim_scl = 0;
  136.         delay11us(1);
  137. }

  138. // i2c master respons.
  139. void PCF8563_master_respons(bit master_ack)
  140. {
  141.         tim_scl = 0;
  142.         delay11us(1);
  143.         tim_sda = ~master_ack;
  144.         delay11us(1);
  145.         tim_scl = 1;
  146.         delay11us(1);
  147.         tim_scl = 0;
  148.         delay11us(1);
  149. }

  150. //i2c init.
  151. void PCF8563_init()
  152. {
  153.         tim_sda = 1;
  154.         delay11us(1);
  155.         tim_scl = 1;
  156.         delay11us(1);
  157. }

  158. // i2c write n byte.
  159. void PCF8563_wr_byte(unsigned char dat)
  160. {
  161.         unsigned char i , temp;
  162.         temp = dat;
  163.         for(i=0;i<8;i++)
  164.         {
  165.                 tim_scl = 0;
  166.                 delay11us(1);

  167.                
  168.                 if(temp&0x80)
  169.                         tim_sda = 1;
  170.                 else
  171.                         tim_sda = 0;
  172.                 temp = temp<<1;
  173.                
  174.                 delay11us(1);
  175.                 tim_scl = 1;
  176.                 delay11us(1);

  177.         }
  178.         tim_scl = 0;
  179.         delay11us(1);
  180.         tim_sda = 1;                       
  181.         delay11us(1);
  182. }

  183. unsigned char PCF8563_rd_byte()
  184. {
  185.         unsigned char i,k;
  186.         tim_scl = 0;
  187.         delay11us(1);
  188.         tim_sda = 1;
  189.         delay11us(1);
  190.         for(i=0;i<8;i++)
  191.         {
  192.                 tim_scl = 1;
  193.                 delay11us(1);
  194.                 k = (k<<1)|tim_sda;
  195.                 tim_scl = 0;
  196.                 delay11us(1);
  197.         }
  198.         return k;
  199. }

  200. void PCF8563_write_n_byte(unsigned char add,unsigned char com,unsigned char *dat,unsigned char n_byte)   //
  201. {
  202.         unsigned char i = 0;
  203.         unsigned char temp;

  204.         temp = *dat;                                  // send to begin address to 'temp'.

  205.         add = add<<1;
  206.         add = 0xa0+add+0x00;                       

  207.         PCF8563_start();
  208.         PCF8563_wr_byte(add);                 //send EEPROM address, bit 0 = 0 is write.
  209.         PCF8563_respons();
  210.         if(!tim_ack)                                //if i2c respons.
  211.         {
  212.                 tim_err = 1;
  213.                 return;
  214.         }
  215.        
  216.         PCF8563_wr_byte(com);                        //send EEPROM beginning address.
  217.         PCF8563_respons();
  218.         if(!tim_ack)                                //if i2c respons.
  219.         {
  220.                 tim_err = 1;
  221.                 return;
  222.         }
  223.        
  224.         while(n_byte)                           //write n byte.
  225.         {
  226.                 PCF8563_wr_byte(temp);
  227.                 PCF8563_respons();
  228.                 if(!tim_ack)                               
  229.                 {
  230.                         tim_err = 1;
  231.                         PCF8563_stop();       
  232.                         return;
  233.                 }
  234.                 temp++;
  235.                 n_byte--;
  236.         }
  237.        
  238.         PCF8563_stop();       
  239. }

  240. void PCF8563_read_n_byte(unsigned char add,unsigned char com,unsigned char n_byte)
  241. {
  242.         unsigned char *temp;

  243.         temp = tim_rd_buffer;

  244.         add = add<<1;
  245.         add = 0xa0+add+0x00;                       

  246.         PCF8563_start();

  247.         PCF8563_wr_byte(add);                                 //send address + wr.
  248.         PCF8563_respons();

  249.         PCF8563_wr_byte(com);                                // first byte address.
  250.         PCF8563_respons();

  251.         add = add+0x01;                       

  252.         PCF8563_start();
  253.         PCF8563_wr_byte(add);                           //send address + rd.
  254.         PCF8563_respons();

  255.         while(n_byte)                                   // rd n byte .
  256.         {
  257.                 *temp = PCF8563_rd_byte();
  258.                 if(n_byte != 1)                                //if i2c respons.
  259.                 {
  260.                         PCF8563_master_respons(1);        //if the number is not the last one, master send a ack bit.
  261.                 }
  262.                 temp++;
  263.                 n_byte--;
  264.         }
  265.         PCF8563_stop();
  266. }

  267. void PCF8563_wr_time()
  268. {
  269.         tim_wr_buffer[0] = 0x00;        //second
  270.         tim_wr_buffer[1] = 0x11;        //minute
  271.         tim_wr_buffer[2] = 0x22;        //hour

  272.         tim_wr_buffer[3] = 0x15;        //day
  273.         tim_wr_buffer[4] = 0x03;        //weekday
  274.         tim_wr_buffer[5] = 0x06;        //month
  275.         tim_wr_buffer[6] = 0x10;        //year

  276.        
  277.         PCF8563_write_n_byte(1,2,tim_wr_buffer,8);
  278. }

  279. //延时眼熟
  280. void DelayFM(unsigned int x)  
  281. {
  282.         unsigned char t;
  283.         while(x--)
  284.         {
  285.                  for(t=0;t<120;t++);
  286.         }
  287. }
  288. //蜂鸣器驱动函数,参数为发声声调
  289. void FM(unsigned char x)
  290. {
  291.         unsigned char i;
  292.         for(i=0;i<100;i++)
  293.         {
  294.                  FMQ = ~FMQ;
  295.                 DelayFM(x);
  296.         }
  297.         FMQ = 0;
  298. }

  299. void PCF8563_rd_time()
  300. {
  301.         unsigned char        temp;


  302.         PCF8563_read_n_byte(1,2,9);

  303.         time.second = ((tim_rd_buffer[1]&0x70)>>4)*10 + (tim_rd_buffer[1]&0x0f);        //second                        

  304.         time.minute = ((tim_rd_buffer[2]&0x70)>>4)*10 + (tim_rd_buffer[2]&0x0f);        //minute

  305.         time.hour = ((tim_rd_buffer[3]&0x30)>>4)*10 + (tim_rd_buffer[3]&0x0f);                //hour
  306.         time.day = ((tim_rd_buffer[4]&0x30)>>4)*10 + (tim_rd_buffer[4]&0x0f);                //day
  307.         time.weekday = tim_rd_buffer[5]&0x07;                                                                                //weekday
  308.         time.month = ((tim_rd_buffer[6]&0x10)>>4)*10 + (tim_rd_buffer[6]&0x0f);                //month

  309.   if(time.second == 0)
  310.   {
  311.     if(bclassFlg == 0 )
  312.     {
  313.       sprintf(stringtemp,"%x%x",time.hour,time.minute);
  314. //      printf("%s\n",stringtemp);
  315.       printf("it's time to have class\n"); //上课
  316.       bclassFlg = 1;
  317.       FM(3);
  318.     }
  319.   }
  320.   else if(time.second == 45) //如果到了45分钟,开始下课铃
  321.   {
  322.     if(bclassFlg == 1)
  323.     {
  324.       sprintf(stringtemp,"%x%x",time.hour,time.minute);
  325. //      printf("%s\n",stringtemp);
  326.       printf("it's time to finish class\n");
  327.       bclassFlg = 0;
  328.       FM(7);
  329.     }
  330.   }
  331.   else
  332.   {
  333.   }

  334.         temp = (tim_rd_buffer[4]&0x80)>>7;
  335.         time.year = (temp+20)*100+((tim_rd_buffer[7]&0x70)>>4)*10 + (tim_rd_buffer[7]&0x0f);           //year
  336.                 lcd16_1[0] = time.hour/10+0x30;          //hour
  337.                 lcd16_1[1] = time.hour%10+0x30;
  338.                 lcd16_1[2] = '-';
  339.                 lcd16_1[3] = time.minute/10+0x30;          //minute
  340.                 lcd16_1[4] = time.minute%10+0x30;
  341.                 lcd16_1[5] = '-';
  342.                 lcd16_1[6] = time.second/10+0x30;          //second
  343.                 lcd16_1[7] = time.second%10+0x30;

  344.                 lcd16_2[0] = time.year/1000+0x30;          //year
  345.                 lcd16_2[1] = (time.year%1000)/100+0x30;
  346.                 lcd16_2[2] = (time.year%100)/10+0x30;
  347.                 lcd16_2[3] = time.year%10+0x30;
  348.                 lcd16_2[4] = '-';
  349.                 lcd16_2[5] = time.month/10+0x30;  //mon
  350.                 lcd16_2[6] = time.month%10+0x30;
  351.                 lcd16_2[7] = '-';
  352.                 lcd16_2[8] = time.day/10+0x30;          //day
  353.                 lcd16_2[9] = time.day%10+0x30;

  354.                 lcd16_2[10] = 'w';
  355.                 lcd16_2[11] = 'e';
  356.                 lcd16_2[12] = 'e';
  357.                 lcd16_2[13] = 'k';
  358.                 lcd16_2[14] = ':';
  359.                 lcd16_2[15] = time.weekday+0x30;

  360.                 lcd16_n_line_n_byte(0,16);
  361.                 lcd16_n_line_n_byte(1,16);
  362. }




  363. void DelayMS(unsigned int ms)
  364. {
  365.         unsigned char i;
  366.         while(ms--)
  367.         {
  368.                  for(i=0;i<120;i++);
  369.         }
  370. }

  371. void InitUart(void)
  372. {
  373.         SCON = 0x50;                                  //工作方式1
  374.         TMOD = 0x21;
  375.         PCON = 0x00;
  376.         TH1 = 0xfd;                                   //使用T1作为波特率发生器
  377.         TL1 = 0xfd;
  378.         TI = 1;
  379.         TR1 = 1;                                      //启动T1                                                                  //启动T1  
  380. }

  381. void main()
  382. {
  383.   PCF8563_init();
  384. //        PCF8563_wr_time();
  385.         lcd_init();
  386.   InitUart();
  387.         while(1)
  388.         {
  389.                 PCF8563_rd_time();
  390.     DelayMS(250);
  391.         }
  392. }
复制代码



51单片机pcf8563自动打铃器仿真的所有资料下载:http://www.51hei.com/bbs/dpj-54940-1.html

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

使用道具 举报

沙发
ID:207690 发表于 2017-6-4 15:46 | 只看该作者
怎么下载
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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