zoukankan      html  css  js  c++  java
  • 温度传感器与蜂鸣器的使用

    实时显示温度与时间,并设置闹钟,播放音乐

                                                       proteus仿真图

      1 #include <AT89X51.H> 
      2 #include <intrins.h>
      3 #include <string.h>
      4 #define uint unsigned int
      5 #define uchar unsigned char
      6 
      7 sbit IO = P1^0;
      8 sbit SCLK = P1^1;
      9 sbit RST = P1^2;         //pdf中的CE即是RST
     10 sbit RS = P2^0;
     11 sbit RW = P2^1;
     12 sbit EN = P2^2;        
     13 sbit beep = P1^3;
     14 sbit k1 = P3^0;
     15 sbit k2 = P3^1;
     16 sbit k3 = P3^2;
     17 sbit k4 = P3^5;
     18 sbit LED = P2^7;
     19 sbit DQ = P3^3;
     20 
     21 uchar LCD_DQY_BUFFER1[30]={"DATE 00-00-00 00:00:00 00.0C"};    //  buffer缓冲器  年  13个字符              
     22 uchar LCD_DQY_BUFFER2[]={"CLOCK 00:00:00    "};    //时间
     23 uchar DateTime[7];
     24 
     25 uchar n=0, h=23,m=19,s=0,R=0;
     26 uchar table[]={"0123456789"};
     27 uchar ClockTime[7];
     28 
     29 uint dian;
     30 uchar A;
     31 uchar temp[6]={10,10,10,10,10,10};
     32 
     33 /*音乐部分*/
     34 uchar timeh,timel;//用于存放定时器的高8位和低8位
     35 uchar code jianpu[]={//定义<<送别>>简谱  每一个值第一位对应简谱的音调,第二位对应拍的长短
     36 0x54,0x32,0x52,0x88,0x64,0x84,0x58,0x54,0x12,0x22,0x34,0x22,0x12,0x28,0x00,0x00,
     37 0x54,0x32,0x52,0x86,0x72,0x64,0x84,0x58,0x54,0x22,0x32,0x46,0x92,0x18,0x00,0x00,
     38 0x64,0x84,0x88,0x74,0x62,0x72,0x88,0x62,0x72,0x82,0x62,0x62,0x52,0x32,0x12,0x28,0x00,0x00,
     39 0x54,0x32,0x52,0x86,0x72,0x64,0x84,0x58,0x54,0x22,0x32,0x46,0x92,0x18,0x00,0x00,
     40 0x54,0x32,0x52,0x88,0x64,0x84,0x58,0x54,0x12,0x22,0x34,0x22,0x12,0x28,0x00,0x00,
     41 0x54,0x32,0x52,0x86,0x72,0x64,0x84,0x58,0x54,0x22,0x32,0x46,0x92,0x18,0x00,0x00
     42 };
     43 //适合12M的晶振定时器初值表,高低8位分开
     44 uchar code chuzhi[]=
     45 {
     46      0xFF,0xFF,    //占位
     47      0xFC,0x43,    //中音1-7
     48      0xFC,0xad,    
     49      0xFD,0x0a,    
     50      0xFD,0x34,    
     51      0xFD,0x82,    
     52      0xFD,0xc8,    
     53      0xFE,0x06,
     54      0xFE,0x21,  //高音1
     55      0xFC,0x0C     //低音7
     56  };
     57 void timer0() interrupt 1     //定时器0(T0)中断服务程序      
     58 {
     59     TH0=timeh;                //将timeh赋给计时器的高8位
     60     TL0=timel;                 //将timel赋给计时器的低8位
     61     beep=~beep;             //定时器每次到时将蜂鸣器反相
     62 }
     63 
     64 void delay(uchar z)            //延时125MS,设为1个十六分音符,1/4拍
     65 {    uint y;
     66     for(z;z>0;z--)
     67          for(y=15615;y>0;y--);
     68 }
     69 
     70 void delay1(uchar z)        //延时0.5MS
     71 {    uchar y;
     72     for(z;z>0;z--)
     73          for(y=243;y>0;y--);
     74 }
     75 
     76 void music()
     77 {
     78     uchar temp;    //存放简谱数组中的每一个音符的临时变量
     79     uchar i=0;    
     80     uchar jp;    //jp用于取出temp中的高8位和低8位
     81     IT0=1;        //INT0
     82     TMOD=0x01;    //设置定时器T0工作于方式1
     83     IE=0x82;      //允许T0中断
     84 
     85 
     86     while(R==1)
     87     {
     88         temp=jianpu[i];
     89         if(temp==0xff)
     90             break;    
     91         jp=temp/16; //取数的高4位,音频数值
     92 
     93         if(jp!=0)
     94         {
     95             timeh=chuzhi[jp*2];        //构造定时器初值高8位
     96             timel=chuzhi[jp*2+1];     //构造定时器初值低8位
     97             TR0=1;      //开定时器
     98         }
     99         else
    100         {
    101             TR0=0;      //关定时器
    102             beep=1;      //关蜂鸣器
    103         }
    104         delay(temp%16); //取数的低4位,节拍(音符总时延)
    105         TR0=0;             //唱完一个音停5MS
    106         beep=1;
    107         delay1(10); 
    108         i++;
    109 
    110         if(k4==0)     //闹钟的控制键
    111         {
    112             R=0;
    113             m=m+5;
    114         }
    115     }
    116 }
    117 
    118 /*1602部分*/
    119 void DelayMS(uint ms)                     // 1
    120 {
    121      uchar i;
    122     while(ms--)
    123     {
    124          for(i=0;i<120;i++);
    125     }
    126 }
    127 
    128 void Write_A_Byte_TO_DQ1302(uchar x)     //  2 DQ1302写
    129 {
    130      uchar i;
    131     for(i=0;i<8;i++)
    132     {                     
    133          IO=x&0x01;SCLK=1;SCLK=0;x>>=1;     //假设x=5,那么x的二进制为0101,x>>1表示x右移1位,即把最右边一位的1删掉,变为010,此时x=2
    134     }     // 
    135 }
    136 
    137 uchar Get_A_Byte_FROM_DQ1302()              // 3  DQ1302取
    138 {
    139      uchar i,b=0x00;
    140     for(i=0;i<8;i++)
    141     {
    142          b |= _crol_((uchar)IO,i); //左移       // 
    143         SCLK=1;SCLK=0;
    144     }
    145     return b/16*10+b%16;    //取完8个位,转为十六进制
    146 }
    147 
    148 uchar Read_Data(uchar addr)                //    4  DQ1302读取
    149 {
    150      uchar dat;
    151     RST = 0;SCLK=0;RST=1;         
    152        Write_A_Byte_TO_DQ1302(addr);
    153     dat = Get_A_Byte_FROM_DQ1302();
    154        SCLK=1;RST=0;
    155     return dat;
    156 }
    157 
    158 void GetTime()                            //    5  获得DateTime[i]数组
    159 {
    160      uchar i,addr = 0x81;            //位址0x81为读秒,每次进2,直到0x8D读年
    161     for(i=0;i<7;i++)
    162     {
    163          DateTime[i]=Read_Data(addr);addr+=2; //将dat放进数组中
    164     }
    165 }
    166 
    167 uchar Read_LCD_State()                    //    6  1602
    168 {
    169      uchar state;
    170     RS=0;RW=1;EN=1;DelayMS(1);
    171     state=P0;
    172     EN = 0;DelayMS(1);
    173     return state;
    174 }
    175 
    176 void LCD_Busy_Wait()                        // 7
    177 {
    178      while((Read_LCD_State()&0x80)==0x80);       //当最高位为1时,延时5秒
    179     DelayMS(5);
    180 }
    181 
    182 void Write_LCD_Data(uchar dat)                 // 8
    183 {
    184      LCD_Busy_Wait();
    185     RS=1;RW=0;EN=0;P0=dat;EN=1;DelayMS(1);EN=0;          //dat为
    186 }
    187 
    188 void Write_LCD_Command(uchar cmd)    // 9  command命令 控制
    189 {
    190      LCD_Busy_Wait();
    191     RS=0;RW=0;EN=0;P0=cmd;EN=1;DelayMS(1);EN=0;         //cmd为地址
    192 }
    193 
    194 void Init_LCD()                                 //  10     初始化
    195 {
    196      Write_LCD_Command(0x38);           //显示16*2显示,5*7点阵,8位数据接口
    197     DelayMS(1);                           
    198     Write_LCD_Command(0x01);           //显示清零,数据指针清零
    199     DelayMS(1);    
    200     Write_LCD_Command(0x06);           //写一个字符后地址指针加一
    201     DelayMS(1);    
    202     Write_LCD_Command(0x0c);            //设置开显示,不显示光标
    203     DelayMS(1);    
    204 }
    205 
    206 void Set_LCD_POS(uchar p)                     // 11
    207 {
    208      Write_LCD_Command(p|0x80);      //
    209 }
    210 
    211 void Display_LCD_String(uchar p,uchar *s)        //12 在LCD显示    Display_LCD_String(0x00,LCD_DQY_BUFFER1);
    212 {
    213      uchar i;
    214     Set_LCD_POS(p);            //p为液晶屏地址0x00
    215     for(i=0;i<25;i++)
    216     {
    217         Write_LCD_Data(s[i+n]);
    218         DelayMS(1);     
    219     }
    220     n++; DelayMS(500);
    221     if(n>16)
    222     n=0;     
    223 }
    224 
    225 void Display_LCD_String2(uchar p,uchar *s)        //12 在LCD显示    Display_LCD_String(0x00,LCD_DQY_BUFFER1);
    226 {
    227      uchar i;
    228     Set_LCD_POS(p);            //p为液晶屏地址0x00
    229     for(i=0;i<16;i++)
    230     {
    231         Write_LCD_Data(s[i]);
    232         DelayMS(1);     
    233     }     
    234 }
    235 
    236 void Format_DateTime(uchar d,uchar *a)            // 13      Format_DateTime(DateTime[6],LCD_DQY_BUFFER1+5);
    237 {
    238      a[0]=d/10+'0';     //0’的ASCII值为48      加‘0’,是为了将前面的数字(1,2···)转换为ASCII码的值
    239     a[1]=d%10+'0';
    240 }
    241 
    242 void Format_DateTime2(uchar d,uchar *a)            // 13  
    243 {
    244      a[0]=d+'0';     
    245 }
    246 
    247 /*键盘扫描和设置闹钟时间*/
    248 void keyscan()
    249 {
    250     if(k1==0)
    251     {
    252         DelayMS(100);
    253         if(k1==0)  //
    254         {
    255             h++;
    256             if(h>=24)
    257             {   h=0;  }
    258             while(!k1);                    //等待按键释放
    259         }
    260     }
    261 
    262     if(k2==0)    //
    263     {
    264         m=m+1;
    265         if(m>=60)
    266            m=0;
    267         while(!k2);                    
    268     }
    269     if(k3==0)    //
    270     {
    271         s=s+1;
    272         if(s>=60)
    273            s=0;
    274         while(!k3);                    
    275     }
    276     if(k4==0)     //控制键
    277     {
    278         R=0;
    279     }
    280 }
    281 
    282 void GetClockTime()
    283 {
    284     ClockTime[0] = h/10;
    285     ClockTime[1] = h%10;
    286     ClockTime[2] = m/10;
    287     ClockTime[3] = m%10;
    288     ClockTime[4] = s/10;
    289     ClockTime[5] = s%10;    
    290 }
    291 
    292 /*DQ18B20部分 */
    293 void init_tempr()//DQ18B20初始化
    294 {
    295     uchar n;
    296     DQ=1;
    297     DelayMS(8);
    298     DQ=0;
    299     DelayMS(80);   //500us
    300     DQ=1;
    301     DelayMS(8);
    302     n=DQ;
    303     DelayMS(4);
    304 }
    305 void write_byte(uchar dat)
    306 {
    307     uchar i;
    308     for(i=0;i<8;i++)
    309     {
    310       DQ=0;
    311       DQ=dat&0x01;
    312       DelayMS(4);
    313       DQ=1;
    314       dat>>=1;
    315     }
    316     DelayMS(4);
    317 }
    318 uchar read_byte(void)
    319 {
    320     uchar i,value;
    321     for(i=0;i<8;i++)
    322     {
    323       DQ=0;
    324       value>>=1;
    325       DQ=1;
    326       if(DQ)
    327       value|=0x80;
    328       DelayMS(4);
    329     }
    330     return value;
    331 }
    332 uchar readtempr(void)
    333 {
    334       uint temp, a,b;
    335       init_tempr();
    336       write_byte(0xcc);
    337       write_byte(0x44);
    338       DelayMS(300);
    339       init_tempr();
    340       write_byte(0xcc);
    341       write_byte(0xbe);
    342            DelayMS(300);
    343       a=read_byte();
    344       b=read_byte();
    345 
    346       temp=b;
    347       temp<<=4;            
    348       temp+=(a&0xf0)>>4;
    349       dian=(a&0x0f)*10*6/10;       //  小数位转化
    350       return temp;
    351 }
    352 
    353 void dis_deal()
    354 {
    355     temp[0]=A/10;
    356     temp[1]= A%10;
    357     temp[2]=dian/10 ;
    358     temp[3]=dian%10 ; 
    359 }
    360 
    361 /*主函数*/
    362 void main()
    363 {
    364     SCON = 0X40;  // 串行口的工作模式选择
    365     TMOD = 0X20;  //  定时器0方式2
    366     PCON = 0X00;  // 波特率倍数
    367     TH1 = 0XFD;
    368     TL1 = 0XFD;
    369     TI = 0;
    370     TR1 = 1;
    371 
    372     TCON=0x05; 
    373     PX1=1;
    374     PT0=0;
    375     EX1=1;
    376      Init_LCD();
    377     while(1)
    378     {    
    379          GetTime();
    380         Format_DateTime(DateTime[6],LCD_DQY_BUFFER1+5);     //
    381         Format_DateTime(DateTime[4],LCD_DQY_BUFFER1+8);     //
    382         Format_DateTime(DateTime[3],LCD_DQY_BUFFER1+11); //
    383         Format_DateTime(DateTime[2],LCD_DQY_BUFFER1+14); //
    384         Format_DateTime(DateTime[1],LCD_DQY_BUFFER1+17); //
    385         Format_DateTime(DateTime[0],LCD_DQY_BUFFER1+20); //
    386         Display_LCD_String(0x00,LCD_DQY_BUFFER1);
    387 
    388         A=readtempr();
    389         dis_deal();
    390         Format_DateTime2(temp[0],LCD_DQY_BUFFER1+23);     //         
    391         Format_DateTime2(temp[1],LCD_DQY_BUFFER1+24);     //
    392         Format_DateTime2(temp[2],LCD_DQY_BUFFER1+26); //
    393 
    394         keyscan();
    395         GetClockTime();
    396         Format_DateTime2(ClockTime[0],LCD_DQY_BUFFER2+6);              
    397         Format_DateTime2(ClockTime[1],LCD_DQY_BUFFER2+7);
    398         Format_DateTime2(ClockTime[2],LCD_DQY_BUFFER2+9);              
    399         Format_DateTime2(ClockTime[3],LCD_DQY_BUFFER2+10);
    400         Format_DateTime2(ClockTime[4],LCD_DQY_BUFFER2+12);              
    401         Format_DateTime2(ClockTime[5],LCD_DQY_BUFFER2+13);     
    402         Display_LCD_String2(0x40,LCD_DQY_BUFFER2);
    403 
    404         if(    DateTime[2] == h && DateTime[1] == m)
    405         {
    406              R=1; music();        
    407         }
    408         else
    409         {
    410             R=0;
    411         } 
    412 
    413     }
    414 }
  • 相关阅读:
    网络安装Centos的方法
    命令源码文件——Golang
    mosquitto: error while loading shared libraries: libwebsockets.so.12: cannot open shared object file
    centos7安装mysql初始化报错
    MQTT --- 操作行为
    MQTTv5.0 ---AUTH – 认证交换
    MQTT v5.0------SUBSCRIBE 报文
    MQTT --- Retained Message
    inux centos7下源码 tar安装5.7.26详解
    20. 有效的括号
  • 原文地址:https://www.cnblogs.com/youcansayIdontKnow/p/13367034.html
Copyright © 2011-2022 走看看