标题:
蓝桥杯2012年初赛题目+答案,串口设置温度报警+DS1302显示时间
[打印本页]
作者:
大力做大力愛
时间:
2018-1-13 16:13
标题:
蓝桥杯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.png
(36.23 KB, 下载次数: 46)
下载附件
2018-1-13 16:09 上传
3.jpg
(138.65 KB, 下载次数: 37)
下载附件
2018-1-13 16:09 上传
代码如下:
#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)
2018-1-13 16:13 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1