#include"config.h"
#define SDA_DIR_OUT P1DIR|=BIT4
#define SDA_DIR_IN P1DIR&=~BIT4
#define SCL_DIR_OUT P1DIR|=BIT5
#define SDA_IN P1IN&BIT4
#define SDA1 P1OUT|=BIT4
#define SDA0 P1OUT&=~BIT4
#define SCL1 P1OUT|=BIT5
#define SCL0 P1OUT&=~BIT5
uchar year,month,date,hour,minute,second;
uchar const table[]={'0','1','2','3','4','5','6','7','8','9'};
uchar const month_12[]={31,29,31,30,31,30,31,31,30,31,30,31};
uchar clockset,clockon,clockoff[5],clock_on;
uchar oclock[5][2];
uchar BCD2HEX(uchar val) //BCD转换为Byte
{
uchar temp;
temp=val&0x0f;
val>>=4;
val&=0x0f;
val*=10;
temp+=val;
return temp;
}
uchar HEX2BCD(uchar val) //B码转换为BCD码
{
uchar i,j,k;
i=val/10;
j=val%10;
k=j+(i<<4);
return k;
}
void Start_I2C()
{
SDA_DIR_OUT;
SCL_DIR_OUT;
SDA1; //发送起始条件的数据信号
delay_us(5);
SCL1;
delay_us(5); //起始条件建立时间大于4.7us,延时
SDA0; //发送起始信号
delay_us(5); // 起始条件锁定时间大于4μs
// SCL0; //钳住I2C总线,准备发送或接收数据
// delay_us(2);
}
void Stop_I2C()
{
SDA_DIR_OUT;
SCL_DIR_OUT;
SDA0; //发送结束条件的数据信号
delay_us(5); //发送结束条件的时钟信号
SCL1; //结束条件建立时间大于4us
delay_us(5);
SDA1; //发送I2C总线结束信号
delay_us(1);
}
void SendByte(uchar c)
{
uchar BitCnt;
SDA_DIR_OUT;
SCL_DIR_OUT;
SCL0;
delay_us(10);
for(BitCnt=0;BitCnt<8;BitCnt++) //要传送的数据长度为8位
{
if(c&0x80)
SDA1; //判断发送位
else
SDA0;
delay_us(1);
SCL0; //置时钟线为高,通知被控器开始接收数据位
delay_us(1); //保证时钟高电平周期大于4μs
SCL1;
delay_us(5);
c=c<<1;
SCL0; //置时钟线为高,通知被控器开始接收数据位
delay_us(5);
}
SDA1; //8位发送完后释放数据线,准备接收应答位
delay_us(1);
SCL0;
delay_us(1);
SCL1;
delay_us(1);
SCL0;
}
uchar ReceiveByte(uchar b)
{
uchar i;
uchar temp;
uchar Dat=0;
/*
SDA_H;
delay(5);
SCL_L;
delay(5);
*/
SDA_DIR_IN;
for(i=0;i<8;i++)
{
SCL1;
delay_us(5);
Dat=Dat<<1;
delay_us(1);
temp=SDA_IN;
if(temp&0x10)
Dat|=0x01;
else
Dat|=0x00;
delay_us(1);
SCL0;
delay_us(5);
}
SDA_DIR_OUT;
if(b)//每收一个数后发送ACK或nACK
SDA1;
else
SDA0;
delay_us(1);
SCL1;
delay_us(1);
SCL0;
delay_us(1);
SDA1; //释放总线
delay_us(1);
return Dat;
}
/****************************************************/
/***********将一个字节写入DS3231指定的地址***********/
void I2cByteWrite(uchar device,uint addr,uchar bytedata)
{
Start_I2C();
// delay_us(1);
SendByte(device);
// delay_us(1);
SendByte(addr);
// delay_us(1);
SendByte(bytedata);
// delay_us(1);
Stop_I2C();
}
/****************************************************/
/************从DS3231指定的地址读一个字节************/
uchar I2cByteRead(uchar device,uint addr)
{
uchar Dat=0;
Start_I2C();
SendByte(device);
// delay_us(1);
SendByte(addr);
// delay_us(1);
Start_I2C();
SendByte(0xd1);//读数
// delay_us(1);
Dat=ReceiveByte(1);//只接收一个字节,所以发nACK
Stop_I2C();
return Dat;
}
/***************************************************/
/*********************读取时间**********************/
void Readtime(void)
{
year=I2cByteRead(0xd0,0x06); //年
month=I2cByteRead(0xd0,0x05); //月
date=I2cByteRead(0xd0,0x04); //日
hour=I2cByteRead(0xd0,0x02); //时
minute=I2cByteRead(0xd0,0x01);//分
second=I2cByteRead(0xd0,0x00);//秒
}
/***************************************************/
/****************修改时间,BCD码输入*****************/
void ModifyTime(uchar yea,uchar mon,uchar da,uchar hou,uchar min,uchar sec)
{
uchar temp=0;
temp=HEX2BCD(yea);
I2cByteWrite(0xD0,0x06,temp);//修改年
temp=HEX2BCD(mon);
I2cByteWrite(0xD0,0x05,temp);//修改月
temp=HEX2BCD(da);
I2cByteWrite(0xD0,0x04,temp);//修改日
temp=HEX2BCD(hou);
I2cByteWrite(0xD0,0x02,temp);//修改时
temp=HEX2BCD(min);
I2cByteWrite(0xD0,0x01,temp);//修改分
temp=HEX2BCD(sec);
I2cByteWrite(0xD0,0x00,temp);//修改秒
}
/****************************************************/
/****************读取时间 计算 并显示****************/
void get_show_time(void)
{
uchar temp1,temp2;
char a[2];
temp1=I2cByteRead(0xd0,0x06); //年
temp2=BCD2HEX(temp1);
a[0]=table[temp2/10];
a[1]=table[temp2%10];
LCD_disp_string(0,1,a);
LCD_disp_char(2,1,'-');
temp1=I2cByteRead(0xd0,0x05); //月
temp2=BCD2HEX(temp1);
a[0]=table[temp2/10];
a[1]=table[temp2%10];
LCD_disp_string(3,1,a);
LCD_disp_char(5,1,'-');
temp1=I2cByteRead(0xd0,0x04); //日
temp2=BCD2HEX(temp1);
a[0]=table[temp2/10];
a[1]=table[temp2%10];
LCD_disp_string(6,1,a);
LCD_disp_char(8,1,'-');
temp1=I2cByteRead(0xd0,0x03); //星期
temp2=BCD2HEX(temp1);
temp2=table[temp2];
LCD_disp_char(9,1,temp2);
LCD_disp_char(10,1,' ');
LCD_disp_char(8,0,' ');
if(clockset==0)
{
temp1=I2cByteRead(0xd0,0x02); //时 24小时制
temp1&=0x3f;
temp2=BCD2HEX(temp1);
a[0]=table[temp2/10];
a[1]=table[temp2%10];
LCD_disp_string(8,0,a);
LCD_disp_char(10,0,':');
temp1=I2cByteRead(0xd0,0x01); //分
temp2=BCD2HEX(temp1);
a[0]=table[temp2/10];
a[1]=table[temp2%10];
LCD_disp_string(11,0,a);
LCD_disp_char(13,0,':');
temp1=I2cByteRead(0xd0,0x00); //秒
temp2=BCD2HEX(temp1);
a[0]=table[temp2/10];
a[1]=table[temp2%10];
LCD_disp_string(14,0,a);
}
if(clockset!=0)
{
LCD_disp_string(8,0," ");
a[0]=table[oclock[clockset-1][0]/10];
a[1]=table[oclock[clockset-1][0]%10];
LCD_disp_string(8,0,a);
LCD_disp_char(10,0,'-');
a[0]=table[oclock[clockset-1][1]/10];
a[1]=table[oclock[clockset-1][1]%10];
LCD_disp_string(11,0,a);
LCD_disp_string(13,0,"CK");
LCD_disp_char(15,0,table[clockoff[clockset-1]]);
}
}
//显示温度
void get_show_Temperature(void)
{
if(change==0)
{
uchar Ttemp1,Ttemp2;
char a[2];
Ttemp1=I2cByteRead(0xd0,0x11); //温度 高字节
Ttemp2=BCD2HEX(Ttemp1);
// LCD_disp_string(9,1," ");
// Ttemp3=I2cByteRead(0xd0,0x12); //温度低字节
// Ttemp4=BCD2HEX(Ttemp3);
a[0]=table[Ttemp2/10];
a[1]=table[Ttemp2%10];
LCD_disp_string(13,1,a);
LCD_disp_char(15,1,'c');
}
if(change!=0)
{
LCD_disp_string(13,1," ");
LCD_disp_char(15,1,table[change-1]);
}
if((clockset!=0)&&(change==0))
{
LCD_disp_string(13,1," ");
LCD_disp_char(13,1,table[clockset]);
LCD_disp_char(15,1,table[clockon]);
}
}
void change_del()
{
uchar temp1,temp2,temp3,temp4;
if(change>0)
{
temp1=I2cByteRead(0xd0,change-1);
temp2=BCD2HEX(temp1);
temp2-=1;
if(change<3)
{
if(temp2>59)
temp2=59;
}
if(change==3)
{
if(temp2>23)
temp2=23;
}
if(change==4)
{
if(temp2==0)
temp2=7;
}
if(change==5)
{
if(temp2==0)
{
temp3=I2cByteRead(0xd0,0x05);
temp4=BCD2HEX(temp3);
temp2=month_12[temp4-1];
}
}
if(change==6)
{
if(temp2==0)
temp2=12;
}
temp2=HEX2BCD(temp2);
I2cByteWrite(0xD0,change-1,temp2);//修改年
}
}
void change_add()
{
uchar temp1,temp2,temp3,temp4;
if(change>0)
{
temp1=I2cByteRead(0xd0,change-1);
temp2=BCD2HEX(temp1);
temp2+=1;
if(change<3)
{
if(temp2>59)
temp2=0;
}
if(change==3)
{
if(temp2>23)
temp2=0;
}
if(change==4)
{
if(temp2==8)
temp2=1;
}
if(change==5)
{
temp3=I2cByteRead(0xd0,0x05);
temp4=BCD2HEX(temp3);
if(temp2>month_12[temp4-1])
temp2=1;
}
if(change==6)
{
if(temp2==13)
temp2=1;
}
temp2=HEX2BCD(temp2);
I2cByteWrite(0xD0,change-1,temp2);//修改年
}
}
void change_set()
{
++change;
if(change>=8)
change=0;
}
void clock_set()
{
++clockset;
if(clockset>=6)
clockset=0;
}
void clock_add()
{
change=0;
++clockon;
if( clockon==3)
clockon=0;
}
void clock_change()
{
if(clockon==1)
{
++oclock[clockset-1][1];
if(oclock[clockset-1][1]>59)
oclock[clockset-1][1]=0;
}
if(clockon==2)
{
++oclock[clockset-1][0];
if(oclock[clockset-1][0]>23)
oclock[clockset-1][0]=0;
}
}
void Key_Icode(uchar dat)
{
LCD_disp_char(10,1,' ');
// LCD_disp_string(10,1," ");
switch(dat) //第3个字节是数据,第4个字节是反码
{ //为了更稳定,可以加上第4个字节数据的判断
case KEY_0:KEY_VAL=0; LCD_disp_char(11,1,KEY_VAL+0x30); LCD_disp_char(12,1,' '); break;
case KEY_1:KEY_VAL=1; LCD_disp_char(11,1,KEY_VAL+0x30); LCD_disp_char(12,1,' '); break;
case KEY_2:KEY_VAL=2; LCD_disp_char(11,1,KEY_VAL+0x30); LCD_disp_char(12,1,' '); break;
case KEY_3:KEY_VAL=3; LCD_disp_char(11,1,KEY_VAL+0x30); LCD_disp_char(12,1,' ');break;
case KEY_4:KEY_VAL=4; LCD_disp_char(11,1,KEY_VAL+0x30); LCD_disp_char(12,1,' ');break;
case KEY_5:KEY_VAL=5; LCD_disp_char(11,1,KEY_VAL+0x30); LCD_disp_char(12,1,' ');break;
case KEY_6:KEY_VAL=6; LCD_disp_char(11,1,KEY_VAL+0x30); LCD_disp_char(12,1,' ');break;
case KEY_7:KEY_VAL=7; LCD_disp_char(11,1,KEY_VAL+0x30); LCD_disp_char(12,1,' ');break;
case KEY_8:KEY_VAL=8; LCD_disp_char(11,1,KEY_VAL+0x30); LCD_disp_char(12,1,' ');break;
case KEY_9:KEY_VAL=9; LCD_disp_char(11,1,KEY_VAL+0x30); LCD_disp_char(12,1,' ');break;
case prex:LCD_disp_string(11,1,"PR");clock_change();break;
case nex :LCD_disp_string(11,1,"NX");clock_add();break;
case play_pause:LCD_disp_string(11,1,"PS");clock_set();break;
case ch_: LCD_disp_string(11,1,"C-");change_del();break;
case ch: LCD_disp_string(11,1,"CH");change_set();break;
case cha:LCD_disp_string(11,1,"C+");change_add();break;
case eq: LCD_disp_string(11,1,"EQ");
if(clockoff[clockset-1]==0)
clockoff[clockset-1]=1;
else clockoff[clockset-1]=0;
break;
case _a:LCD_disp_string(11,1,"V+");break;
case __:LCD_disp_string(11,1,"V-");break;
case _100a:LCD_disp_string(11,1,"1+");break;
case _200a:LCD_disp_string(11,1,"2+");break;
case power:LCD_disp_string(11,1,"PW");break;
case up: LCD_disp_string(11,1,"UP");break;
case down:LCD_disp_string(11,1,"DW");break;
case left:LCD_disp_string(11,1,"LF");break;
case right:LCD_disp_string(11,1,"RT");break;
case ok:LCD_disp_string(11,1,"OK");break;
default:KEY_VAL=' ';break;
}
key_code[2]=' ';
}
void oclockon()
{
uchar clock_flag[5];
uchar temp1,temp2,temp3;
temp1=I2cByteRead(0xd0,0x02); //时 24小时制
temp1&=0x3f;
temp2=BCD2HEX(temp1);
temp1=I2cByteRead(0xd0,0x01); //分
temp3=BCD2HEX(temp1);
uchar i;
for(i=0;i<5;i++)
{
if(temp2==oclock[i][0])
{
if(temp3==oclock[i][1])
{
if(clockoff[i]==1)
clock_flag[i]=1;
else clock_flag[i]=0;
}
else clock_flag[i]=0;
}
else clock_flag[i]=0;
}
clock_on=0;
for(i=0;i<5;i++)
{
if(clock_flag[i]==1)
clock_on=1;
}
}
#include"config.h"
uchar t;
/***********TA初始化*********/
void init_TA()
{
TACCTL0 = CCIE; // TACCR0 interrupt enabled
TACCR0 = 60000; //5ms中断一次
TACTL = TASSEL_2 + MC_1; // SMCLK, upmode
}
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
if(++t==200)
{
t=0;
dh11_read();
get_show_Temperature();
get_show_time();
oclockon();
}
if(clock_on==1)
P1OUT ^= 0x08;
}