选用材料为蓝桥杯官方提供的开发板。
因为此板选用了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
效果图:
代码如下:
- #include<reg52.h>
- #include<intrins.h> //_nop_()延时函数头文件
- #define uchar unsigned char
- #define uint unsigned int
- sfr AUXR=0x8e; //定义stc15芯片的特殊寄存器AUXR地址 因为采用的是52的头文件 如果采用15的头文件择不用设置
- // 如果改为51系列芯片的话只需删掉这行然后把定时器和中断的初始化函数改掉 此寄存器的作用在此为设置定时器速度为1T还是12T模式
- sbit DQ=P1^4; //温度引脚
- sbit CE=P1^3; //1302芯片引脚
- sbit SCL=P1^7;
- sbit io=P2^3;
- uchar code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF}; //共阳数码管数值
- // 0, 1 , 2 , 3 , 4 ........ — ,关显示
- uchar dspbuf[]={11,11,11,11,11,11,11,11}; //显示缓冲区
- uchar DSP;
- uchar zi[]={"wendu:"}; //串口发送数据
- uchar jieshou[6];
- uchar zd4_add;
- uchar max,min;
- uchar cmd_ds[3]; //接收1302时间
- uchar int_ds[]={30,13,0,0,0,0}; //初始化1302
- uchar temp;
- uint sec_add;
- bit sec_flag;
- bit sz_flag;
- void int_t0(); //定时器t0初始化
- void int_chuankou(); //串口初始化
- void display();
- //*********************1302*****************************************//
- void DS1302_wuchar(uchar cmd); //写一个字节到1302
- uchar DS1302_ruchar(); //读取一个字节
- void write_DS1302(uchar cmd,uchar dat); //写dat数据到cmd寄存器地址
- uchar red_DS1302(uchar cmd); //读取cmd地址中的数据
- void red_ds(); //读取全部时间
- void int_DS1302(); //初始化1302
- //***********************温度函数**********************************//
- void w_18(uchar cmd); //写cmd到1820
- uchar r_18(); //读取一个字节
- uchar red_18(); //读取温度
- void int_18(); //初始化温度
- void Delay500us(); //延时
- void Delay100us();
- void open_led1(); //开LED1
- void cls_led1(); //关LED1
- void open_led2();
- void cls_led2();
- void ckfz(); //串口发送
- void main()
- {
- max=30; //初始最大值与最小值
- min=28;
- int_t0(); //初始化定时器t0
- int_DS1302(); //初始化1302
- int_chuankou(); //串口初始化
- while(1)
- {
- temp=red_18(); //读取温度
- red_ds(); //读取时间
- dspbuf[6]=temp/10; //显示
- dspbuf[7]=temp%10; //显示格式为 xx—xx xx
- dspbuf[0]=cmd_ds[1]/10;
- dspbuf[1]=cmd_ds[1]%10;
- dspbuf[2]=10; //显示横杠
- dspbuf[3]=cmd_ds[0]/10;
- dspbuf[4]=cmd_ds[0]%10;
- ckfz(); //串口发送温度到PC
- if(sz_flag) //如果串口接收到修改最大值最小值指令 sz_flag会由0变1 最大值与最小值更新
- {
- max=jieshou[0]*10+jieshou[1];
- min=jieshou[3]*10+jieshou[4];
- sz_flag=0; //标志位清零
- }
- // dspbuf[6]=jieshou[0];
- // dspbuf[7]=jieshou[1];
- // dspbuf[2]=jieshou[2];
- // dspbuf[3]=jieshou[3];
- // dspbuf[4]=jieshou[4];
- }
- }
- void t0() interrupt 1
- {
- sec_add++;
- if(sec_add==1000) //1s
- {
- sec_add=0;
- sec_flag=~sec_flag; //1秒标志位
- }
- if(temp>max) //如果温度大于最大值 LED1隔1秒闪烁
- {
- if(sec_flag)
- {open_led1();}
- else
- {cls_led1();}
- }
- if(temp<min) //如果温度小于最小值 LED2隔1秒闪烁
- {
- if(sec_flag)
- {open_led2();}
- else
- {cls_led2();}
- }
- display(); //中断刷新显示函数
- }
- void ck() interrupt 4 //串口接收中断
- {
- if(RI) //如果RI接收标志位为1
- {
- EA=0;
- RI=0;
- jieshou[zd4_add]=SBUF-48; //接收 xx-xx格式数据 5个字节 串口应为文本发送 因为字符0 代表十进制48 所以应减去48 才是10进制的0
- zd4_add++;
- if(zd4_add==5) //接收5次
- zd4_add=0;
- EA=1;
- }
- sz_flag=1; //单片机接收到数据时 sz_flag=1
- }
- void int_t0()
- {
- AUXR |= 0x80; //定时器时钟1T模式
- TMOD &= 0xF0; //设置定时器模式
- TL0 = 0x9A; //设置定时初值 //1ms延时
- TH0 = 0xA9; //设置定时初值
- TF0 = 0; //清除TF0标志
- TR0 = 1; //定时器0开始计时
- EA=1;
- ET0=1;
- }
- void int_chuankou() //2400波特率
- {
- SCON = 0x50; //8位数据,可变波特率
- AUXR |= 0x40; //定时器1时钟为Fosc,即1T
- AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
- TMOD &= 0x0F; //设定定时器1为16位自动重装方式
- TL1 = 0x80; //设定定时初值
- TH1 = 0xFB; //设定定时初值
- ET1 = 0; //关闭定时器1中断
- ES=1; //开启串口中断
- TR1 = 1; //启动定时器1
- }
- void display() //显示函数
- {
- P2=(P2&0x1f)|0xe0; //关显示
- P0=0xff;
- P2&=0X1F;
- P2=(P2&0x1f)|0xc0; //位选
- P0=1<<DSP;
- P2&=0X1F;
- P2=(P2&0x1f)|0xe0; //查表显示
- P0=tab[dspbuf[DSP]];
- P2&=0X1F;
- DSP++;
- if(DSP==8)
- DSP=0;
- }
- //******************温度函数************************//
- void int_18() //初始化温度传感器
- {
- DQ = 0;
- Delay500us();// 延时大于480us
- DQ = 1;
- Delay500us();
- }
- void w_18(uchar cmd)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- DQ=0;
- DQ=cmd&0x01; //从低位写起
- Delay100us();
- DQ=1;
- cmd>>=1;
- }
- }
- uchar r_18()
- {
- uchar num,i;
- for(i=0;i<8;i++)
- {
- DQ=0; //温度从低位读起
- num>>=1;
- DQ=1;
- if(DQ)
- {
- num=num|0x80;
- }
- Delay100us();
- }
- return num;
- }
- uchar red_18()
- {
- uchar low,high,num;
- int_18();
- w_18(0xcc);
- w_18(0x44);
- // Delayus(200);
-
- int_18();
- w_18(0xcc);
- w_18(0xbe);
- low=r_18(); //先读低八位
- high=r_18();
- num=high<<4;
- num=num|(low>>4);
- return num;
- }
- void Delay500us() //@11.0592MHz
- {
- unsigned char i, j;
- _nop_();
- _nop_();
- i = 6;
- j = 93;
- do
- {
- while (--j);
- } while (--i);
- }
- void Delay100us() //@11.0592MHz
- {
- unsigned char i, j;
- _nop_();
- _nop_();
- i = 2;
- j = 15;
- do
- {
- while (--j);
- } while (--i);
- }
- //**************DS1302****************//
- void int_DS1302() //初始化DS1302,把int_ds[]数组里的数写入相应时间寄存器地址
- {
- write_DS1302(0x8e,0x00); //写保护关
- write_DS1302(0x80,int_ds[0]);
- write_DS1302(0x82,int_ds[1]);
- write_DS1302(0x8e,0x80); //写保护开
- }
- void DS1302_wuchar(uchar cmd)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- SCL=0;
- io=cmd&0x01;
- SCL=1;
- cmd>>=1;
- }
- }
- uchar DS1302_ruchar()
- {
- uchar dat,i;
- for(i=0;i<8;i++)
- {
- SCL=0;
- dat>>=1;
- if(io)
- dat|=0x80;
- SCL=1;
- }
- return dat;
- }
- void write_DS1302(uchar cmd,uchar dat)
- {
- uchar x;
- CE=0;
- SCL=0;
- CE=1;
- DS1302_wuchar(cmd);
- x=(dat/10<<4)|(dat%10);//十进制转换十六进制
- DS1302_wuchar(x);
- CE=0;
- }
- uchar red_DS1302(uchar cmd)
- {
- uchar dat;
- uchar dat1,dat2;
- CE=0;
- SCL=0;
- CE=1;
- DS1302_wuchar(cmd);
- dat=DS1302_ruchar();
- dat1=dat/16; //十六进制转十进制
- dat2=dat%16;
- dat=dat1*10+dat2;
- io=0;
- CE=0;
- return dat;
- }
- void red_ds()
- {
- write_DS1302(0x8e,0x00);
- cmd_ds[0]=red_DS1302(0x81);
- cmd_ds[1]=red_DS1302(0x83);
- write_DS1302(0x8e,0x80);
- }
- void ckfz()
- {
- uchar i;
- if(sec_flag)
- {
- for(i=0;i<6;i++) //发送温度数据到PC
- {
- SBUF=zi[i];
- while(TI==0);
- TI=0;
- }
- SBUF=temp/10+0x30;//(temp/10)<<4|(temp%10);
- while(TI==0);
- TI=0;
- SBUF=temp%10+0x30;//(temp/10)<<4|(temp%10);
- while(TI==0);
- TI=0;
- SBUF='\n';
- while(TI==0);
- TI=0;
- sec_flag=0;
- }
- }
- void open_led1()
- {
- P2=(P2&0x1f)|0x80;
- P0=0x7f;
- P2&=0x1f;
- }
- void cls_led1()
- {
- P2=(P2&0x1f)|0x80;
- P0=0xff;
- P2&=0x1f;
- }
- void open_led2()
- {
- P2=(P2&0x1f)|0x80;
- P0=0xbf;
- P2&=0x1f;
- }
- void cls_led2()
- {
- P2=(P2&0x1f)|0x80;
- P0=0xff;
- P2&=0x1f;
- }
复制代码
附上代码和原理图
2012.rar
(312.39 KB, 下载次数: 25)
|