找回密码
 立即注册

QQ登录

只需一步,快速开始

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

蓝桥杯2012年初赛题目+答案,串口设置温度报警+DS1302显示时间

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

选用材料为蓝桥杯官方提供的开发板。

因为此板选用了4块74LS573芯片用于锁存P0口信号,这种设计可节约很多的i/0口,与市面上很多的开发板不一样,所以如果要换到其他开发板上使用,需要改一下显示代码 和LED亮灭代码,但是大致思路不变,只要改变一下那几个比较特殊的使用到了573锁存来编程的函数即可。

我也是一名菜鸡  如果有那个大神有更好的编程思路的话 那就拜托大神赐教了。

设计要求如下:
1、        读取DS18B20温度,在数码管的最后两位显示。
2、读取DS1302时间,初始化为13:30。在数码管的高五位显示,格式为:13-30
3、其余没用到的数码管灭。
4、通过串口设置DS18B20温度上限和下限,设置格式为:30-28,其中30是高温上限,28是低温下限
5、采集DS18B20温度,通过串口上传实时数据给上位机。
6、当温度超过上限,LED1隔1秒亮一次。超过下限,LED2隔1秒亮一次。
7、串口波特率一律用2400bps

效果图:




代码如下:

  1. #include<reg52.h>
  2. #include<intrins.h>                             //_nop_()延时函数头文件
  3. #define uchar unsigned char
  4. #define uint  unsigned int

  5. sfr AUXR=0x8e;                                         //定义stc15芯片的特殊寄存器AUXR地址 因为采用的是52的头文件 如果采用15的头文件择不用设置
  6.                                                                  // 如果改为51系列芯片的话只需删掉这行然后把定时器和中断的初始化函数改掉  此寄存器的作用在此为设置定时器速度为1T还是12T模式
  7. sbit DQ=P1^4;                                         //温度引脚

  8. sbit CE=P1^3;                                         //1302芯片引脚
  9. sbit SCL=P1^7;
  10. sbit io=P2^3;

  11. uchar code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};  //共阳数码管数值
  12.                                  //  0,  1 ,  2  , 3 ,   4  ........                                         — ,关显示  
  13. uchar dspbuf[]={11,11,11,11,11,11,11,11};        //显示缓冲区
  14. uchar DSP;

  15. uchar zi[]={"wendu:"};                                                //串口发送数据

  16. uchar jieshou[6];
  17. uchar zd4_add;

  18. uchar max,min;

  19. uchar cmd_ds[3];                                                        //接收1302时间
  20. uchar int_ds[]={30,13,0,0,0,0};                                //初始化1302

  21. uchar temp;

  22. uint sec_add;
  23. bit sec_flag;

  24. bit sz_flag;

  25. void int_t0();                                                           //定时器t0初始化
  26. void int_chuankou();                                           //串口初始化
  27. void display();

  28. //*********************1302*****************************************//

  29. void DS1302_wuchar(uchar cmd);                                  //写一个字节到1302
  30. uchar DS1302_ruchar();                                                   //读取一个字节
  31. void write_DS1302(uchar cmd,uchar dat);                  //写dat数据到cmd寄存器地址
  32. uchar red_DS1302(uchar cmd);                                  //读取cmd地址中的数据
  33. void red_ds();                                                                  //读取全部时间
  34. void int_DS1302();                                                          //初始化1302


  35. //***********************温度函数**********************************//

  36. void w_18(uchar cmd);                                   //写cmd到1820
  37. uchar r_18();                                                   //读取一个字节
  38. uchar red_18();                                                   //读取温度
  39. void int_18();                                                   //初始化温度
  40. void Delay500us();                                           //延时
  41. void Delay100us();

  42. void open_led1();                                           //开LED1
  43. void cls_led1();                                           //关LED1
  44. void open_led2();
  45. void cls_led2();

  46. void ckfz();                                                   //串口发送

  47. void main()
  48. {
  49.         max=30;                                                           //初始最大值与最小值
  50.         min=28;
  51.         int_t0();                                                   //初始化定时器t0
  52.         int_DS1302();                                           //初始化1302
  53.         int_chuankou();                                           //串口初始化
  54.         while(1)
  55.         {
  56.                 temp=red_18();                                   //读取温度
  57.                 red_ds();                                           //读取时间
  58.                 dspbuf[6]=temp/10;                           //显示
  59.                 dspbuf[7]=temp%10;                           //显示格式为       xx—xx xx
  60.                 dspbuf[0]=cmd_ds[1]/10;
  61.                 dspbuf[1]=cmd_ds[1]%10;        
  62.                 dspbuf[2]=10;                                   //显示横杠
  63.                 dspbuf[3]=cmd_ds[0]/10;
  64.                 dspbuf[4]=cmd_ds[0]%10;                                

  65.                 ckfz();                                                   //串口发送温度到PC

  66.                 if(sz_flag)                                           //如果串口接收到修改最大值最小值指令  sz_flag会由0变1 最大值与最小值更新
  67.                 {
  68.                         max=jieshou[0]*10+jieshou[1];
  69.                         min=jieshou[3]*10+jieshou[4];
  70.                         sz_flag=0;                                   //标志位清零
  71.                 }

  72. //                dspbuf[6]=jieshou[0];
  73. //                dspbuf[7]=jieshou[1];
  74. //                dspbuf[2]=jieshou[2];
  75. //                dspbuf[3]=jieshou[3];
  76. //                dspbuf[4]=jieshou[4];
  77.         }
  78. }

  79. void t0() interrupt 1
  80. {
  81.         sec_add++;
  82.         if(sec_add==1000)                                   //1s
  83.         {
  84.                 sec_add=0;
  85.                 sec_flag=~sec_flag;                           //1秒标志位
  86.         }

  87.         if(temp>max)                                           //如果温度大于最大值  LED1隔1秒闪烁
  88.         {
  89.                 if(sec_flag)
  90.                 {open_led1();}
  91.                 else
  92.                 {cls_led1();}
  93.         }

  94.         if(temp<min)                                           //如果温度小于最小值  LED2隔1秒闪烁
  95.         {
  96.                 if(sec_flag)
  97.                 {open_led2();}
  98.                 else
  99.                 {cls_led2();}
  100.         }

  101.         display();                                                   //中断刷新显示函数
  102. }

  103. void ck() interrupt 4                                   //串口接收中断
  104. {
  105.         if(RI)                                                           //如果RI接收标志位为1
  106.         {
  107.                 EA=0;
  108.                 RI=0;
  109.                 jieshou[zd4_add]=SBUF-48;           //接收  xx-xx格式数据  5个字节  串口应为文本发送  因为字符0 代表十进制48 所以应减去48 才是10进制的0
  110.                 zd4_add++;
  111.                 if(zd4_add==5)                                   //接收5次
  112.                 zd4_add=0;        
  113.                 EA=1;
  114.         }  
  115.         sz_flag=1;                                           //单片机接收到数据时  sz_flag=1
  116. }

  117. void int_t0()                                                                                                
  118. {
  119.         AUXR |= 0x80;                //定时器时钟1T模式
  120.         TMOD &= 0xF0;                //设置定时器模式                                 
  121.         TL0 = 0x9A;                //设置定时初值                          //1ms延时
  122.         TH0 = 0xA9;                //设置定时初值
  123.         TF0 = 0;                //清除TF0标志
  124.         TR0 = 1;                //定时器0开始计时
  125.         EA=1;
  126.         ET0=1;
  127. }

  128. void int_chuankou()                                                                                                                          //2400波特率
  129. {
  130.         SCON = 0x50;                //8位数据,可变波特率
  131.         AUXR |= 0x40;                //定时器1时钟为Fosc,即1T
  132.         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  133.         TMOD &= 0x0F;                //设定定时器1为16位自动重装方式
  134.         TL1 = 0x80;                //设定定时初值
  135.         TH1 = 0xFB;                //设定定时初值
  136.         ET1 = 0;                //关闭定时器1中断
  137.         ES=1;                        //开启串口中断
  138.         TR1 = 1;                //启动定时器1
  139. }

  140. void display()                                   //显示函数
  141. {
  142.         P2=(P2&0x1f)|0xe0;                   //关显示
  143.         P0=0xff;
  144.         P2&=0X1F;

  145.         P2=(P2&0x1f)|0xc0;                   //位选
  146.         P0=1<<DSP;
  147.         P2&=0X1F;

  148.         P2=(P2&0x1f)|0xe0;                   //查表显示
  149.         P0=tab[dspbuf[DSP]];
  150.         P2&=0X1F;

  151.         DSP++;
  152.         if(DSP==8)
  153.         DSP=0;
  154. }


  155. //******************温度函数************************//

  156. void int_18()                                  //初始化温度传感器
  157. {
  158.         DQ = 0;
  159.           Delay500us();// 延时大于480us
  160.           DQ = 1;
  161.     Delay500us();
  162. }

  163. void w_18(uchar cmd)
  164. {
  165.          uchar i;
  166.         for(i=0;i<8;i++)
  167.         {
  168.                 DQ=0;
  169.                 DQ=cmd&0x01;                                          //从低位写起
  170.                 Delay100us();
  171.                 DQ=1;
  172.                 cmd>>=1;
  173.         }
  174. }

  175. uchar r_18()
  176. {
  177.         uchar num,i;
  178.          for(i=0;i<8;i++)
  179.          {
  180.                  DQ=0;                                                          //温度从低位读起
  181.                  num>>=1;
  182.                  DQ=1;
  183.                  if(DQ)
  184.                  {
  185.                           num=num|0x80;
  186.                  }
  187.                  Delay100us();
  188.          }
  189.          return num;
  190. }

  191. uchar red_18()
  192. {
  193.         uchar low,high,num;
  194.         int_18();
  195.         w_18(0xcc);
  196.         w_18(0x44);
  197. //        Delayus(200);
  198.                
  199.            int_18();
  200.         w_18(0xcc);
  201.         w_18(0xbe);
  202.         low=r_18();                                           //先读低八位
  203.         high=r_18();

  204.         num=high<<4;
  205.         num=num|(low>>4);
  206.         return num;
  207. }

  208. void Delay500us()                //@11.0592MHz
  209. {
  210.         unsigned char i, j;

  211.         _nop_();
  212.         _nop_();
  213.         i = 6;
  214.         j = 93;
  215.         do
  216.         {
  217.                 while (--j);
  218.         } while (--i);
  219. }

  220. void Delay100us()                //@11.0592MHz
  221. {
  222.         unsigned char i, j;

  223.         _nop_();
  224.         _nop_();
  225.         i = 2;
  226.         j = 15;
  227.         do
  228.         {
  229.                 while (--j);
  230.         } while (--i);
  231. }




  232. //**************DS1302****************//


  233. void int_DS1302()          //初始化DS1302,把int_ds[]数组里的数写入相应时间寄存器地址
  234. {
  235.         write_DS1302(0x8e,0x00);                  //写保护关
  236.         write_DS1302(0x80,int_ds[0]);
  237.         write_DS1302(0x82,int_ds[1]);
  238.         write_DS1302(0x8e,0x80);                     //写保护开
  239. }

  240. void DS1302_wuchar(uchar cmd)
  241. {
  242.         uchar i;
  243.         for(i=0;i<8;i++)
  244.         {
  245.                 SCL=0;
  246.                 io=cmd&0x01;
  247.                 SCL=1;
  248.                 cmd>>=1;
  249.         }
  250. }

  251. uchar DS1302_ruchar()
  252. {
  253.         uchar dat,i;
  254.         for(i=0;i<8;i++)
  255.         {
  256.                 SCL=0;
  257.                 dat>>=1;
  258.                 if(io)
  259.                 dat|=0x80;        
  260.                 SCL=1;
  261.         }
  262.         return dat;        
  263. }

  264. void write_DS1302(uchar cmd,uchar dat)
  265. {
  266.         uchar x;
  267.         CE=0;
  268.         SCL=0;
  269.         CE=1;
  270.         DS1302_wuchar(cmd);        
  271.         x=(dat/10<<4)|(dat%10);//十进制转换十六进制
  272.         DS1302_wuchar(x);
  273.         CE=0;        
  274. }

  275. uchar red_DS1302(uchar cmd)
  276. {
  277.         uchar dat;
  278.         uchar dat1,dat2;
  279.         CE=0;
  280.         SCL=0;
  281.         CE=1;
  282.         DS1302_wuchar(cmd);
  283.         dat=DS1302_ruchar();
  284.         dat1=dat/16;                         //十六进制转十进制
  285.         dat2=dat%16;
  286.         dat=dat1*10+dat2;
  287.         io=0;
  288.         CE=0;
  289.         return dat;
  290. }

  291. void red_ds()
  292. {
  293.         write_DS1302(0x8e,0x00);
  294.         cmd_ds[0]=red_DS1302(0x81);        
  295.         cmd_ds[1]=red_DS1302(0x83);        
  296.         write_DS1302(0x8e,0x80);        
  297. }

  298. void ckfz()
  299. {
  300.         uchar i;
  301.         if(sec_flag)
  302.         {
  303.                 for(i=0;i<6;i++)                                                   //发送温度数据到PC
  304.                 {
  305.                         SBUF=zi[i];
  306.                         while(TI==0);
  307.                         TI=0;        
  308.                 }
  309.                 SBUF=temp/10+0x30;//(temp/10)<<4|(temp%10);
  310.                 while(TI==0);
  311.                 TI=0;

  312.                 SBUF=temp%10+0x30;//(temp/10)<<4|(temp%10);
  313.                 while(TI==0);
  314.                 TI=0;

  315.                 SBUF='\n';
  316.                 while(TI==0);
  317.                 TI=0;
  318.                 sec_flag=0;
  319.         }
  320. }

  321. void open_led1()
  322. {
  323.         P2=(P2&0x1f)|0x80;
  324.         P0=0x7f;
  325.         P2&=0x1f;
  326. }

  327. void cls_led1()
  328. {
  329.         P2=(P2&0x1f)|0x80;
  330.         P0=0xff;
  331.         P2&=0x1f;
  332. }

  333. void open_led2()
  334. {
  335.         P2=(P2&0x1f)|0x80;
  336.         P0=0xbf;
  337.         P2&=0x1f;
  338. }

  339. void cls_led2()
  340. {
  341.         P2=(P2&0x1f)|0x80;
  342.         P0=0xff;
  343.         P2&=0x1f;
  344. }
复制代码



附上代码和原理图
2012.rar (312.39 KB, 下载次数: 25)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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