基于PIC16F877A单片机的温度,时间显示以及闹钟设置,硬件和软件配备
一,硬件图
#include
__CONFIG(0x3B31);
#define rs RD0
#define rw RD1
#define en RD2
#define BEEP RD3
#define s1 RA0
#define s2 RA1
#define s3 RA2
#define s4 RA3
#define uint unsigned int
#define uchar unsigned char
signed char set_time[7]={0,58,23,6,1,5,12};//秒 分 时 星期 日 月 年
signed char read_time[7]={0,0,0,0,0,0,0};
signed char shi=7,fen=15,alarm_time=1,reapeat_fen=2,cent;//闹钟时,闹钟分,闹铃响分钟,闹铃响间隔
uchar s1_num,s2_num;
const uchar alarm[]={"ALARM TIME:"};
const uchar mode[]={"MODE:"};
const uchar rpt[]={"RPT:"};
const uchar min[]={"min"};
void PORT_INIT()
{
TRISA=0xff;//A口设置为输入
ADCON1=0x06;//RA口上电复位为模拟输入口
TRISC3=1;//SCL和SDA设置为输入
TRISC4=1;
TRISD=0x00;//D口设置为输出
}
void IIC_INIT()
{
SSPCON=0x28;
STAT_SMP=0;
SSPADD=4;
}
void delayms(uint z)//延时 函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void delayus(uint k)
{
while(k--);
}
void write_byte_low(uchar R1,uchar flag0)//写一个字节的低4位,flag0为指令/数据选择位
{ //,0为写指令,1为写数据
uchar low;
rs=flag0;
low=R1&0x0f;
low=low<<4;
PORTD&=0x0f;NOP();
PORTD|=low;NOP();//写指令的低4位
en=1;delayus(20);en=0;
}
void lcd_write(uchar dat,uchar flag1)//写指令/数据到1602
{
uchar dat_high,dat_low;
dat_high=dat>>4;
write_byte_low(dat_high,flag1);
dat_low=dat&0x0f;
write_byte_low(dat_low,flag1);
NOP();
}
void write_string(uchar address,uchar const *str)//往指定的地址写字符串
{
uchar i=0;
lcd_write(address,0);
while(str[i]!='\0')
{
lcd_write(str[i],1);
delayus(5);
i++;
}
}
void LCD_INIT()//初始化函数
{
rw=0;
en=0;
delayms(20);
write_byte_low(0b0011,0);
delayms(1);
write_byte_low(0b0011,0);
delayus(10);
write_byte_low(0b0011,0);
delayus(10);
write_byte_low(0b0010,0);
delayms(1);
lcd_write(0x28,0);
delayms(5);
lcd_write(0x0c,0);
delayms(5);
lcd_write(0x01,0);
delayms(5);
lcd_write(0x06,0);
delayms(5);
}
void naoling()
{
uchar i;
for(i=0;i<20;i++)
{
BEEP=1;
delayus(5);
BEEP=0;
delayus(5);
}
}
void IIC_SEND(uchar num)
{
SSPBUF=num;
while(STAT_RW==1);//等待发送结束
while(SSPIF==0);
while(ACKSTAT==1);//等待应答
}
signed char read_temp()//读温度
{
signed char temp;
SEN=1;
while(SEN==1);
IIC_SEND(0b10011010);
IIC_SEND(0);
RSEN=1;
while(RSEN==1);
IIC_SEND(0b10011011);
RCEN=1;
while(RCEN==1);
// SSPIF=0;
// while(SSPIF==0);//等待接收结束
temp=SSPBUF;
PEN=1;
while(PEN==1);
return temp;
}
void dispose()//BCD数据处理
{
uchar i,temp1,temp2;
for(i=0;i<7;i++)
{
temp1=set_time[i]/10;
temp2=set_time[i]%10;
set_time[i]=temp1*16+temp2;
}
}
void time_csh()//时间初始化
{
uchar i;
dispose();
for(i=0;i<7;i++)
{
SEN=1;//起始信号
while(SEN==1);//检测起始信号是否已完成
IIC_SEND(0xd0);
IIC_SEND(i);
IIC_SEND(set_time[i]);
PEN=1;//停止信号
while(PEN==1);
}
}
void read_ds1307()//读时间
{
uchar k;
for(k=0;k<8;k++)
{
SEN=1;//起始信号
while(SEN==1);
IIC_SEND(0xd0);
IIC_SEND(k);
PEN=1;//停止信号
while(PEN==1);
RSEN=1;//重新启动
while(RSEN==1);
IIC_SEND(0xd1);
SSPIF=0;
RCEN=1;
while(SSPIF==0);//等待接收结束
read_time[k-1]=SSPBUF;
NOP();
NOP();
PEN=1;//停止信号
while(PEN==1);
}
}
void display_time()
{
lcd_write(0x80,0);
lcd_write(0x32,1);
lcd_write(0x30,1);
lcd_write(0x30+read_time[6]/16,1);//年
lcd_write(0x30+read_time[6]%16,1);
lcd_write('-',1);
lcd_write(0x30+read_time[5]/16,1);//月
lcd_write(0x30+read_time[5]%16,1);
lcd_write('-',1);
lcd_write(0x30+read_time[4]/16,1);//日
lcd_write(0x30+read_time[4]%16,1);
lcd_write(0x80+0x0d,0);
switch(read_time[3])
{
case 1:lcd_write('M',1);lcd_write('O',1);lcd_write('N',1);break;
case 2:lcd_write('T',1);lcd_write('U',1);lcd_write('E',1);break;
case 3:lcd_write('W',1);lcd_write('E',1);lcd_write('D',1);break;
case 4:lcd_write('T',1);lcd_write('H',1);lcd_write('U',1);break;
case 5:lcd_write('F',1);lcd_write('R',1);lcd_write('I',1);break;
case 6:lcd_write('S',1);lcd_write('A',1);lcd_write('T',1);break;
case 7:lcd_write('S',1);lcd_write('U',1);lcd_write('N',1);break;
}
lcd_write(0x80+0x40,0);
lcd_write(0x30+read_time[2]/16,1);//时
lcd_write(0x30+read_time[2]%16,1);
lcd_write(':',1);
lcd_write(0x30+read_time[1]/16,1); //分
lcd_write(0x30+read_time[1]%16,1);
lcd_write(':',1);
lcd_write(0x30+read_time[0]/16,1); //秒
lcd_write(0x30+read_time[0]%16,1);
NOP();
NOP();
cent=read_temp();
lcd_write(0x80+0x4b,0);
lcd_write(0x30+cent/10,1);
lcd_write(0x30+cent%10,1);
lcd_write(0xdf,1);
lcd_write('C',1);
if((shi==(read_time[2]/16*10+read_time[2]%16))&&(fen<=(read_time[1]/16*10+read_time[1]%16))&&((read_time[1]/16*10+read_time[1]%16)<(fen+alarm_time)))
{
naoling();
}
if((shi==(read_time[2]/16*10+read_time[2]%16))&&(fen+reapeat_fen<=(read_time[1]/16*10+read_time[1]%16))&&((read_time[1]/16*10+read_time[1]%16)<(fen+alarm_time+reapeat_fen)))
{
naoling();
}
if((shi==(read_time[2]/16*10+read_time[2]%16))&&(fen+2*reapeat_fen<=(read_time[1]/16*10+read_time[1]%16))&&((read_time[1]/16*10+read_time[1]%16)<(fen+alarm_time+2*reapeat_fen)))
{
naoling();
}
if((shi==(read_time[2]/16*10+read_time[2]%16))&&(fen+3*reapeat_fen<=(read_time[1]/16*10+read_time[1]%16))&&((read_time[1]/16*10+read_time[1]%16)<(fen+alarm_time+3*reapeat_fen)))
{
naoling();
}
if((shi==(read_time[2]/16*10+read_time[2]%16))&&(fen+4*reapeat_fen<=(read_time[1]/16*10+read_time[1]%16))&&((read_time[1]/16*10+read_time[1]%16)<(fen+alarm_time+4*reapeat_fen)))
{
naoling();
}
}
void setting_time()
{
uchar l,s2_value,setting_flag;
if(s2==0)
{
delayms(10);
if(s2==0)
{
s2_value++;
setting_flag = 1;
while(s2==0);//松手检测
for(l=0;l<7;l++)//存储当前时间数据 //年 星期 月 日 时 分 秒
{
set_time[l]=read_time[l]/16*10+read_time[l]%16;
}
while(setting_flag)
{
if(s2==0)
{
delayms(5);
if(s2==0)
{
s2_value++;
while(s2==0);//松手检测
}
}
if(s2_value==1)
{
lcd_write(0x83,0);//指向年份
lcd_write(0x0f,0);//显示游标并闪烁
if(s3==0)
{
delayms(5);
if(s3==0)
{
set_time[6]++;
if(set_time[6]==100)
{
set_time[6]=0;
}
lcd_write(0x82,0);
lcd_write(0x30+set_time[6]/10,1);
lcd_write(0x30+set_time[6]%10,1);
lcd_write(0x83,0);//指向年份
while(s3==0);
}
}
if(s4==0)
{
delayms(5);
if(s4==0)
{
set_time[6]--;
if(set_time[6]==-1)
{
set_time[6]=99;
}
lcd_write(0x82,0);
lcd_write(0x30+set_time[6]/10,1);
lcd_write(0x30+set_time[6]%10,1);
lcd_write(0x83,0);//指向年份
while(s4==0);
}
}
}
if(s2_value==2)
{
lcd_write(0x86,0);//指向月份
if(s3==0)
{
delayms(5);
if(s3==0)
{
set_time[5]++;
if(set_time[5]==13)
{
set_time[5]=1;
}
lcd_write(0x85,0);
lcd_write(0x30+set_time[5]/10,1);
lcd_write(0x30+set_time[5]%10,1);
lcd_write(0x86,0);//指向月份
while(s3==0);
}
}
if(s4==0)
{
delayms(5);
if(s4==0)
{
set_time[5]--;
if(set_time[5]==0)
{
set_time[5]=12;
}
lcd_write(0x85,0);
lcd_write(0x30+set_time[5]/10,1);
lcd_write(0x30+set_time[5]%10,1);
lcd_write(0x86,0);//指向月份
while(s4==0);
}
}
}
if(s2_value==3)
{
lcd_write(0x89,0);//指向日
if(s3==0)
{
delayms(5);
if(s3==0)
{
set_time[4]++;
if(set_time[4]==32)
{
set_time[4]=1;
}
lcd_write(0x88,0);
lcd_write(0x30+set_time[4]/10,1);
lcd_write(0x30+set_time[4]%10,1);
lcd_write(0x89,0);//指向日
while(s3==0);
}
}
if(s4==0)
{
delayms(5);
if(s4==0)
{
set_time[4]--;
if(set_time[4]==0)
{
set_time[4]=31;
}
lcd_write(0x88,0);
lcd_write(0x30+set_time[4]/10,1);
lcd_write(0x30+set_time[4]%10,1);
lcd_write(0x89,0);//指向日
while(s4==0);
}
}
}
if(s2_value==4)
{
lcd_write(0x8f,0);//指向星期
if(s3==0)
{
delayms(5);
if(s3==0)
{
set_time[3]++;
if(set_time[3]==8)
{
set_time[3]=1;
}
switch(set_time[3])
{
case 1:lcd_write(0x8d,0);lcd_write('M',1);lcd_write('O',1);lcd_write('N',1);break;
case 2:lcd_write(0x8d,0);lcd_write('T',1);lcd_write('U',1);lcd_write('E',1);break;
case 3:lcd_write(0x8d,0);lcd_write('W',1);lcd_write('E',1);lcd_write('D',1);break;
case 4:lcd_write(0x8d,0);lcd_write('T',1);lcd_write('H',1);lcd_write('U',1);break;
case 5:lcd_write(0x8d,0);lcd_write('F',1);lcd_write('R',1);lcd_write('I',1);break;
case 6:lcd_write(0x8d,0);lcd_write('S',1);lcd_write('A',1);lcd_write('T',1);break;
case 7:lcd_write(0x8d,0);lcd_write('S',1);lcd_write('U',1);lcd_write('N',1);break;
}
lcd_write(0x8f,0);//指向星期
while(s3==0);
}
}
if(s4==0)
{
delayms(5);
if(s4==0)
{
set_time[3]--;
if(set_time[3]==0)
{
set_time[3]=7;
}
switch(set_time[3])
{
case 1:lcd_write(0x8d,0);lcd_write('M',1);lcd_write('O',1);lcd_write('N',1);break;
case 2:lcd_write(0x8d,0);lcd_write('T',1);lcd_write('U',1);lcd_write('E',1);break;
case 3:lcd_write(0x8d,0);lcd_write('W',1);lcd_write('E',1);lcd_write('D',1);break;
case 4:lcd_write(0x8d,0);lcd_write('T',1);lcd_write('H',1);lcd_write('U',1);break;
case 5:lcd_write(0x8d,0);lcd_write('F',1);lcd_write('R',1);lcd_write('I',1);break;
case 6:lcd_write(0x8d,0);lcd_write('S',1);lcd_write('A',1);lcd_write('T',1);break;
case 7:lcd_write(0x8d,0);lcd_write('S',1);lcd_write('U',1);lcd_write('N',1);break;
}
lcd_write(0x8f,0);//指向星期
while(s4==0);
}
}
}
if(s2_value==5)
{
lcd_write(0x80+0x41,0);//指向小时
if(s3==0)
{
delayms(5);
if(s3==0)
{
set_time[2]++;
if(set_time[2]==24)
{
set_time[2]=0;
}
lcd_write(0x80+0x40,0);
lcd_write(0x30+set_time[2]/10,1);
lcd_write(0x30+set_time[2]%10,1);
lcd_write(0x80+0x41,0);//指向小时
while(s3==0);
}
}
if(s4==0)
{
delayms(5);
if(s4==0)
{
set_time[2]--;
if(set_time[2]==-1)
{
set_time[2]=23;
}
lcd_write(0x80+0x40,0);
lcd_write(0x30+set_time[2]/10,1);
lcd_write(0x30+set_time[2]%10,1);
lcd_write(0x80+0x41,0);//指向小时
while(s4==0);
}
}
}
if(s2_value==6)
{
lcd_write(0x80+0x44,0);//指向分钟
if(s3==0)
{
delayms(5);
if(s3==0)
{
set_time[1]++;
if(set_time[1]==60)
{
set_time[1]=0;
}
lcd_write(0x80+0x43,0);
lcd_write(0x30+set_time[1]/10,1);
lcd_write(0x30+set_time[1]%10,1);
lcd_write(0x80+0x44,0);//指向分钟
while(s3==0);
}
}
if(s4==0)
{
delayms(5);
if(s4==0)
{
set_time[1]--;
if(set_time[1]==-1)
{
set_time[1]=59;
}
lcd_write(0x80+0x43,0);
lcd_write(0x30+set_time[1]/10,1);
lcd_write(0x30+set_time[1]%10,1);
lcd_write(0x80+0x44,0);//指向分钟
while(s4==0);
}
}
}
if(s2_value==7)
{
lcd_write(0x80+0x47,0);//指向秒
if(s3==0)
{
delayms(5);
if(s3==0)
{
set_time[0]++;
if(set_time[0]==60)
{
set_time[0]=0;
}
lcd_write(0x80+0x46,0);
lcd_write(0x30+set_time[0]/10,1);
lcd_write(0x30+set_time[0]%10,1);
lcd_write(0x80+0x47,0);//指向分钟
while(s3==0);
}
}
if(s4==0)
{
delayms(5);
if(s4==0)
{
set_time[0]--;
if(set_time[0]==-1)
{
set_time[0]=59;
}
lcd_write(0x80+0x46,0);
lcd_write(0x30+set_time[0]/10,1);
lcd_write(0x30+set_time[0]%10,1);
lcd_write(0x80+0x47,0);//指向分钟
while(s4==0);
}
}
}
if(s2_value==8)//这里注意?
{
s2_value=0;
lcd_write(0x0c,0);
setting_flag=0;
time_csh();
}
}
}
}
}
void naozhong()
{
write_string(0x80,alarm);
lcd_write(0x30+shi/10,1);
lcd_write(0x30+shi%10,1);
lcd_write('-',1);
lcd_write(0x30+fen/10,1);
lcd_write(0x30+fen%10,1);
write_string(0x80+0x40,mode);
lcd_write(0x30+alarm_time,1);
write_string(0x80+0x47,rpt);
lcd_write(0x30+reapeat_fen/10,1);
lcd_write(0x30+reapeat_fen%10,1);
write_string(0x80+0x4d,min);
}
uchar s1_scan()
{
if(s1==0)
{
delayms(5);
if(s1==0)
{
s1_num++;
if(s1_num==2)
{
s1_num=0;
s2_num=0;
lcd_write(0x0c,0);
}
while(s1==0);
lcd_write(0x01,0);
if(s1_num==1)
{
naozhong();
lcd_write(0x0f,0);
}
}
}
return s1_num;
}
void setting_naozhong()
{
if(s2==0)
{
delayms(5);
if(s2==0)
{
s2_num++;
if(s2_num==4)
{
s2_num=0;
}
while(s2==0);
}
}
switch(s2_num)
{
case 0:
{
lcd_write(0x8c,0);
if(s3==0)
{
delayms(5);
if(s3==0)
{
shi++;
if(shi==24)
{
shi=0;
}
lcd_write(0x8b,0);
lcd_write(0x30+shi/10,1);
lcd_write(0x30+shi%10,1);
lcd_write(0x8c,0);//指向小时
while(s3==0);
}
}
if(s4==0)
{
delayms(5);
if(s4==0)
{
shi--;
if(shi==-1)
{
shi=23;
}
lcd_write(0x8b,0);
lcd_write(0x30+shi/10,1);
lcd_write(0x30+shi%10,1);
lcd_write(0x8c,0);//指向小时
while(s4==0);
}
}
break;
}
case 1:
{
lcd_write(0x8f,0);
if(s3==0)
{
delayms(5);
if(s3==0)
{
fen++;
if(fen==60)
{
fen=0;
}
lcd_write(0x8e,0);
lcd_write(0x30+fen/10,1);
lcd_write(0x30+fen%10,1);
lcd_write(0x8f,0);//指向小时
while(s3==0);
}
}
if(s4==0)
{
delayms(5);
if(s4==0)
{
fen--;
if(fen==-1)
{
fen=59;
}
lcd_write(0x8e,0);
lcd_write(0x30+fen/10,1);
lcd_write(0x30+fen%10,1);
lcd_write(0x8f,0);//指向小时
while(s4==0);
}
}
break;
}
case 2:
{
lcd_write(0x80+0x45,0);
if(s3==0)
{
delayms(5);
if(s3==0)
{
alarm_time++;
if(alarm_time==10)
{
alarm_time=1;
}
lcd_write(0x30+alarm_time,1);
lcd_write(0x80+0x45,0);//指向小时
while(s3==0);
}
}
if(s4==0)
{
delayms(5);
if(s4==0)
{
alarm_time--;
if(alarm_time==0)
{
alarm_time=9;
}
lcd_write(0x30+alarm_time,1);
lcd_write(0x80+0x45,0);//指向小时
while(s4==0);
}
}
break;
}
case 3:
{
lcd_write(0x80+0x4c,0);
if(s3==0)
{
delayms(5);
if(s3==0)
{
reapeat_fen++;
if(reapeat_fen==60)
{
reapeat_fen=0;
}
lcd_write(0x80+0x4b,0);
lcd_write(0x30+reapeat_fen/10,1);
lcd_write(0x30+reapeat_fen%10,1);
lcd_write(0x80+0x4c,0);//指向小时
while(s3==0);
}
}
if(s4==0)
{
delayms(5);
if(s4==0)
{
reapeat_fen--;
if(reapeat_fen==-1)
{
reapeat_fen=59;
}
lcd_write(0x80+0x4b,0);
lcd_write(0x30+reapeat_fen/10,1);
lcd_write(0x30+reapeat_fen%10,1);
lcd_write(0x80+0x4c,0);//指向小时
while(s4==0);
}
}
break;
}
default:break;
}
}
void main()
{
PORT_INIT();
LCD_INIT();
IIC_INIT();
time_csh();
while(1)
{
switch(s1_scan())
{
case 0:read_ds1307();display_time();setting_time();break;
case 1:setting_naozhong();break;
default:break;
}
}
}
¥29.8
¥9.9
¥59.8