找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机12864闹钟代码

[复制链接]
跳转到指定楼层
楼主
ID:432036 发表于 2018-11-23 19:55 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式
闹钟简单代码
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #include<stdlib.h>

  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. /*端口定义*/
  7. sbit LCD_RS=P2^6;
  8. sbit LCD_RW=P2^5;
  9. sbit LCD_EN=P2^4;
  10. sbit LCD_PSB=P2^3;
  11. sbit DQ=P3^7;                              //18b20
  12. sbit SDA=P1^4;                              //ds32321            //模拟I2C数据传送位SDA        
  13. sbit SCL=P1^3;                                   //模拟I2C时钟控制位SCL
  14. //***按键功能****//
  15. ////***K1停止时间显示****//
  16. ////***K2选择修改位置****//
  17. ////***K3进行加1的修改****//
  18. ////***K4将修改写入ds3231,同时启动时间显示****//
  19. sbit K1=P3^2;                       
  20. sbit K2=P3^3;
  21. sbit K3=P3^4;
  22. sbit K4=P3^5;
  23. //定义变量               
  24. uchar numbr[10]="0123456789";                      //字模


  25. uchar dis4[]="   ";                                                            //          第四行显示   自己添加
  26. uchar t[]="  .   ℃" ;                                            //18b20
  27. uint sdata,xiaoshu1,xiaoshu2;                                 //整数、小数1位、小数2位
  28. bit fg=1;                                  //温度正负标志
  29. uchar tempL=0,tempH=0;                                                                // 变量         
  30. uchar year,month,date,hour,min,sec;                                 //    ds3231
  31. uchar a[]="2011年22月33日";
  32. uchar b[]="11时22分33秒";
  33.                                 ///函数
  34. //******************延时子程序 *******************************

  35. //这个延时程序的具体延时时间是time=i*8+10,适用于小于2ms的延时

  36. //************************************************************
  37. void delay(unsigned char i)
  38. {
  39. for(i;i>0;i--);
  40. }
  41. //***********************************************************
  42. //                     延时子程序
  43. //************************************************************
  44. void delay1ms(uchar j)
  45. {
  46. while(j!=0)
  47. {uchar i;
  48. for(i=124;i>0;i--);  //延时124*8+10=1002us
  49. j--;
  50. }
  51. }
  52. /**************************12864部分*************************************/
  53. /**************************12864部分*************************************/     
  54.                                                                                              /*写指令数据到LCD
  55.                                                                                              RS=L——表示DB0-DB7为显示指令数据
  56.                                                                                              RW=L——表示DB0-DB7数据被write(当E=“H-L”,指令数据被写到IR或DR)
  57.                                                                                              E=高脉冲
  58.                                                                                              此时DB0-DB7=指令码   */
  59. void write_cmd(uchar cmd)
  60. {
  61.          LCD_RS=0;
  62.          LCD_RW=0;
  63.          LCD_EN=0;
  64.          P0=cmd;
  65.          delay1ms(5);
  66.          LCD_EN=1;
  67.          delay1ms(5);
  68.          LCD_EN=0;
  69. }
  70.                                                                                     /*设定显示位置*/
  71. void lcd_pos(uchar X, uchar Y)
  72. {
  73.          ucharpos;

  74.          if(X== 0)
  75.          {
  76.                    X= 0x80;
  77.          }
  78.          elseif(X == 1)
  79.          {
  80.                    X= 0x90;
  81.          }
  82.          elseif(X == 2)
  83.          {
  84.                    X= 0x88;
  85.          }
  86.          elseif(X == 3)
  87.          {
  88.                    X= 0x98;
  89.          }
  90.          pos= X + Y;
  91.          write_cmd(pos);                                                     //显示地址
  92. }

  93.                                                                                                                 /*写显示数据到LCD*/
  94.                                                                                                                 /*
  95.                                                                                                                          RS=H——表示DB0-DB7为显示数据
  96.                                                                                                                          RW=L——RW=L,E='H-L',DB0-DB7数据被写到IR或DR   
  97.                                                                                                                           E=高脉冲
  98.                                                                                                                          DB0-DB7=显示数据        */
  99. void write_dat(uchar dat)
  100. {
  101.          LCD_RS=1;
  102.          LCD_RW=0;
  103.          LCD_EN=0;
  104.          P0=dat;
  105.          delay1ms(5);
  106.          LCD_EN=1;
  107.          delay1ms(5);
  108.          LCD_EN=0;
  109. }
  110.                                                                                                                          /*LCD初始化*/
  111. void lcd_init()
  112. {        uinti;

  113.          LCD_PSB=1;                                                                                //并口方式
  114.          write_cmd(0x30);                                                            //基本操作指令
  115.          delay1ms(5);
  116.          write_cmd(0x0c);                                                            //打开显示,光标关闭
  117.          delay1ms(5);
  118.          write_cmd(0x01);                                                            //清除LCD显示类容
  119.          delay1ms(5);


  120.          lcd_pos(3,0);
  121.                                      i=0;
  122.                                      while(dis4[ i]!='\0')
  123.                                                {
  124.                                                delay1ms(1);
  125.                                                write_dat(dis4);
  126.                                                delay1ms(1);
  127.                                                i++;
  128.                                                }

  129. }
  130. /**********************************18b20************************************************/
  131. /**********************************18b20************************************************/


  132. void Init_DS18B20(void)                                                                                              //初始化
  133. {
  134. uchar x=0;
  135. DQ=1; //DQ先置高
  136. delay(8); //稍延时
  137. DQ=0; //发送复位脉冲
  138. delay(80); //延时(>480us)
  139. DQ=1; //拉高数据线
  140. delay(5); //等待(15~60us)
  141. x=DQ; //用X的值来判断初始化有没有成功,18B20存在的话X=0,否则X=1
  142. delay(20);
  143. }

  144. //**********读一个字节************//

  145. ReadOneChar(void)  //主机数据线先从高拉至低电平1us以上,再使数据线升为高电平,从而产生读信号
  146. {
  147. unsigned char i=0; //每个读周期最短的持续时间为60us,各个读周期之间必须有1us以上的高电平恢复期
  148. unsigned char dat=0;
  149. for (i=8;i>0;i--) //一个字节有8位
  150. {
  151. DQ=1;
  152. delay(1);
  153. DQ=0;
  154. dat>>=1;
  155. DQ=1;
  156. if(DQ)
  157. dat|=0x80;
  158. delay(4);
  159. }
  160. return(dat);
  161. }
  162. //*********************** **写一个字节**************************//

  163. void WriteOneChar(unsigned char dat)
  164. {
  165. unsigned char i=0; //数据线从高电平拉至低电平,产生写起始信号。15us之内将所需写的位送到数据线上,
  166. for(i=8;i>0;i--) //在15~60us之间对数据线进行采样,如果是高电平就写1,低写0发生。
  167.   {
  168.   DQ=0; //在开始另一个写周期前必须有1us以上的高电平恢复期。
  169.   DQ=dat&0x01;
  170.   delay(5);
  171.   DQ=1;
  172.   dat>>=1;
  173.   }
  174. delay(4);
  175. }

  176. void ReadTemperature(void)                                                                                      //读温度值(低位放tempL;高位放tempH;)//
  177.          {
  178.           Init_DS18B20(); //初始化
  179.           WriteOneChar(0xcc); //跳过读序列号的操作
  180.           WriteOneChar(0x44); //启动温度转换
  181.           delay(125); //转换需要一点时间,延时
  182.           Init_DS18B20(); //初始化
  183.           WriteOneChar(0xcc); //跳过读序列号的操作
  184.           WriteOneChar(0xbe); //读温度寄存器(头两个值分别为温度的低位和高位)
  185.           tempL=ReadOneChar(); //读出温度的低位LSB
  186.           tempH=ReadOneChar(); //读出温度的高位MSB

  187.                    if(tempH>0x7f)      //最高位为1时温度是负
  188.                    {
  189.                     tempL=~tempL;         //补码转换,取反加一
  190.                     tempH=~tempH+1;      
  191.                     fg=0;     //读取温度为负时fg=0
  192.       }
  193.                    sdata= tempL/16+tempH*16;      //整数部分
  194.                    xiaoshu1= (tempL&0x0f)*10/16; //小数第一位
  195.                    xiaoshu2= (tempL&0x0f)*100/16%10;//小数第二位
  196.                    t[0]=numbr[sdata/10];
  197.                    t[1]=numbr[sdata%10];
  198.                    t[3]=numbr[xiaoshu1];
  199.                    t[4]=numbr[xiaoshu2];

  200.          }
  201. /*****************************************ds3231********************************************/

  202. #define ADDRTW          0xD0    //器件写地址
  203. #define ADDRTD          0xD1 //器件读地址
  204. #define DS3231_SEC      0x00   //秒
  205. #define DS3231_MIN      0x01   //分
  206. #define DS3231_HOUR     0x02   //时
  207. #define DS3231_DAY      0x03   //星期
  208. #define DS3231_DATE     0x04   //日
  209. #define DS3231_MONTH    0x05   //月
  210. #define DS3231_YEAR     0x06   //年
  211. //闹铃1            
  212. #define DS3231_Al1SEC   0x07   //秒
  213. #define DS3231_AL1MIN   0x08   //分
  214. #define DS3231_AL1HOUR  0x09   //时
  215. #define DS3231_AL1DAY   0x0A   //星期/日
  216. //闹铃2
  217. #define DS3231_AL2MIN   0x0b   //分
  218. #define DS3231_AL2HOUR  0x0c   //时
  219. #define DS3231_AL2DAY   0x0d   //星期/日
  220. #define DS3231_CONTROL  0x0e   //控制寄存器
  221. #define DS3231_STATUS   0x0f   //状态寄存器
  222. bit ack;


  223. uchar BCD2HEX(uchar val)           //BCD转换为Byte           
  224. {        uchari;
  225.    i= val&0x0f;
  226.    val >>= 4;
  227.    val &= 0x0f;
  228.    val *= 10;
  229.     i+= val;

  230.    return i;
  231. }


  232. uchar HEX2BCD(uchar val)//B码转换为BCD码
  233.          {
  234.          uchari,j,k;

  235.            i=val/10;
  236.            j=val%10;
  237.            k=j+(i<<4);
  238.            return k;
  239.          }

  240. void Start()      
  241. {
  242.    SDA=1;                  //发送起始条件的数据信号
  243.    delay(1);
  244.    SCL=1;
  245.    delay(5);             //起始条件建立时间大于4.7us,延时
  246.      SDA=0;                  //发送起始信号
  247.    delay(5);             // 起始条件锁定时间大于4μs
  248.    SCL=0;                  //钳住I2C总线,准备发送或接收数据
  249.    delay(2);
  250. }
  251. void Stop()
  252. {
  253.    SDA=0;                  //发送结束条件的数据信号
  254.    delay(1);             //发送结束条件的时钟信号
  255.    SCL=1;                  //结束条件建立时间大于4us
  256.     delay(5);

  257.    SDA=1;                  //发送I2C总线结束信号
  258.    delay(4);
  259. }
  260. /********************************************************/
  261. /*******************************************************************
  262.                   字节数据发送函数               
  263. 函数原型:     void  SendByte(uchar Dat);
  264. 功能:      将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
  265.           此状态位进行操作.(不应答或非应答都使ack=0)
  266.           ack=1        发送数据正常,
  267.           ack=0        被控器无应答或损坏。
  268. ********************************************************************/
  269. void SendByte(uchar Dat)
  270. {
  271. uchar BitCnt;

  272.    for(BitCnt=0;BitCnt<8;BitCnt++)         //要传送的数据长度为8位
  273.     {
  274.        if((Dat<<BitCnt)&0x80)
  275.            SDA=1;                          //判断发送位
  276.        else
  277.            SDA=0;               
  278.          delay(1);
  279.          SCL=1;                            //置时钟线为高,通知被控器开始接收数据位
  280.          delay(5);                       //保证时钟高电平周期大于4μs   
  281.          SCL=0;
  282.     }

  283.    delay(2);
  284.    SDA=1;                                 //8位发送完后释放数据线,准备接收应答位
  285.    delay(2);  
  286.    SCL=1;
  287.     delay(3);
  288.    if(SDA==1)
  289.        ack=0;   
  290.    else
  291.        ack=1;                             //判断是否接收到应答信号
  292.    SCL=0;
  293.    delay(2);
  294. }

  295. uchar RcvByte()                                                                                  //功能:     用来接收从器件传来的数据,并判断总线错误(不发应答信号),发完后请用应答函数应答从机。
  296. {
  297. uchar retc;
  298. uchar BitCnt;

  299.   retc=0;
  300.   SDA=1;                          //置数据线为输入方式
  301.   for(BitCnt=0;BitCnt<8;BitCnt++)
  302.    {
  303.        delay(1);  
  304.        SCL=0;                      //置时钟线为低,准备接收数据位

  305.        delay(5);                 //时钟低电平周期大于4.7μs

  306.        SCL=1;                      //置时钟线为高使数据线上数据有效
  307.        delay(3);
  308.        retc=retc<<1;
  309.        if(SDA==1)
  310.            retc=retc+1;            //读数据位,接收的数据位放入retc中
  311.        delay(2);
  312.    }
  313.   SCL=0;
  314.   delay(2);
  315.   return(retc);
  316. }

  317. void I2CACK(bit a)                       // 功能:       主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
  318. {

  319.    if(a==0)
  320.        SDA=0;              //在此发出应答或非应答信号
  321.    else
  322.        SDA=1;
  323.    delay(3);     
  324.    SCL=1;

  325.    delay(5);             //时钟低电平周期大于4μs

  326.    SCL=0;                  //清时钟线,钳住I2C总线以便继续接收
  327.    delay(2);   
  328. }



  329. uchar I2CRead()                                                                                  /************从DS3231当前地址读一个字节************/
  330. {
  331. uchar read_data;
  332.          Start();
  333.    SendByte(ADDRTD);                                             
  334.    if(ack==0)
  335.     {
  336. return(0);
  337.     }
  338.    read_data = RcvByte();
  339.    I2CACK(1);
  340.    Stop();
  341.    return read_data;
  342. }


  343. uchar I2CReadAdd(uchar addr)                                                      /************从DS3231指定地址读一个字节************/
  344.          {
  345.              Start();
  346.              SendByte(ADDRTW);                           
  347.              if(ack==0)
  348.              {        
  349.            return(0);
  350.              }
  351.              SendByte(addr);
  352.              if(ack==0)
  353.              {        
  354.            return(0);
  355.              }
  356.              return(I2CRead());
  357.          }
  358. void Readtime()                                                                                            /*********************读取时间**********************/
  359.          {
  360.           uchar temp;
  361.           temp=I2CReadAdd(DS3231_SEC);//秒
  362.           sec=BCD2HEX(temp);

  363.           temp=I2CReadAdd(DS3231_MIN);//分
  364.           min=BCD2HEX(temp);

  365.           temp=I2CReadAdd(DS3231_HOUR);  //时                  
  366.           hour=BCD2HEX(temp);

  367.           temp=I2CReadAdd(DS3231_DATE);  //日
  368.           date=BCD2HEX(temp);

  369.           temp=I2CReadAdd(DS3231_MONTH); //月
  370.           month=BCD2HEX(temp);

  371.           temp=I2CReadAdd(DS3231_YEAR);  //年
  372.           year=BCD2HEX(temp);
  373.           }

  374. void InitDS3231()                                                                                                            //ds3231初始化
  375.          {SCL=1;
  376.           delay(5);
  377.           SDA=1;
  378.           delay(5);

  379.          }
  380. void TimeDisplay(uchar Dhour,ucharDmin,uchar Dsec)                                     //时分秒数组赋值
  381.          {        b[0]=numbr[Dhour / 10];        // 时十位
  382.              b[1]=numbr[Dhour % 10];        // 时个位
  383.              b[4]=numbr[Dmin / 10];         // 分十位
  384.              b[5]=numbr[Dmin % 10];         // 分个位
  385.              b[8]=numbr[Dsec / 10];         // 秒十位
  386.              b[9]=numbr[Dsec % 10];         // 秒个位
  387.          }
  388. void DateDisplay(uchar Dyear,ucharDmonth,uchar Dday)                       //年月天数组赋值   
  389.          {        a[2]=numbr[Dyear / 10];        // 年十位
  390.              a[3]=numbr[Dyear % 10];        // 年个位
  391.              a[6]=numbr[Dmonth / 10];       // 月十位
  392.              a[7]=numbr[Dmonth % 10];       // 月个位
  393.              a[10]=numbr[Dday / 10];         // 天十位
  394.              a[11]=numbr[Dday % 10];         // 天个位                                   
  395.          }

  396. void Start_I2C()
  397. {
  398.    SDA=1;                  //发送起始条件的数据信号
  399.    delay(1);
  400.    SCL=1;
  401.    delay(5);             //起始条件建立时间大于4.7us,延时

  402.    SDA=0;                  //发送起始信号
  403.    delay(5);             // 起始条件锁定时间大于4μs

  404.    SCL=0;                  //钳住I2C总线,准备发送或接收数据
  405.    delay(2);
  406. }

  407. void Stop_I2C()
  408. {
  409.     SDA=0;                  //发送结束条件的数据信号
  410.    delay(1);             //发送结束条件的时钟信号
  411.    SCL=1;                  //结束条件建立时间大于4us
  412.    delay(5);

  413.    SDA=1;                  //发送I2C总线结束信号
  414.    delay(4);
  415. }

  416. uchar write_byte(uchar addr, ucharwrite_data)
  417. {
  418.    Start_I2C();
  419.    SendByte(ADDRTW);                //////*******************************************************************///////////
  420.    if (ack == 0)
  421.        return 0;

  422.    SendByte(addr);   
  423.    if (ack == 0)
  424.        return 0;

  425.    SendByte(write_data);
  426.    if (ack == 0)
  427.        return 0;

  428.    Stop_I2C();
  429.     delay1ms(10);      
  430.    return 1;
  431. }

  432. void ModifyTime(uchar yea,uchar mon,ucharda,uchar hou,uchar min,uchar sec)
  433. {     uchar temp=0;

  434.    temp=HEX2BCD(yea);
  435.    write_byte(DS3231_YEAR,temp);   //修改年

  436.    temp=HEX2BCD(mon);
  437.    write_byte(DS3231_MONTH,temp);  //修改月

  438.    temp=HEX2BCD(da);                                                                                     /////////////////////
  439.    write_byte(DS3231_DATE,temp);   //修改日

  440.    temp=HEX2BCD(hou);
  441.    write_byte(DS3231_HOUR,temp);   //修改时

  442.    temp=HEX2BCD(min);
  443.    write_byte(DS3231_MIN,temp); //修改分

  444.    temp=HEX2BCD(sec);
  445.    write_byte(DS3231_SEC,temp); //修改秒
  446. }





  447. void xianshi(void)
  448.    {

  449.                             {uint i;


  450.                    TimeDisplay(hour,min,sec);                                                                                         
  451.                                      lcd_pos(1,1);                         //时间
  452.                                      i=0;
  453.                                      while(b[ i]!='\0')
  454.                                                {
  455.                                                delay1ms(1);
  456.                                                write_dat(b);
  457.                                                delay1ms(1);
  458.                                                i++;
  459.                                                }

  460.                                      DateDisplay(year,month,date);        //显示日期                                                                                                                                                                    
  461.                                      delay1ms(1);
  462.                                      lcd_pos(0,0);
  463.                                      i=0;
  464.                                      while(a[ i]!='\0')
  465.                                                {
  466.                                                delay1ms(1);
  467.                                                write_dat(a);
  468.                                                delay1ms(1);
  469.                                                i++;
  470.                                                }
  471.                                      ReadTemperature();                                                                //显示温度
  472.                                      delay1ms(1);
  473.                                      lcd_pos(2,1);
  474.                                      delay1ms(1);
  475.                                      i=0;
  476.                                      while(t[ i]!='\0')
  477.                                                         {
  478.                                                         delay1ms(1);
  479.                                                         write_dat(t);
  480.                                                         delay1ms(2);
  481.                                                         i++;
  482.                                                         }
  483.                             }
  484. }

  485. void shuaxin(void)
  486.          {                 uint i;
  487.                  TimeDisplay(hour,min,sec);                                                                                         
  488.                                      lcd_pos(1,1);                         //时间
  489.                                      i=0;
  490.                                      while(b[ i]!='\0')
  491.                                                {
  492.                                                delay1ms(1);
  493.                                                write_dat(b);
  494.                                                delay1ms(1);
  495.                                                i++;
  496.                                                }

  497.                                      DateDisplay(year,month,date);        //显示日期                                                                                                                                                                    
  498.                                      delay1ms(1);
  499.                                      lcd_pos(0,0);
  500.                                      i=0;
  501.                                      while(a[ i]!='\0')
  502.                                                {
  503.                                                delay1ms(1);
  504.                                                write_dat(a);
  505.                                                delay1ms(1);
  506.                                                i++;
  507.                                                }
  508.          }



  509. void sotp(void)                                                                                                                 
  510. {
  511.          uinti;                     

  512. while(1)
  513.           {
  514.          duan1:                if(K1==0)
  515.                             {
  516.                             delay1ms(100);
  517.                             if(K1==0)
  518.                                      {
  519.                                      Readtime();
  520.                                      shuaxin();
  521.                                      i=0;
  522.                             gotoduan2;

  523.                                      }
  524.                             }
  525.                             else
  526.                             {gotoduan5;}

  527.          duan2:               if(K2==0)
  528.                             {
  529.                                      delay1ms(100);
  530.                                      if(K2==0)
  531.                                      {
  532.                                      i++;
  533.                                      if(i>6){i=0;}
  534.                                      shuaxin();
  535.                                      }        
  536.                             }
  537.                             switch(i)
  538.                              {
  539.                                      case 0:  if(K3==0){delay1ms(100);if(K3==0){year=year+1;}                 if(year>=100){year=0;}                                                             shuaxin();}break;
  540.                                       case 1:  if(K3==0){delay1ms(100);if(K3==0){month=month+1;}         if(month>=13){month=0;}                                                                shuaxin();}break;
  541.                                      case 2:  if(K3==0){delay1ms(100);if(K3==0){date=date+1;}                if(date>=32){date=0;}                                                              shuaxin();}break;
  542.                                      case 3:  if(K3==0){delay1ms(100);if(K3==0){hour=hour+1;}                if(hour>=25){hour=0;}                                                              shuaxin();}break;
  543.                                      case 4:  if(K3==0){delay1ms(100);if(K3==0){min=min+1;}                 if(min>=61){min=0;}                                                                        shuaxin();}break;
  544.                                      case 5:  if(K3==0){delay1ms(100);if(K3==0){sec=sec+1;}                   if(sec>=61){sec=0;}                                                                shuaxin();} break;
  545.                              }


  546.          duan4:               if(K4==0)
  547.                             {
  548.                             delay1ms(100);
  549.                             if(K4==0)
  550.                             {
  551.                             ModifyTime(year,month,date,hour,min,sec);
  552.                             gotoduan5;                                 ///////////////////*******************//////////
  553.                             }        
  554.                    }

  555.                           else
  556.                             {gotoduan2;}







  557. duan5:      Readtime();
  558.                     xianshi();
  559.                    }

  560.          }




  561. main()                                              /*主程序*/
  562. {


  563.          lcd_init();
  564.          delay1ms(5);
  565.          InitDS3231();
  566.          delay1ms(5);
  567.          delay1ms(5);
  568.          sotp();      
  569. }
复制代码


闹钟.docx

18.31 KB, 下载次数: 5, 下载积分: 黑币 -5

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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