main.c程序
#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,0xc6};
uchar yi,er,san,si,wu,liu,qi,ba; //定义字符型变量yi,er,san,si,wu,liu,qi,ba,当作数码管显示控制变量
extern unsigned char shijian[];
uchar s7=5,s6=0,s4=0,wendu=0,LED_kai=0;
uchar naozhong[3]={
0,0,0};
uint miao=0,tt=0;
bit fla=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();
Timer0Init();
while(1)
{
DS_get();
if(wendu==0)
{
if(s7==5)
{
yi=shijian[2]/10;er=shijian[2]%10;san=10;si=shijian[1]/10;wu=shijian[1]%10;liu=10;qi=shijian[0]/10;ba=shijian[0]%10; //显示时钟页面
}
else if(s7==1)
{
if(shijian[0]%2==0){
yi=shijian[2]/10;er=shijian[2]%10;san=10;si=shijian[1]/10;wu=shijian[1]%10;liu=10;qi=shijian[0]/10;ba=shijian[0]%10;} //时钟时选中页面
else {
yi=11;er=11;}
}
else if(s7==2)
{
if(shijian[0]%2==0){
yi=shijian[2]/10;er=shijian[2]%10;san=10;si=shijian[1]/10;wu=shijian[1]%10;liu=10;qi=shijian[0]/10;ba=shijian[0]%10;} //时钟分选中页面
else {
si=11;wu=11;}
}
else if(s7==3)
{
if(shijian[0]%2==0){
yi=shijian[2]/10;er=shijian[2]%10;san=10;si=shijian[1]/10;wu=shijian[1]%10;liu=10;qi=shijian[0]/10;ba=shijian[0]%10;} //时钟秒选中页面
else {
qi=11;ba=11;}
}
if(s6==5)
{
yi=naozhong[2]/10;er=naozhong[2]%10;san=10;si=naozhong[1]/10;wu=naozhong[1]%10;liu=10;qi=naozhong[0]/10;ba=naozhong[0]%10;; //显示闹钟页面
}
else if(s6==1)
{
if(shijian[0]%2==0){
yi=naozhong[2]/10;er=naozhong[2]%10;san=10;si=naozhong[1]/10;wu=naozhong[1]%10;liu=10;qi=naozhong[0]/10;ba=naozhong[0]%10;} //闹钟时选中页面
else {
yi=11;er=11;}
}
else if(s6==2)
{
if(shijian[0]%2==0){
yi=naozhong[2]/10;er=naozhong[2]%10;san=10;si=naozhong[1]/10;wu=naozhong[1]%10;liu=10;qi=naozhong[0]/10;ba=naozhong[0]%10;} //闹钟分选中页面
else {
si=11;wu=11;}
}
else if(s6==3)
{
if(shijian[0]%2==0){
yi=naozhong[2]/10;er=naozhong[2]%10;san=10;si=naozhong[1]/10;wu=naozhong[1]%10;liu=10;qi=naozhong[0]/10;ba=naozhong[0]%10;} //闹钟秒选中页面
else {
qi=11;ba=11;}
}
}
else if(wendu==1)
{
yi=11;er=11;san=11;si=11;wu=11;liu=Tempget()/10;qi=Tempget()%10;ba=12; //温度显示页面
}
if((shijian[0]==naozhong[0])&&(shijian[1]==naozhong[1])&&(shijian[2]==naozhong[2])) //判断时钟时分秒是否跟闹钟时分秒重合
{
LED_kai=1;tt=0;miao=0; //是的话打开L1灯
}
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(LED_kai==0) //非闹钟提醒状态下
{
if(s7==0){
s7=5;s6=0;} //按键按下切换相应状态,这里有按键按下s6清零,方便显示时钟页面
else if(s7==5){
s7=1;} //按键按下切换相应状态,进入时钟时选中页面
else if(s7==1){
s7=2;} //按键按下切换相应状态,进入时钟分选中页面
else if(s7==2){
s7=3;} //按键按下切换相应状态,进入时钟秒选中页面
else if(s7==3){
s7=5;} //按键按下切换相应状态,进入时钟显示页面
}
else if(LED_kai==1) //闹钟提醒状态下,按键按下则关L1灯
{
LED_kai=0;P2=0X80;P0=0XFF;
}
}
while(!P30); //如果按键不松开,则一直循环
}
else if(P31==0) //判断P31是否等于0
{
delayms(5); //延时5ms
if(P31==0) //再次判断P31是否等于0
{
if(LED_kai==0) //非闹钟提醒状态下
{
if(s6==0){
s6=5;s7=0;} //按键按下切换相应状态,这里有按键按下s6清零,方便显示闹钟页面
else if(s6==5){
s6=1;} //按键按下切换相应状态,进入闹钟时选中页面
else if(s6==1){
s6=2;} //按键按下切换相应状态,进入闹钟分选中页面
else if(s6==2){
s6=3;} //按键按下切换相应状态,进入闹钟秒选中页面
else if(s6==3){
s6=5;} //按键按下切换相应状态,进入闹钟显示页面
}
else if(LED_kai==1) //闹钟提醒状态下,按键按下则关L1灯
{
LED_kai=0;P2=0X80;P0=0XFF;
}
}
while(!P31); //如果按键不松开,则一直循环
}
else if(P32==0) //判断P32是否等于0
{
delayms(5); //延时5ms
if(P32==0) //再次判断P32是否等于0
{
if(LED_kai==0) //非闹钟提醒状态下
{
if(s7==1)
{
if(shijian[2]==23)shijian[2]=23;//判断时钟时是否大于等于23,是的话时还是等于23
else shijian[2]++; //否则时钟时进行加一
DS_init(); //初始化时钟
}
else if(s7==2)
{
if(shijian[1]==59)shijian[1]=59;//判断时钟分是否大于等于59,是的话分还是等于59
else shijian[1]++; //否则时钟分进行加一
DS_init(); //初始化时钟
}
else if(s7==3)
{
if(shijian[0]==59)shijian[0]=59;//判断时钟秒是否大于等于59,是的话秒还是等于59
else shijian[0]++; //否则时钟秒进行加一
DS_init(); //初始化时钟
}
if(s6==1)
{
if(naozhong[2]==23)naozhong[2]=23;//判断闹钟时是否大于等于23,是的话时还是等于23
else naozhong[2]++; //否则闹钟时进行加一
}
else if(s6==2)
{
if(naozhong[1]==59)naozhong[1]=59;//判断闹钟分是否大于等于59,是的话分还是等于59
else naozhong[1]++; //否则闹钟分进行加一
}
else if(s6==3)
{
if(naozhong[0]==59)naozhong[0]=59;//判断闹钟秒是否大于等于59,是的话秒还是等于59
else naozhong[0]++; //否则闹钟秒进行加一
}
}
else if(LED_kai==1) //闹钟提醒状态下,按键按下则关L1灯
{
LED_kai=0;P2=0X80;P0=0XFF;
}
}
while(!P32); //如果按键不松开,则一直循环
}
else if(P33==0) //判断P33是否等于0
{
delayms(5); //延时5ms
if(P33==0) //再次判断P33是否等于0
{
s4=1; //按键按下s4置1
if(s7==5)wendu=1; //判断是否是在始终显示状态下按键,是的话显示温度页面
}
}
else if((s4==1)&&(P33==1)) //判断s4是否等于1且按键抬起
{
s4=0; //s4置0,为下次按键按下做准备
wendu=0; //温度不显示
if(LED_kai==0) //非闹钟提醒状态下
{
if(s7==1)
{
if(shijian[2]==0)shijian[2]=0;//判断时钟时是否大于等于0,是的话时还是等于0
else shijian[2]--; //否则时钟时进行减一
DS_init(); //初始化时钟
}
else if(s7==2)
{
if(shijian[1]==0)shijian[1]=0;//判断时钟分是否大于等于0,是的话分还是等于0
else shijian[1]--; //否则时钟分进行减一
DS_init(); //初始化时钟
}
else if(s7==3)
{
if(shijian[0]==0)shijian[0]=0;//判断时钟秒是否大于等于0,是的话秒还是等于0
else shijian[0]--; //否则时钟秒进行减一
DS_init(); //初始化时钟
}
if(s6==1)
{
if(naozhong[2]==0)naozhong[2]=0;//判断闹钟时是否大于等于0,是的话时还是等于0
else naozhong[2]--; //否则闹钟时进行减一
}
else if(s6==2)
{
if(naozhong[1]==0)naozhong[1]=0;//判断闹钟分是否大于等于0,是的话分还是等于0
else naozhong[1]--; //否则闹钟分进行减一
}
else if(s6==3)
{
if(naozhong[0]==0)naozhong[0]=0;//判断闹钟秒是否大于等于0,是的话秒还是等于0
else naozhong[0]--; //否则闹钟秒进行减一
}
}
else if(LED_kai==1) //闹钟提醒状态下,按键按下则关L1灯
{
LED_kai=0;P2=0X80;P0=0XFF;
}
}
}
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++,miao++;
if((tt==40)&&(LED_kai==1))//判断计时是否到了0.2s并且LED_kai等于1
{
tt=0; //tt置0
if(fla==0){
fla=1;P2=0X80;P0=0XFE;} //判断fla是否等于0,是的话L1开,fla置1
else if(fla==1){
fla=0;P2=0X80;P0=0XFF;} //判断fla是否等于1,是的话L1关,fla置0
}
if(miao==1000) //定义5秒钟
{
LED_kai=0; //LED_kai标志位置0
miao=0; //秒置0
P2=0X80;P0=0XFF;//关闭LED灯
}
}
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
unsigned char shijian[]={
50,59,23,0,0,0,0};
sbit SCK=P1^7;
sbit SDA=P2^3;
sbit RST = P1^3; // DS1302复位
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 temp,low,high;
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
第八届蓝桥杯单片机省赛作品演示