(1)功能简述
设备按照用户通过按键设定的时间间隔自动采集并存储温度数据,并具有采集完成提醒、数码管显示等功能,系统硬件部分主要由按键电路、电源供电电路、 RTC 时钟、传感器电路和显示电路组成。 系统框图如图 1 所示:
(2)设计任务及要求
1. 数码管显示
1.1 设备上电后,自动进入参数设置界面(图 1) 此时,通过按键 S4 切换 4 个温度采集间隔时间,分别为 1 秒、 5 秒、 30 秒和 60 秒;
按下按键 S5,确认采集间隔时间,并退出参数设置界面(图 1),进入时钟显示界面(图 2)并开始采集温度。
要求: 时钟显示界面(图 2)下,提示符 1、 2 以 1 秒为间隔闪烁
1.2 当设备按照用户设定的采集间隔采集到 10 个数据后,指示灯 L1 闪烁提示本次温度采集已经完成,此时进入数码管温度采集显示界面(图 3):
此时,按下 S6, L1 熄灭,按照时间先后顺序,切换显示设备内存储的温度数据;按下 S7 按键进入参数设置界面(图 1),待用户输入温度采集间隔之后,可以进行下一次的温度采集工作。
说明: 索引指的是当前显示的温度按照采集时间先后顺序的编号(00-09)。
2. 温度检测功能
使用 DS18B20 温度传感器完成温度测量功能。
3. RTC
使用 DS1302 时钟芯片完成 RTC 的相关功能。
4. 设备工作模式说明
(1) 默认 RTC 时间: 23 时 59 分 50 秒;
(2) 默认温度数据采集间隔为 1 秒;
(3) 设备处在不同的显示界面下,与该界面无关的按键操作无效;
(4) 温度数据最大存储容量: 10 个
对于实时时钟DS1302:要记得一些细节的改变(根据官方库文件修改得来的):
另外又添加了实时时钟初始化函数和读取函数。
对于DS18B02(温度获取函数):
unsigned char get_wendu(){
unsigned char temp,high,low;
Init_DS18B20();
Write_DS18B20(0XCC);
Write_DS18B20(0X44);
Delay_OneWire(200);
Init_DS18B20();
Write_DS18B20(0XCC);
Write_DS18B20(0XBE);
low=Read_DS18B20();
high=Read_DS18B20();
temp=(low>>4)|(high<<4);
return temp;
}
ds1302.c
#include "ds1302.h"
unsigned char time[]={50,59,23,0,0,0,0};
/********************************************************************/
/*单字节写入一字节数据*/
void Write_Ds1302_Byte(unsigned char dat)
{
unsigned char i;
SCK = 0;
for (i=0;i<8;i++)
{
if (dat & 0x01) // 等价于if((addr & 0x01) ==1)
{
SDA_SET; //#define SDA_SET SDA=1 /*电平置高*/
}
else
{
SDA_CLR; //#define SDA_CLR SDA=0 /*电平置低*/
}
SCK_SET;
SCK_CLR;
dat = dat >> 1;
}
}
/********************************************************************/
/*单字节读出一字节数据*/
unsigned char Read_Ds1302_Byte(void)
{
unsigned char i, dat=0;
for (i=0;i<8;i++)
{
dat = dat >> 1;
if (SDA_R) //等价于if(SDA_R==1) #define SDA_R SDA /*电平读取*/
{
dat |= 0x80;
}
else
{
dat &= 0x7F;
}
SCK_SET;
SCK_CLR;
}
return dat;
}
/********************************************************************/
/*向DS1302 单字节写入一字节数据*/
void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat)
{
RST_CLR; /*RST脚置低,实现DS1302的初始化*/
SCK_CLR; /*SCK脚置低,实现DS1302的初始化*/
RST_SET; /*启动DS1302总线,RST=1电平置高 */
addr = addr & 0xFE;
Write_Ds1302_Byte(addr); /*写入目标地址:addr,保证是写操作,写之前将最低位置零*/
Write_Ds1302_Byte((dat/10<<4)|(dat%10)); /*写入数据:dat*/
RST_CLR; /*停止DS1302总线*/
}
/********************************************************************/
/*从DS1302单字节读出一字节数据*/
unsigned char Ds1302_Single_Byte_Read(unsigned char addr)
{
unsigned char temp,dat1,dat2;
RST_CLR; /*RST脚置低,实现DS1302的初始化*/
SCK_CLR; /*SCK脚置低,实现DS1302的初始化*/
RST_SET; /*启动DS1302总线,RST=1电平置高 */
addr = addr | 0x01;
Write_Ds1302_Byte(addr); /*写入目标地址:addr,保证是读操作,写之前将最低位置高*/
temp=Read_Ds1302_Byte(); /*从DS1302中读出一个字节的数据*/
dat1=temp/16;
dat2=temp%16;
temp=dat1*10+dat2;
SD=0;
return temp;
}
void ds1302_init(){
unsigned char add,i;
add=0x80;
Ds1302_Single_Byte_Write(0x8e,0x00);
for(i=0;i<7;i++)
{
Ds1302_Single_Byte_Write(add,time[i]);
add+=2;
}
Ds1302_Single_Byte_Write(0x8e,0x80);
}
void ds1302_read(){
unsigned char add,i;
add=0x81;
Ds1302_Single_Byte_Write(0x8e,0x00);
for(i=0;i<7;i++)
{
time[i]=Ds1302_Single_Byte_Read(add);
add+=2;
}
Ds1302_Single_Byte_Write(0x8e,0x80);
}
ds1302.h
#ifndef __DS1302_H__
#define __DS1302_H__
#include
#include
/********************************************************************/
sbit SCK=P1^7;
sbit SD=P2^3;
sbit RST=P1^3;
/********************************************************************/
/*复位脚*/
#define RST_CLR RST=0 /*电平置低*/
#define RST_SET RST=1 /*电平置高*/
/*双向数据*/
#define SDA_CLR SD=0 /*电平置低*/
#define SDA_SET SD=1 /*电平置高*/
#define SDA_R SD /*电平读取*/
/*时钟信号*/
#define SCK_CLR SCK=0 /*时钟信号*/
#define SCK_SET SCK=1 /*电平置高*/
/********************************************************************/
#define ds1302_sec_addr 0x80 //秒数据地址
#define ds1302_min_addr 0x82 //分数据地址
#define ds1302_hr_addr 0x84 //时数据地址
#define ds1302_date_addr 0x86 //日数据地址
#define ds1302_month_addr 0x88 //月数据地址
#define ds1302_day_addr 0x8A //星期数据地址
#define ds1302_year_addr 0x8C //年数据地址
#define ds1302_control_addr 0x8Ee //写保护命令字单元地址
#define ds1302_charger_addr 0x90 //涓电流充电命令字地址
#define ds1302_clkburst_addr 0xBE //日历、时钟突发模式命令字地址
/********************************************************************/
/********************************************************************/
/*单字节写入一字节数据*/
extern void Write_Ds1302_Byte(unsigned char dat);
/********************************************************************/
/*单字节读出一字节数据*/
extern unsigned char Read_Ds1302_Byte(void);
/********************************************************************/
/********************************************************************/
/*向DS1302单字节写入一字节数据*/
extern void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat);
/********************************************************************/
/*从DS1302单字节读出一字节数据*/
extern unsigned char Ds1302_Single_Byte_Read(unsigned char addr);
extern unsigned char time[];
extern void ds1302_init();
extern void ds1302_read();
#endif
/********************************************************************/
// END FILE
/********************************************************************/
onewire.c
#include "onewire.h"
//单总线延时函数
void Delay_OneWire(unsigned int t)
{
t=12*t;
while(t--);
}
//DS18B20芯片初始化
bit Init_DS18B20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(80);
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(5);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}
//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
unsigned char get_wendu(){
unsigned char temp,high,low;
Init_DS18B20();
Write_DS18B20(0XCC);
Write_DS18B20(0X44);
Delay_OneWire(200);
Init_DS18B20();
Write_DS18B20(0XCC);
Write_DS18B20(0XBE);
low=Read_DS18B20();
high=Read_DS18B20();
temp=(low>>4)|(high<<4);
return temp;
}
onewire.h
#ifndef _ONEWIRE_H
#define _ONEWIRE_H
#include "stc15f2k60s2.h"
#define OW_SKIP_ROM 0xcc
#define DS18B20_CONVERT 0x44
#define DS18B20_READ 0xbe
//IC引脚定义
sbit DQ = P1^4;
//函数声明
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
bit Init_DS18B20(void);
unsigned char Read_DS18B20(void);
unsigned char get_wendu();
#endif
text.c
#include
#include "ds1302.h"
#include "onewire.h"
#define uchar unsigned char
#define uint unsigned int
uchar code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
uchar flag1=0;
uchar flag2=0;
uchar led=0;
uchar count=0;
uchar wendu=0;
uchar tt=0;
uchar caiji_wendu[10];
uchar n=0;
uchar jiange=0;
uchar f1,f2,f3,f4,f5,f6,f7,f8;
void delayms(uchar ms);
void delay();
void display12(uchar f1,uchar f2);
void display34(uchar f3,uchar f4);
void display56(uchar f5,uchar f6);
void display78(uchar f7,uchar f8);
void keyscan();
void allinit();
void Time0_init();
void main(){
ds1302_init();
allinit();
Time0_init();
while(1)
{
wendu=get_wendu();
keyscan();
switch(count)
{
case 1:jiange=1;break;
case 2:jiange=5;break;
case 3:jiange=30;break;
case 4:jiange=60;count=0;break;
}
if(flag1==0)
{
f1=11;f2=11;f3=11;f4=11;f5=11;f6=10;f7=jiange/10;f8=jiange%10;
}
if(flag1==1)
{
ds1302_read();
if(time[0]%2==1)
{
f1=time[2]/10;f2=time[2]%10;f3=10;
f4=time[1]/10;f5=time[1]%10;f6=10;
f7=time[0]/10;f8=time[0]%10;
}
else
{
f1=time[2]/10;f2=time[2]%10;f3=11;
f4=time[1]/10;f5=time[1]%10;f6=11;
f7=time[0]/10;f8=time[0]%10;
}
}
display12(f1,f2);
display34(f3,f4);
display56(f5,f6);
display78(f7,f8);
}
}
void keyscan(){
if(P30==0) //s7
{
delayms(5);
if(P30==0)
{
flag1=0;
}
while(!P30);
}
if(!P31==0) //s6
{
delayms(5);
if(P31==0)
{
led=0;
}
while(!P31);
}
if(P32==0) //s5
{
delayms(5);
if(P32==0)
{
if(flag1==0)
{
flag1=1;
tt=0;
count=1;
}
}
}
if(P33==0) //s4
{
delayms(5);
if(P33==0)
{
count++;
}
while(!P33);
}
}
void allinit(){
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
P2=0XC0;P0=0XFF;P2=0XFF;P0=0XFF;
}
void delayms(uchar ms){
uchar i,j,k;
for(k=ms;k>0;k--)
{
i=12;
j=169;
do
{
while(j--);
}
while(i--);
}
}
void delay(){
uchar i,j;
for(i=10;i>0;i--)
for(j=200;j>0;j--);
}
void display12(uchar f1,uchar f2){
P2=0XC0;P0=0X01;P2=0XFF;P0=tab[f1];
delay();
P2=0XC0;P0=0X02;P2=0XFF;P0=tab[f2];
delay();
}
void display34(uchar f3,uchar f4){
P2=0XC0;P0=0X04;P2=0XFF;P0=tab[f3];
delay();
P2=0XC0;P0=0X08;P2=0XFF;P0=tab[f4];
delay();
}
void display56(uchar f5,uchar f6){
P2=0XC0;P0=0X10;P2=0XFF;P0=tab[f5];
delay();
P2=0XC0;P0=0X20;P2=0XFF;P0=tab[f6];
delay();
}
void display78(uchar f7,uchar f8){
P2=0XC0;P0=0X40;P2=0XFF;P0=tab[f7];
delay();
P2=0XC0;P0=0X80;P2=0XFF;P0=tab[f8];
delay();
}
void Time0_init(){
TMOD=0X01;
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TR0=1;
EA=1;
ET0=1;
}
void Time0_service() interrupt 1
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
tt++;
if((tt==jiange*200)&&(flag1==1))
{
tt=0;
caiji_wendu[n]=wendu;
n++;
if(n==10)
{
n=0;
led=1;
flag1=2;
f1=10;f2=0;f3=0;
f4=11;f5=11;f6=10;
f7=caiji_wendu[0]/10;f8=caiji_wendu[0]%10;
}
}
if((flag1==2)&&(tt==200))
{
tt=0;
if(led==1)
{
if(flag2==0)
{
flag2=1;
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
P00=0;
}
else if(flag2==1)
{
flag2=0;
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
P00=1;
}
}
else if(led==0)
{
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
P00=1;
f1=10;f2=n/10;f3=n%10;
f4=11;f5=11;f6=10;
f7=caiji_wendu[n]/10;f8=caiji_wendu[n]%10;
n++;
if(n==10)
{
flag1=3;
n=0;
}
}
}
}