#include<reg51.h>
#include<intrins.h>
sbit P2_0 = 0xA0; //此管脚控制第1位显示
sbit P2_1 = 0xA1; //此管脚控制第2位显示
sbit P2_2 = 0xA2; //此管脚控制第3位显示
sbit P2_3 = 0xA3;
sbit P2_7=0xA7;
sbit P3_6=0xB6;
#define uchar unsigned char
#define uint unsigned int
#define _nop() _nop_()
#define LED_OFF 10
#define SDA P2_7
#define SCL P3_6
bit ack;
uchar SZ;
uchar fuse;
uchar adder;
uchar adder1;
uchar date;
unsigned char LED_Tab[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0xff};
void Delay10ms(const unsigned char n) //函数调用需要2个指令周期
{
unsigned char i;
unsigned int j;
//for语句需要8个指令周期,(本开发板使用11.0592M晶振,每个指令周期1.0851微秒)
for (i = 0; i < n; i++)
{
j = 1305; //赋值语句需要2个指令周期
while (j--); //while语句7个指令周期
}
}
void STAR(void)
{
SCL = 0;
SCL = 1;
SDA = 1;
_nop_();
_nop_();
SDA = 0;
_nop_();
_nop_();
SCL = 0;
SDA = 1;
}
void STOP(void)
{
SCL = 0;
SDA = 0;
SCL = 1;
_nop_();
_nop_();
SDA = 1;
_nop_();
_nop_();
SCL = 0;
}
bit WDT(uchar c)
{
int i = 8;
do
{
SCL = 0;
if(c&0x80==0x80) SDA=1;
else
SDA=0;
c <<= 1;
SCL = 1;
}while(--i);
SCL = 0;
// 等待应答
SDA = 1; // For input direct
SCL = 1;
for ( i=5; i>0; i--)
{
if (SDA == 0)
{
SCL = 0;
return(0x01);
}
if(SDA==1)
{
SCL = 0;
return(0x00);
}
}
}
uchar RDT()
{
uchar i;
uchar retc;
retc=0;
SDA=1;
for(i=0;i<8;i++)
{
_nop_();
SCL=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
retc=retc<<1;
if(SDA==1)
retc=retc+1;
_nop_();
_nop_();
}
SCL=0;
_nop_();
_nop_();
return (retc);
}
void ACKS(bit a)
{
if(a==0)
SDA=0;
else
SDA=1;
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
}
bit send (uchar sla,uchar suba, uchar s)
{ uchar wit;
STAR();
wit=WDT(sla);
return(wit);
WDT(suba);
WDT(s);
if(ack==1)
{STOP();
return(0x01);
}
}
uchar receive(uint sla ,uint suba)
{
uchar c;
STAR();
WDT(sla);
if(ack==0)
return(0x01);
else
{
WDT(suba);
if(ack==0)
return(0x00);
else
{ STAR();
WDT(sla+1);
c=RDT();
SCL=0;
ACKS(1);
STOP();
return(c);
}
}
}
void LED_DisplayF(unsigned int num)
{
bit nonzero_before; //高位0标志,如果高位全为0不显示
unsigned char temp;
static unsigned char digit; //当前需要扫描显示的位
num = num%10000; //抛弃4位以上的高数位
if (digit == 0)
{
temp = num/1000; //得到千位数
P2_3 = 1; //关掉上个位
if (temp)
{
P0 = LED_Tab[temp]; //把千位数送上数据输出口
nonzero_before = 1; //设置标志位
}
else
{
P0 = LED_Tab[LED_OFF]; //千位为0不显示
}
P2_0 = 0; //选通千位数码管
digit++;
}
else if (digit == 1)
{
temp = (num%1000)/100; //得到百位数
P2_0 = 1;
if (temp)
{
P0 = LED_Tab[temp]; //把百位数送上数据输出口
nonzero_before = 1;
}
else if (nonzero_before) //千位不为0时,百位为0要显示
{
P0 = LED_Tab[temp];
}
else //千位为0
{
P0 = LED_Tab[LED_OFF];
}
P2_1 = 0;
digit++;
}
else if (digit == 2)
{
temp = ((num%1000)%100)/10; //得到十位数
P2_1 = 1;
if (temp)
{
P0 = LED_Tab[temp]; //把十位数送上数据输出口
nonzero_before = 1;
}
else if (nonzero_before) //千或百位或十位不为0时,十位为0要显示
{
P0 = LED_Tab[temp];
}
else //十位为0
{
P0 = LED_Tab[LED_OFF];
}
P2_2 = 0;
digit++;
}
else if (digit == 3)
{
temp = ((num%1000)%100)%10;
P2_2 = 1;
P0 = LED_Tab[temp]; //把个位数送上数据输出口,0要显示
P2_3 = 0;
digit = 0;
nonzero_before = 0;
}
}
main(void)
{ uchar anx;
adder= 0xa0;
adder1= 0x007f;
date=0x06;
anx=send (adder,adder1,date);
Delay10ms(1);
fuse=receive(adder,adder1);
while(1)
{
LED_DisplayF(anx);
}
}
还在调试中,只是每次写数据到I2C,SDAu=1没写进去一直没找到原因,求指点啊 |