#include
#include "ds18b20.h"
#include
#define uchar unsigned char //定义无符号字符类型uchar
#define uint unsigned int //定义无符号整型类型uint
uchar code tab[]={
0xc0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0Xbf,0XFF};//数字0~9,“-”“关”
uchar yi,er,san,si,wu,liu,qi,ba; //定义字符型变量yi,er,san,si,wu,liu,qi,ba,当作数码管显示控制变量
extern unsigned char shijian[]; //调用DS1302定义的时间数组
uchar wendu,shezhi=0,jiange=1,s4=0;
uint tt=0;
uchar Save[10],Save_n=0;
bit fla=0,LED_shan=0;
void delayms(int ms); //延时函数
void allinit(); //初始化函数
void keyscan(); //独立按键函数
void display1(uchar yi,uchar er); //第一、二段数码管函数
void display2(uchar san,uchar si); //第三、四段数码管函数
void display3(uchar wu,uchar liu); //第五、六段数码管函数
void display4(uchar qi,uchar ba); //第七、八段数码管函数
void Timer0Init(void); //5毫秒@11.0592MHz
void main()//主函数
{
allinit(); //初始化函数
DS_init(); //初始化DS1302
Timer0Init(); //初始化定时器0
while(1)
{
wendu=Tempget(); //获取温度
if(shezhi==0) //参数设置页面
{
yi=11;er=11;san=11;si=11;wu=11;liu=10;qi=jiange/10;ba=jiange%10; //显示间隔
}
else if(shezhi==1) //时钟显示页面
{
DS_get();
yi=shijian[2]/10;er=shijian[2]%10;
si=shijian[1]/10;wu=shijian[1]%10;
qi=shijian[0]/10;ba=shijian[0]%10;
if(shijian[0]%10%2==0){
san=10;liu=10;} //判断秒是奇数还是偶数,用来让数码管三、六位间隔闪烁
else{
san=11;liu=11;}
}
keyscan(); //独立按键函数
display1(yi,er); //第一、二段数码管函数
display2(san,si); //第三、四段数码管函数
display3(wu,liu); //第五、六段数码管函数
display4(qi,ba); //第七、八段数码管函数
}
}
void keyscan()//独立按键函数
{
if(P30==0) //判断P30是否等于0
{
delayms(5); //延时5ms
if(P30==0) //再次判断P30是否等于0
{
if(shezhi==3)shezhi=0; //判断此时是否在第三个页面,也就是说采集到的10个数据均已在数码管上显示完毕,按键后返回到参数设置页面
}
while(!P30); //如果按键不松开,则一直循环
}
else if(P31==0) //判断P31是否等于0
{
delayms(5); //延时5ms
if(P31==0) //再次判断P31是否等于0
{
if(shezhi==2){
LED_shan=0;P2=0X80;P0=0XFF;} //判断此时是否在第二个页面,也就是10个参数采集过后,L1灯亮起,按键后L1熄灭,数码管循环显示采集到的10个数据
}
while(!P31); //如果按键不松开,则一直循环
}
else if(P32==0) //判断P32是否等于0
{
delayms(5); //延时5ms
if(P32==0) //再次判断P32是否等于0
{
if(shezhi==0){
shezhi=1;tt=0;} //判断在设置页面下按键是否按下,按下后进入到时钟显示页面,并开始采集数据
}
while(!P32); //如果按键不松开,则一直循环
}
else if(P33==0) //判断P33是否等于0
{
delayms(5); //延时5ms
if(P33==0) //再次判断P33是否等于0
{
if(shezhi==0)
{
if(jiange==1)jiange=5; //判断间隔是否在1s上,如果是按键按下后间隔改为5s
else if(jiange==5)jiange=30; //判断间隔是否在5s上,如果是按键按下后间隔改为30s
else if(jiange==30)jiange=60; //判断间隔是否在30s上,如果是按键按下后间隔改为60s
else if(jiange==60)jiange=1; //判断间隔是否在60s上,如果是按键按下后间隔改为1s
}
}
while(!P33); //如果按键不松开,则一直循环
}
}
void Timer0Init(void) //5毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0x28; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA=1;ET0=1;
}
void time0 () interrupt 1
{
tt++;
if((tt==jiange*200)&&(shezhi==1))
{
tt=0;
Save[Save_n]=wendu;
Save_n++;
if(Save_n==10)
{
shezhi=2;LED_shan=1;Save_n=0;
yi=10;er=0;san=0;si=11;wu=11;liu=11;qi=Save[0]/10;ba=Save[0]%10;
}
}
if((tt==200)&&(shezhi==2))
{
tt=0;
if(LED_shan==1)
{
if(fla==0){
fla=1;P2=0X80;P0=0XFE;}
else if(fla==1){
fla=0;P2=0X80;P0=0XFF;}
}
else if(LED_shan==0)
{
yi=10;er=Save_n/10;san=Save_n%10;si=11;wu=11;liu=11;qi=Save[Save_n]/10;ba=Save[Save_n]%10;
Save_n++;
if(Save_n==10)
{
Save_n=0;shezhi=3;
}
}
}
}
void delayms(int ms)//延时函数
{
uint i,j;
for(i=ms;i>0;i--)
for(j=845;j>0;j--);
}
void allinit()//初始化函数
{
P2=0XA0;P0=0X00; //关闭蜂鸣器继电器
P2=0X80;P0=0XFF; //关闭所有LED灯
P2=0XC0;P0=0XFF; //选中所有数码管段选
P2=0XFF;P0=0XFF; //关闭所有数码管
}
void display1(uchar yi,uchar er)//第一、二段数码管函数
{
P2=0XC0;P0=0X01; //选中第一个数码管位选
P2=0XFF;P0=tab[yi]; //让第一个数码管显示yi指向的值
delayms(1); //延时1ms
P2=0XC0;P0=0X02; //选中第二个数码管位选
P2=0XFF;P0=tab[er]; //让第一个数码管显示er指向的值
delayms(1); //延时1ms
}
void display2(uchar san,uchar si)//第三、四段数码管函数
{
P2=0XC0;P0=0X04; //选中第s三个数码管位选
P2=0XFF;P0=tab[san]; //让第一个数码管显示san指向的值
delayms(1); //延时1ms
P2=0XC0;P0=0X08; //选中第四个数码管位选
P2=0XFF;P0=tab[si]; //让第一个数码管显示si指向的值
delayms(1); //延时1ms
}
void display3(uchar wu,uchar liu)//第五、六段数码管函数
{
P2=0XC0;P0=0X10; //选中第五个数码管位选
P2=0XFF;P0=tab[wu]; //让第一个数码管显示wu指向的值
delayms(1); //延时1ms
P2=0XC0;P0=0X20; //选中第六个数码管位选
P2=0XFF;P0=tab[liu]; //让第一个数码管显示liu指向的值
delayms(1); //延时1ms
}
void display4(uchar qi,uchar ba)//第七、八段数码管函数
{
P2=0XC0;P0=0X40; //选中第七个数码管位选
P2=0XFF;P0=tab[qi]; //让第一个数码管显示qi指向的值
delayms(1); //延时1ms
P2=0XC0;P0=0X80; //选中第八个数码管位选
P2=0XFF;P0=tab[ba]; //让第一个数码管显示ba指向的值
delayms(1); //延时1ms
P2=0XC0;P0=0X80; //选中第八个数码管位选
P2=0XFF;P0=0XFF; //让第八个数码管熄灭
}
ds1302.c程序
#include
#include
#include
sbit SCK=P1^7;
sbit SDA=P2^3;
sbit RST = P1^3; // DS1302复位
unsigned char shijian[]={
50,59,23,0,0,0,0};
void Write_Ds1302_Byte(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK=0;
SDA=temp&0x01;
temp>>=1;
SCK=1;
}
}
void Write_Ds1302( unsigned char address,unsigned char dat )
{
RST=0;
_nop_();
SCK=0;
_nop_();
RST=1;
_nop_();
Write_Ds1302_Byte(address);
Write_Ds1302_Byte((dat/10<<4)|(dat%10));
RST=0;
}
unsigned char Read_Ds1302 ( unsigned char address )
{
unsigned char i,temp=0x00,dat1,dat2;
RST=0;
_nop_();
SCK=0;
_nop_();
RST=1;
_nop_();
Write_Ds1302_Byte(address);
for (i=0;i<8;i++)
{
SCK=0;
temp>>=1;
if(SDA)
temp|=0x80;
SCK=1;
}
RST=0;
_nop_();
RST=0;
SCK=0;
_nop_();
SCK=1;
_nop_();
SDA=0;
_nop_();
SDA=1;
_nop_();
dat1=temp/16;
dat2=temp%16;
temp=dat1*10+dat2;
return (temp);
}
void DS_init()
{
unsigned char add,i;
add=0x80;
Write_Ds1302(0x8e,0x00);
for(i=0;i<7;i++)
{
Write_Ds1302(add,shijian[i]);
add=add+2;
}
Write_Ds1302(0x8e,0x80);
}
void DS_get()
{
unsigned char add,i;
add=0x81;
Write_Ds1302(0x8e,0x00);
for(i=0;i<7;i++)
{
shijian[i]=Read_Ds1302(add);
add=add+2;
}
Write_Ds1302(0x8e,0x80);
}
ds18b20.c程序
#include
#include "ds18b20.h"
sbit DQ = P1^4; //单总线接口
//单总线延时函数
void Delay_OneWire(unsigned int t)
{
while(t--);
}
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(50);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(50);
}
//从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(50);
}
return dat;
}
//DS18B20设备初始化
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(120);
DQ = 0;
Delay_OneWire(800);
DQ = 1;
Delay_OneWire(100);
initflag = DQ;
Delay_OneWire(50);
return initflag;
}
unsigned char Tempget()
{
unsigned char low,high,temp;
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=high<<4;
temp|=(low>>4);
return temp;
}
ds1302.h程序
#ifndef __DS1302_H
#define __DS1302_H
void Write_Ds1302_Byte(unsigned char temp);
void Write_Ds1302( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302 ( unsigned char address );
void DS_init();
void DS_get();
#endif
ds18b20.h程序
#ifndef __DS18B20_H
#define __DS18B20_H
//单总线延时函数
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
unsigned char Tempget();
#endif
第六届蓝桥杯单片机省赛作品演示