主要是为了测试IIC总线方式的AT24c02基本读写测试,试了好几次,每次输出到串口的数据都是错误的,把数据输出到led灯也是一样,实在找不出错误。。
main.c的程序
#include "at24c02.h"
void Com_init(void)
{
TMOD = 0x20;
PCON = 0x00;
TH1 = 0xfd;
TL1 = 0xfd;
SCON = 0x40;
TR1 = 1;
}
void main(void)
{
uchar dat;
Com_init();
SCL = 1;
delay();
SDA = 1;
delay();
send_byte(0x00,0xf0);
dat = read_byte(0x00);
while(1)
{
SBUF = dat;
while(!TI);
TI = 0;
delay_1ms(1500);
}
}
at24c02.c的程序
#include "at24c02.h"
bit ack_bit = 0;
//-------------------仿真得出延时约为6.51US------------------------
void delay(void)
{
_nop_();
_nop_();
}
//-------------------非应答信号------------------------
void nack(void)
{
SCL = 0;
delay();
SDA = 1;
delay();
SCL = 1;
delay();
}
//-------------------1ms*del延时------------------------
void delay_1ms(uint del)
{
uint i,j;
for(i = 0; i < del; i++)
for(j = 0; j < 128; j++);
}
//---------------------start------------------------------
void start(void)
{
SDA = 1; //SCL高电平期间,SDA由高变低为起始信号
SCL = 1;
delay();
SDA = 0;
delay();
SCL = 0;
delay();
}
//---------------------stop------------------------------
void stop(void)
{
SDA = 0; //SCL高电平期间,SDA由低变高为停止信号
SCL = 1;
delay();
SDA = 1;
delay();
}
//---------------------send------------------------------
void send(uchar dat)
{
uchar i,temp;
temp = dat;
SCL = 0; //SCL拉底,数据可以改变
delay();
for(i = 0; i < 8; i++)
{
temp <<= 1; //temp左移一位
SDA = CY; //CY进位标志的值赋给SDA
delay();
SCL = 1;
delay();
SCL = 0;
delay();
}
SDA = 1; //释放SDA
delay();
SCL = 1; //高电平,等待应答信号
delay();
if(SDA == 1)
ack_bit = 1;
else
ack_bit = 0;
SDA = 1;
}
//---------------------read------------------------------
uchar read(void)
{
uchar i,dat,j;
SCL = 0; //拉底,为释放SDA做准备
delay();
SDA = 1; //释放SDA
delay();
for(i = 0; i < 8; i++)
{
SCL = 1; //高电平数据稳定
delay();
if(SDA == 1)
j = 1;
else
j = 0;
dat = dat | j;
delay();
SCL = 0; //拉底,为数据改变做准备
delay();
dat <<= 1; //每次左移1位
}
SDA = 1; //释放总线,等待MCU发送非应答信号
delay();
SCL = 1; //拉高,数据稳定
delay();
return dat; //返回dat值
}
//---------------------send_byte------------------------------
bit send_byte(uchar waddr,uchar dat) //waddr为子地址的首地址,dat为数据
{
start();
send(0xa0); //写器件地址,已经说明写位
if(ack_bit) return 0;
send(waddr); //写首地址
if(ack_bit) return 0;
send(dat); //写数据
if(ack_bit) return 0;
stop();
delay_1ms(10);
return 1;
}
//-------------------read_byte------------------------
uchar read_byte(uchar waddr)
{
uchar dat;
start();
send(0xa0); //伪写,目的是写入地址
if(ack_bit) return 0;
send(waddr); //写首地址
if(ack_bit) return 0;
start();
send(0xa1); //写器件地址,读
if(ack_bit) return 0;
dat = read(); //获取数据
nack();
stop();
delay_1ms(10);
return dat;
}
下面是串口输出的结果
|