void delay(unsigned int ms){ //可變延時
while(ms--);
}
void i2cinit(void){ //IIC總線初始化
SCL=1;
delay(10);
SDA=1;
delay(10);
SCL=0;
delay(10);
SDA=0;
delay(10);
}
void i2cstart(void){ //開始信號
SDA=1;
delay(10);
SCL=1;
delay(10);
SDA=0;
delay(10);
SCL=0;
}
void i2cstop(void){ //停止信號
SCL=0;
SDA=0;
delay(10);
SCL=1;
delay(10);
SDA=1;
}
void i2cack(){ //IIC應答信號
SDA=0;
SCL=1;
delay(10);
SCL=0;
SDA=1;
}
bit testack(void){ //應答檢測
unsigned char errorbit=0;
SDA=1;
SCL=1;
delay(10);
errorbit=SDA;
SCL=0;
return(errorbit);
}
void i2csend(unsigned char i_data){ //IIC發送
unsigned char t;
for (t=0;t<8;t++){
SDA=(bit)(i_data&0x80); //強制類型轉換
SCL=1;
delay(10);
SCL=0;
i_data=i_data<<1;
}
}
unsigned char i2cread(void){ //讀一個字節
unsigned char t;
unsigned char i_data=0;
for(t=0;t<=7;t++){
SCL=1;
i_data=i_data*2;
i_data=i_data|((unsigned char)(SDA)); //強制類型轉換
SCL=0;
}
return i_data;
}
writei2c(unsigned char writedeviceadderss,unsigned char romadderss,
unsigned char i_data){ // 一個字節寫入i2c
stopread1307=0;
i2cstart();
i2csend(writedeviceadderss); //如果writedeviceadderss=0xa0是24C02地址,0xd0是1307的地址
if (testack()==1) return 0;
i2csend(romadderss); //romadderss是 數據 的存放地址
if (testack()==1) return 0;
i2csend(i_data); //i_data是要寫的數據
if (testack()==1) return 0;
i2cstop();
delay(10);
}
unsigned char readi2c(unsigned char writedeviceadderss,unsigned char readdeviceadderss,
unsigned char romadderss){ // 從i2c讀出一個字節
unsigned char i_data;
stopread1307=0;
i2cstart();
i2csend(writedeviceadderss); //如果writedeviceadderss=0xa0是24C02地址,0xd0是1307的地址
if (testack()==1)return 0;
i2csend(romadderss);
if (testack()==1)return 0;
i2cstart();
i2csend(readdeviceadderss); //如果readdeviceadderss=0xa1是24C02地址,0xd1是1307的地址
if (testack()==1)return 0;
i_data=i2cread();
i2cack();
i2cstop();
return i_data;
}
unsigned char readi2cbyte(unsigned char *idataaddress,unsigned char mdata,unsigned char writedeviceadderss,
unsigned char readdeviceadderss,unsigned char romadderss){ //連續讀多個字節
i2cstart();
i2csend(writedeviceadderss); //如果writedeviceadderss=0xa0是24C02地址,0xd0是1307的地址
if (testack()==1)return 0;
i2csend(romadderss);
if (testack()==1)return 0;
i2cstart();
i2csend(readdeviceadderss); //如果readdeviceadderss=0xa1是24C02地址,0xd1是1307的地址
if (testack()==1)return 0;
while(mdata!=0){
*idataaddress=i2cread();
i2cack();
idataaddress++;
mdata--;
}
i2cstop();
return idataaddress;
}
void up(void){ //加一 且燈ED1閃爍
EX0=0;
stopread1307=0;
PD=0x09;
PD=0x07;
delay(5000);
x++;
PD=0x06;
y=0x06;
stopread1307=1;
}
void down(void){ //減一 且燈ED2閃爍
EX0=0;
stopread1307=0;
PD=0x07;
PD=0x09;
delay(5000);
x--;
PD=0x08;
y=0x08;
stopread1307=1;
}
void ppromup(void){
writei2c(0xa0,0x0C,x);
}
void ppromdown(void){
writei2c(0xa0,0x23,x);
}
void pprom(void){
EX0=0;
stopread1307=0;
if (y==0x06) ppromup(); // 如果LED1亮存儲上限值
if (y==0x08) ppromdown(); // 如果LED2亮存儲下限值
}
unsigned char keyscan(void){
unsigned char key;
while(1)
{
if (PB!=0xff){
delay(2924);
if (PB!=0xff){
key=PB;
switch(key){
case 0xfe : return 0x01 ;break;
case 0xfd : return 0x02 ;break;
case 0xfb : return 0x03 ;break;
case 0xf7 : return 0x04 ;break;
case 0xef : return 0x05 ;break;
case 0xdf : return 0x06 ;break;
case 0xbf : return 0x07 ;break;
case 0x7f : return 0x08 ;break;
default : return 0xff;
}
}
}
return 0xff;
}
}
void Speaker(void) {
SpeakerP12=0;
delay(500);
SpeakerP12=1;
delay(500);
}
void ADCSTART(void) interrupt 0{
x=ADCIN;
ADCIN=0x00; //通道0
stopread1307=1;
}
void LCDINIT(){
delay(20000);
LCDD=0x38;
delay(50);
LCDD=0x0c;
delay(50);
LCDD=0x01;
delay(10);
}
void readup(void){ //讀上限
EX0=0;
stopread1307=0;
x=readi2c(0xa0,0xa1,0x0C);
m=x;
}
void readdown(void){ //讀下限
EX0=0;
stopread1307=0;
x=readi2c(0xa0,0xa1,0x23);
n=x;
}
void read1307(){
zfc[15]=(zfctemp[0]&0x0f)+0x30; //秒個位
zfc[14]=((zfctemp[0]>>4)&0x0f)+0x30; //秒十位
zfc[13]=':';
zfc[12]=(zfctemp[1]&0x0f)+0x30; //分個位
zfc[11]=((zfctemp[1]>>4)&0x0f)+0x30; //分十位
zfc[10]=':';
zfc[9]=(zfctemp[2]&0x0f)+0x30; //時個位
zfc[8]=((zfctemp[2]>>4)&0x0f)+0x30; //時十位
zfc[7]='/'; //星期
zfc[6]=(zfctemp[3]&0x0f)+0x30;
zfc[5]=(zfctemp[4]&0x0f)+0x30; //日個位
zfc[4]=((zfctemp[4]>>4)&0x0f)+0x30; //日十位
zfc[3]=(zfctemp[5]&0x0f)+0x30; //月個位
zfc[2]=((zfctemp[5]>>4)&0x0f)+0x30; //月十位
zfc[1]=(zfctemp[6]&0x0f)+0x30; //年個位
zfc[0]=((zfctemp[6]>>4)&0x0f)+0x30; //年十位
}
void LCDDISP(unsigned char *LCDdata){ //液晶顯示16個字符
unsigned char t;
for (t=0;t<16;t++){
if(t==0) {LCDD=0x80;delay(10);}
else if(t==8) {LCDD=0xc0;delay(10);}
if(*LCDdata!='\0'){
LCDRW=*LCDdata;
delay(100);
LCDdata++;
}
}
}
void disp(void) interrupt 1{ //數碼管顯示中斷服務子函數
TH0=0xC4; //定時器0初值裝載
TL0=0x00; //定時器0初值裝載
PA=smgd[sa];
PD=smgb[0];
delay(200);
PD=smgb[1];
PA=smgd[sb];
PD=smgb[2];
delay(200);
PD=smgb[3];
PA=smgd[sc];
PD=smgb[4];
delay(200);
PD=smgb[5];
}
void c8255init(void){ //8255初始化
PD=0x82;
PC=0xff;
PB=0xff;
PA=0Xff;
}
void SETDS1307(){
}
void main(void){ //主函數
i2cinit();
c8255init();
readup(); //上限初始化
readdown(); //下限初始化
x=0;
TMOD=0x01; //設置定時器0工作在方式1
TH0=0xC4; //定時器0初值裝載
TL0=0x00; //定時器0初值裝載
EA=1; //開CPU中斷
ET0=1; //開定時器0中斷
TR0=1; //啟動定時/計數器0
IT0=1;
EX0=1; //設置外部中斷觸發模式 電平觸發
ADCIN=0x00; //通道0啟動信號
LCDINIT();
writei2c(0xd0,0x00,0x00);
while(1){
sc=x%10;
sb=x%100/10;
sa=x/100;
if (((x>=m)|(x<=n))&(EX0==1)) {P1_5=0;Speaker();} else P1_5=1;
switch (keyscan()){
case 0x01: up();break; // 加1
case 0x02: down();break; // 減1
case 0x03: pprom();break; // 存儲,如果LED1亮存儲上限值,如果LED2亮存儲下限值
case 0x04: EX0=1;break; // 啟動ADC轉換
case 0x05: readup();break; // 讀取上限值
case 0x06: readdown();break; // 讀取下限值 //
case 0x07: SETDS1307();break; // 調整時間
case 0x08: x=0;break; // 清零
}
if (stopread1307==1) readi2cbyte(zfctemp,7,0xd0,0xd1,0x00); //從DS1307里連續讀出8個字節
read1307();
LCDDISP(zfc);
}
}
詳細資料聯系QQ:81748606