|
/*#include"reg51.h"
#define uchar unsigned char
#define uint unsigned int
sbit PWM=P1^0;
sbit DEC=P1^1;
sbit INC=P1^2;
sbit seg=P1^3;
sbit cp=P1^4;
sbit DAT=P1^5;
uint high;
bit stop;
uchar tab[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void delayms(uchar n)
{ uchar i,j,k;
for(i=0;i<n;i++)
for(j=0;j<100;j++)
for(k=0;k<5;k++);
}
void delay(uint N)
{ while(--N);
}
void writebyte_164(uchar Dat)
{ uchar temp,i;
temp=Dat;
for(i=0;i<8;i++)
{ cp=0;
if(temp&0x80) DAT=1;
else DAT=0;
cp=1;
temp<<=1;
}
}
void main()
{ PWM=0;
seg=0;
EX0=1;
IT0=1;
EA=1;
writebyte_164(tab[0]);
writebyte_164(tab[0]);
writebyte_164(tab[0]);
seg=1;
while(!stop);
while(1)
{ PWM=1;
delay(high);
PWM=0;
delay(300-high);
}
}
void int0()interrupt 0
{ PWM=0;
if(!stop) stop=1;
if(!DEC) high-=10;
if(!INC) high+=10;
seg=0;
writebyte_164(tab[high/2%10]);
writebyte_164(tab[high/2%100/10]|0x80);
writebyte_164(tab[high/2/100]);
seg=1;
delayms(255);
} */
#include"reg51.h"
#include"intrins.h" //_nop_();延時函數(shù)用
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit PWM=P1^0;
sbit DEC=P1^1;
sbit INC=P1^2;
sbit seg=P1^3;
sbit cp=P1^4;
sbit DAT=P1^5;
sbit sda=P2^0; //數(shù)據(jù)線
sbit scl=P2^1; //時鐘線
uint high;
bit flag;
uchar tab[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void delayms(uchar n)
{ uchar i,j,k;
for(i=0;i<n;i++)
for(j=0;j<100;j++)
for(k=0;k<5;k++);
}
void delay(uint N)
{ while(--N);
}
//**************************************************************************************************
//啟動(SCL為高,SDA由高變?yōu)榈褪且粋開始條件)
//**************************************************************************************************
void start()
{
sda=1; //數(shù)據(jù)線置高,
_nop_(); //延時
scl=1; //時鐘線置高
_nop_(); //延時
sda=0; //數(shù)據(jù)線置低,由高變低
_nop_(); //延時
scl=0; //時鐘線置低,準(zhǔn)備發(fā)送或接收數(shù)據(jù),總線進(jìn)入忙狀態(tài)(I2C總線在空閑狀態(tài)時,SDA與SCL均被置高)
_nop_(); //延時
}
//**************************************************************************************************
//停止(SCL為高,SDA由低變?yōu)楦呤且粋結(jié)束條件)
//**************************************************************************************************
void stop()
{
sda=0; //數(shù)據(jù)線置低
_nop_(); //延時
scl=1; //時鐘線置高
_nop_(); //延時
sda=1; //數(shù)據(jù)線置高,由低變高
_nop_(); //延時
}
//**************************************************************************************************
//檢測應(yīng)答(所有的地址和數(shù)據(jù)字都是以8bit,在第9個時鐘周期,從器件發(fā)出"0"信號來作為收到一個字的應(yīng)答信號)
//**************************************************************************************************
void checkACK() //主器件檢測從器件是否返回應(yīng)答
{
scl=1; //時鐘線置高
_nop_(); //延時
while(sda==1); //等待第9個時鐘周期器件發(fā)出的響應(yīng)信號"0"
scl=0; //時鐘線置低
_nop_(); //延時
}
//**************************************************************************************************
//發(fā)送應(yīng)答(發(fā)送方為主器件,接收方為從器件,控制器作為從器件接收完1數(shù)據(jù)時,發(fā)送應(yīng)答信號
//**************************************************************************************************
void sendACK(bit ACK)
{
if(ACK)sda=1; //如果i位為1則發(fā)送1,即發(fā)送"非應(yīng)答信號"
else sda=0; //如果i位為0則發(fā)送0,即發(fā)送"應(yīng)答信號"
scl=1; //時鐘線置高,給一個脈沖
_nop_(); //延時
scl=0; //時鐘線置低
_nop_(); //延時
}
//**************************************************************************************************
//寫一字節(jié)
//**************************************************************************************************
void send_byte(uchar date) //寫一個8位字
{
uchar i,temp; //定義局部變量
temp=date; //待發(fā)8位數(shù)據(jù)賦予temp
for(i=0;i<8;i++) //循環(huán)8次,每次寫入1位,從最高位開始發(fā)送
{
if(temp&0x80)sda=1; //如果temp最高位為1則發(fā)送1
else sda=0; //如果temp最高位為0則發(fā)送0
_nop_(); //延時
scl=1; //給一個脈沖,發(fā)送sda當(dāng)前這位數(shù)據(jù)
_nop_(); //延時,需大于4us(參考數(shù)據(jù)手冊時序圖)
_nop_();
_nop_();
_nop_();
_nop_();
scl=0; //時鐘線置低,準(zhǔn)備下一脈沖
_nop_(); //延時,需大于4.7us(參考數(shù)據(jù)手冊時序圖)
_nop_();
_nop_();
_nop_();
_nop_();
temp=temp<<1; //左移1位,準(zhǔn)備好下1位待發(fā)送的數(shù)據(jù)
}
checkACK(); //查詢是否返回應(yīng)答信號
}
//**************************************************************************************************
//讀一字節(jié)
//**************************************************************************************************
uchar receive_byte() //讀一個8位字
{
uchar i,temp; //定義局部變量
sda=1; //設(shè)置數(shù)據(jù)線為輸入
_nop_(); //延時
for(i=0;i<8;i++) //循環(huán)8次,每次讀取1位,從最高位開始接收
{
scl=1; //給一脈沖,準(zhǔn)備發(fā)送1位數(shù)據(jù)
_nop_(); //延時,需大于4us(參考數(shù)據(jù)手冊時序圖)
_nop_();
_nop_();
_nop_();
_nop_();
temp=(temp<<1)|sda; //讀取1位數(shù)據(jù),放在temp最低位
scl=0; //準(zhǔn)備給下1個脈沖
_nop_(); //延時,需大于4.7us(參考數(shù)據(jù)手冊時序圖)
_nop_();
_nop_();
_nop_();
_nop_();
}
return temp; //返回讀取的8位數(shù)據(jù)
}
//**************************************************************************************************
//向某I2C器件的某字地址寫一字節(jié)數(shù)據(jù)
//**************************************************************************************************
void write_word(uchar device_add,uchar word_add,uchar date) //寫進(jìn)去一個存儲數(shù)據(jù)
{
start(); //啟動
send_byte(device_add); //選擇從器件地址,RW位為0,即選擇寫命令
send_byte(word_add); //寫字地址
send_byte(date); //寫數(shù)據(jù)
stop(); //停止
}
//**************************************************************************************************
//向某I2C器件的某字地址讀一字節(jié)數(shù)據(jù)
//**************************************************************************************************
uchar read_word(uchar device_add,uchar word_add) //讀出一個存儲的數(shù)據(jù)
{
uchar date;
start(); //啟動
send_byte(device_add); //選擇從器件地址,RW位為0,即選擇寫命令
send_byte(word_add); //寫字地址
start(); //啟動
send_byte(device_add+1); //選擇從器件地址,RW位為1,即選擇讀命令
date=receive_byte(); //讀數(shù)據(jù)
sendACK(1); //發(fā)送非應(yīng)答信號
stop(); //停止
return date; //返回讀取結(jié)果數(shù)據(jù)
}
void writebyte_164(uchar Dat)
{ uchar temp,i;
temp=Dat;
for(i=0;i<8;i++)
{ cp=0;
if(temp&0x80) DAT=1;
else DAT=0;
cp=1;
temp<<=1;
}
}
void main()
{ PWM=0;
seg=0;
EX0=1;
IT0=1;
EA=1;
/* write_word(0xa0,0,0);
delayms(5); */
high=(uint)read_word(0xa0,0)*2;
writebyte_164(tab[high/2%10]);
writebyte_164(tab[high/2%100/10]|0x80);
writebyte_164(tab[high/2/100]);
seg=1;
if(high==0) while(!flag);
while(1)
{ PWM=1;
delay(high);
PWM=0;
delay(300-high);
}
}
void int0()interrupt 0
{ PWM=0;
if(!flag) flag=1;
if(!DEC) high-=10;
if(!INC) high+=10;
if(high>=300) high=290;
if(high<=0) high=10;
write_word(0xa0,0,(high/2));
seg=0;
writebyte_164(tab[high/2%10]);
writebyte_164(tab[high/2%100/10]|0x80);
writebyte_164(tab[high/2/100]);
seg=1;
delayms(255);
}
|
|