单总线通讯学习的困扰,感觉比较难尤其是I2C总线。视频看了多遍,自己还是做不好
炼气士 2011-06-29 11:09:54 单总线学习对时间的要求太多了,学起来也比较费劲。视频反复的看,原理也反复的读。写出来的代码就是出不来结果。
sbit scl=P3^4;
sbit sda=P3^5;
sbit E=P2^2;
sbit RS=P2^0;
sbit RW=P2^1;
uchar devAddr=0x0a;
// I2C BUS AT24C08 地址为0xa0+0x00/0x01,写/读
uchar writeData=1;
uchar readData=0;
void delay8us()
{
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
}
// startbit
void start_bit()
{
scl = 1;
sda = 1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
sda = 0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
scl=0;
}
// stopbit
void stop_bit()
{
scl=1;
sda=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
sda=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
scl=0;
sda=0;
}
void ack_bit()
{
uint i;
scl=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
while(sda&&(i<200))
{
i++;
}
scl=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
void noAck_bit()
{
// uint i;
sda =1;
delay8us();
scl=1;
delay8us();
scl=0;
//while(!sda);
//接收停止
}
void write_byte_24c08(uchar dat)
{
uchar i;
scl=0;
_nop_();
for(i=0;i<8;i++)
{
if(dat&0x80)
sda=1;
else
sda=0;
dat<<=1;
delay8us();
scl=1;
delay8us();
scl=0;
delay8us();
}
sda=1;
delay8us();
}
void write_data_24c08(uchar romAddr,uchar dat)
{
start_bit();
write_byte_24c08(0xa0); //slave address
ack_bit(); // 等待从机发出应答信号
write_byte_24c08(romAddr); // 需要写入的地址
ack_bit();
write_byte_24c08(dat); // 写入数据
ack_bit();
stop_bit(); // 如果 需要对其他从机写,则不发停止,发起始信号
}
uchar read_byte_24c08()
{
uchar i,value;
scl=0;
delay8us();
sda=1;
delay8us();
for(i=0;i<8;i++)
{
scl=1;
delay8us();
value<<=1;
if(sda)
{
value++;
}
scl=0;
delay8us();
}
sda = 1;
scl = 0;
return value;
}
void read_24c08(uchar romAdd)
{
start_bit();
write_byte_24c08(0xa0); //写设备地址
ack_bit();
write_byte_24c08(romAdd); // 写要读取的寄存器地址
ack_bit();
start_bit();
write_byte_24c08(0xa1); // 功能为读
readData=read_byte_24c08();
noAck_bit();
stop_bit();
}
//--1602
void delay_50us(uint t)
{
uchar j;
for(;t>0;t--)
for(j=19;j>0;j--);
}
void write_com(uchar com)
{
RS = 0;
RW = 0;
P0 = com;
E = 0;
delay_50us(10);
E = 1;
delay_50us(20);
E = 0;
}
void init1602(void)
{
delay_50us(300);
write_com(0x38);
delay_50us(100);
write_com(0x38);
delay_50us(100);
write_com(0x38);
delay_50us(100);
write_com(0x38);
write_com(0x08);
write_com(0x01);
write_com(0x06);
write_com(0x0c);
}
void write_data(uchar dat)
{
RS = 1;
RW = 0;
P0 = dat;
E = 0;
delay_50us(10);
E = 1;
delay_50us(20);
E = 0;
}
void display()
{
//read = 0x31;
write_com(0x80);
//write_data('0');
write_data(readData+0x30);
}
void main()
{
scl=1;
sda=1; //初始化
init1602();
write_data_24c08(0x08,writeData);
delay_50us(20);
read_24c08(0x08);
while(1)
display();
}
1602的显示是好的,单总线的学习有什么经验可以借鉴不?