关于51单片机IIC总线问题,AT24C02的使用!我想要写一个数据,然后再读出来!以下是我的代码与仿真图...
不知道在哪出了问题,总之仿真时就一直都是全亮,不管写什么数据都是这样,调试时发现并没有写入地址,望各位路过的大神帮帮忙,最好能帮我找出我的问题所在,当然如果各位有其他更好...
不知道在哪出了问题,总之仿真时就一直都是全亮,不管写什么数据都是这样,调试时发现并没有写入地址,望各位路过的大神帮帮忙,最好能帮我找出我的问题所在,当然如果各位有其他更好的方法,希望留下仿真图与代码,在下感激不尽,唯有将分数拉高,谢谢!!!
#include<reg52.h>
#include <intrins.h>
#define uchar unsigned char
sbit scl=P2^1;
sbit sda=P2^0;
uchar a;
void delay() //短延时
{
_nop_(); _nop_();
_nop_(); _nop_();
_nop_(); _nop_();
_nop_(); _nop_();
}
void start() //开始信号
{
sda = 1;
delay();
scl = 1;
delay();
sda = 0;
delay();
}
void stop() //停止
{
sda = 0;
delay();
scl = 1;
delay();
sda = 1;
delay();
}
void respons() //应答
{
uchar i;
scl = 1;
delay();
while((sda==1)&&(i<250))i++;
scl = 0;
delay();
}
void NoRespons()//不应答
{
sda=1;
delay();
scl=1;
delay();
scl=0;
delay();
}
void init()//初始化
{
sda = 1;
delay();
scl = 1;
delay();
}
void write_byte(uchar date)//写入
{
uchar i,temp;
temp = date;
for(i=0;i<8;i++)
{
temp = temp<<1;
scl = 0;
delay();
sda = CY;
delay();
scl = 1;
delay();
}
scl = 0;
delay();
sda = 1;
delay();
}
uchar read_byte()//读取
{
uchar i,k;
scl = 0;
delay();
sda = 1;
delay();
for(i=0;i<8;i++)
{
scl = 1;
delay();
k=(k<<1)|sda;
scl = 0;
delay();
}
return k;
}
void delay1(uchar x)//长延时
{
uchar a,b;
for(a=x;a>0;a--)
for(b=100;b>0;b--);
}
void write_add(uchar address,uchar date)//将一个数据写到IIC总线的过程
{
start(); //开始
write_byte(0xa0); //确定机器地址
respons(); //应答
write_byte(address); //确定将数据存储的地址
respons(); //应答
write_byte(date); //写数据
respons(); //应答
stop(); //停止
}
uchar read_add(uchar address) //读出一个数据的过程
{
uchar date;
start(); //开始
write_byte(0xa0); //确定 写 数据的机器地址
respons(); //应答
write_byte(address); //确定存储数据的地址
respons(); //应答
start(); //开始
write_byte(0xa1); //确定 读 数据的机器地址
respons(); //应答
date = read_byte(); //读取数据
NoRespons(); //不应答
stop(); //停止
return date; //返回读取的数据
}
void main()
{
init();
a = read_add(2); //读取地址为2的数据
if(a>=0xff) //如果开始读出的数出错,就从0开始
a = 0x00;
P1 = a; //把读到的数赋给P1
write_add(2,0xaa); //在地址为2的地方写数据
delay1(100); //延时
P1 = read_add(2); //读
while(1);
}
啊 展开
#include<reg52.h>
#include <intrins.h>
#define uchar unsigned char
sbit scl=P2^1;
sbit sda=P2^0;
uchar a;
void delay() //短延时
{
_nop_(); _nop_();
_nop_(); _nop_();
_nop_(); _nop_();
_nop_(); _nop_();
}
void start() //开始信号
{
sda = 1;
delay();
scl = 1;
delay();
sda = 0;
delay();
}
void stop() //停止
{
sda = 0;
delay();
scl = 1;
delay();
sda = 1;
delay();
}
void respons() //应答
{
uchar i;
scl = 1;
delay();
while((sda==1)&&(i<250))i++;
scl = 0;
delay();
}
void NoRespons()//不应答
{
sda=1;
delay();
scl=1;
delay();
scl=0;
delay();
}
void init()//初始化
{
sda = 1;
delay();
scl = 1;
delay();
}
void write_byte(uchar date)//写入
{
uchar i,temp;
temp = date;
for(i=0;i<8;i++)
{
temp = temp<<1;
scl = 0;
delay();
sda = CY;
delay();
scl = 1;
delay();
}
scl = 0;
delay();
sda = 1;
delay();
}
uchar read_byte()//读取
{
uchar i,k;
scl = 0;
delay();
sda = 1;
delay();
for(i=0;i<8;i++)
{
scl = 1;
delay();
k=(k<<1)|sda;
scl = 0;
delay();
}
return k;
}
void delay1(uchar x)//长延时
{
uchar a,b;
for(a=x;a>0;a--)
for(b=100;b>0;b--);
}
void write_add(uchar address,uchar date)//将一个数据写到IIC总线的过程
{
start(); //开始
write_byte(0xa0); //确定机器地址
respons(); //应答
write_byte(address); //确定将数据存储的地址
respons(); //应答
write_byte(date); //写数据
respons(); //应答
stop(); //停止
}
uchar read_add(uchar address) //读出一个数据的过程
{
uchar date;
start(); //开始
write_byte(0xa0); //确定 写 数据的机器地址
respons(); //应答
write_byte(address); //确定存储数据的地址
respons(); //应答
start(); //开始
write_byte(0xa1); //确定 读 数据的机器地址
respons(); //应答
date = read_byte(); //读取数据
NoRespons(); //不应答
stop(); //停止
return date; //返回读取的数据
}
void main()
{
init();
a = read_add(2); //读取地址为2的数据
if(a>=0xff) //如果开始读出的数出错,就从0开始
a = 0x00;
P1 = a; //把读到的数赋给P1
write_add(2,0xaa); //在地址为2的地方写数据
delay1(100); //延时
P1 = read_add(2); //读
while(1);
}
啊 展开
3个回答
展开全部
给你参考
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
sbit SCL=P2^0; //定义端口
sbit SDA=P2^1;
//*********************************************
//启动IIC总线程序
//*********************************************
void start(void)
{
SDA=1; //发送起始条件数据信号
_nop_();
SCL=1; //发送起始条件的时钟信号
_nop_();
_nop_();
_nop_();
_nop_();
_nop_(); //发送起始信号
SDA=0;
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
}
//*********************************************
//停止IIC总线程序
//*********************************************
void stop(void)
{ //发送停止条件的数据信号
SDA=0;
_nop_();
_nop_();
SCL=1; //发送停止条件的时钟信号
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA=1; //发送I2C总线停止信号
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
//*********************************************
//从机接收一位数据应答0
//*********************************************
void slave_0(void)
{
SDA=0;
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
_nop_();
SDA=1;
_nop_();
}
//*********************************************
//从机接收到最后一位数据应答1
//*********************************************
void slave_1(void)
{
SDA=1;
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
}
//*********************************************
// 延时子程序
//*********************************************
void delay(unsigned int N)
{
unsigned int i;
for(i = 0;i < N;i++);
}
//*********************************************
//从机应答位检子程序
//*********************************************
void check_ACK(void)
{
SCL=0;
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
while(SDA);
SCL=0;
}
//*********************************************
//发送一个字节子程序
//*********************************************
void write_byte(uchar ch)
{
uchar i, n=8; //向SDA发送一个字节数据,8位
for(i=0;i<n;i++)
{
if((ch&0x80)==0x80)
{ //若要发送的位为1,则SDA=1
SDA=1;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}
else //若要发送的位为0,则SDA=0
{
SDA=0;
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}
ch=ch<<1;
}
}
//*********************************************
//接收一个字节子程序
//*********************************************
uchar read_byte(void)
{
uchar n=8; //从SDA线上读一个字节,8位
uchar receive_data=0;
while(n--)
{
SDA=1;
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
receive_data=receive_data<<1; //左移一位
if(SDA==1)
{
receive_data=receive_data|0x01; //若接收到的位为1,则数据的最后一位置1
}
else
{
receive_data=receive_data&0xfe; //若接收到的位为0,则数据的最后一位为0
}
SCL=0;
}
return(receive_data);
}
//*********************************************
//向AT24C1024写入数据
//*********************************************
void write_1024(uchar send[])
{
int i;
start();
write_byte(0xa0); //启动总线
check_ACK(); //发送器件地址
write_byte(0x00); //发送器件片内高8位地址
check_ACK(); //检查从机是否应答
write_byte(0x00); //发送器件片内低8位地址
check_ACK();
for(i=0;i<16;i++) //写16个数
{ //将sind[]数组里面的数据写入AT24C1024
write_byte(send[i]);
check_ACK();
}
stop(); //停止总线
}
//*********************************************
//从AT24C1024读出数据
//*********************************************
void read_1024(uchar receive_data[])
{
uchar i;
start(); //启动总线
write_byte(0xa0); //发送器件地址
check_ACK(); //检查从机是否应答
write_byte(0x00); //发送器件片内高8位地址
check_ACK();
write_byte(0x00); //发送器件片内低8位地址
check_ACK();
start(); //再次启动总忂
write_byte(0xa1); //发读命令
check_ACK();
for(i=0;i<16;i++) //读16个数
{
receive_data[i]=read_byte(); //读出来的数据存到receivedata[]数组中
if(i==15) //是否读完,未读完全部数据,则应答0
slave_1();
else
slave_0();
} //停止总线
stop();
}
void main()
{
uchar send_data[16]={1,9,8,8,0,5,2,3,1,9,8,8,0,9,0,6};//要写入到AT24C1024数据
uchar receive_data[16]={0}; //存储从AT24C1024读出的数据
while(1)
{
delay(300); //延时等待蕊片复位
write_1024(send_data); //调用写AT24C1024程序
delay(1000); //AT24C1024写入延时
read_1024(receive_data); //调用读AT24C1024程序
}
}
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
sbit SCL=P2^0; //定义端口
sbit SDA=P2^1;
//*********************************************
//启动IIC总线程序
//*********************************************
void start(void)
{
SDA=1; //发送起始条件数据信号
_nop_();
SCL=1; //发送起始条件的时钟信号
_nop_();
_nop_();
_nop_();
_nop_();
_nop_(); //发送起始信号
SDA=0;
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
}
//*********************************************
//停止IIC总线程序
//*********************************************
void stop(void)
{ //发送停止条件的数据信号
SDA=0;
_nop_();
_nop_();
SCL=1; //发送停止条件的时钟信号
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA=1; //发送I2C总线停止信号
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
//*********************************************
//从机接收一位数据应答0
//*********************************************
void slave_0(void)
{
SDA=0;
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
_nop_();
SDA=1;
_nop_();
}
//*********************************************
//从机接收到最后一位数据应答1
//*********************************************
void slave_1(void)
{
SDA=1;
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
}
//*********************************************
// 延时子程序
//*********************************************
void delay(unsigned int N)
{
unsigned int i;
for(i = 0;i < N;i++);
}
//*********************************************
//从机应答位检子程序
//*********************************************
void check_ACK(void)
{
SCL=0;
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
while(SDA);
SCL=0;
}
//*********************************************
//发送一个字节子程序
//*********************************************
void write_byte(uchar ch)
{
uchar i, n=8; //向SDA发送一个字节数据,8位
for(i=0;i<n;i++)
{
if((ch&0x80)==0x80)
{ //若要发送的位为1,则SDA=1
SDA=1;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}
else //若要发送的位为0,则SDA=0
{
SDA=0;
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}
ch=ch<<1;
}
}
//*********************************************
//接收一个字节子程序
//*********************************************
uchar read_byte(void)
{
uchar n=8; //从SDA线上读一个字节,8位
uchar receive_data=0;
while(n--)
{
SDA=1;
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
receive_data=receive_data<<1; //左移一位
if(SDA==1)
{
receive_data=receive_data|0x01; //若接收到的位为1,则数据的最后一位置1
}
else
{
receive_data=receive_data&0xfe; //若接收到的位为0,则数据的最后一位为0
}
SCL=0;
}
return(receive_data);
}
//*********************************************
//向AT24C1024写入数据
//*********************************************
void write_1024(uchar send[])
{
int i;
start();
write_byte(0xa0); //启动总线
check_ACK(); //发送器件地址
write_byte(0x00); //发送器件片内高8位地址
check_ACK(); //检查从机是否应答
write_byte(0x00); //发送器件片内低8位地址
check_ACK();
for(i=0;i<16;i++) //写16个数
{ //将sind[]数组里面的数据写入AT24C1024
write_byte(send[i]);
check_ACK();
}
stop(); //停止总线
}
//*********************************************
//从AT24C1024读出数据
//*********************************************
void read_1024(uchar receive_data[])
{
uchar i;
start(); //启动总线
write_byte(0xa0); //发送器件地址
check_ACK(); //检查从机是否应答
write_byte(0x00); //发送器件片内高8位地址
check_ACK();
write_byte(0x00); //发送器件片内低8位地址
check_ACK();
start(); //再次启动总忂
write_byte(0xa1); //发读命令
check_ACK();
for(i=0;i<16;i++) //读16个数
{
receive_data[i]=read_byte(); //读出来的数据存到receivedata[]数组中
if(i==15) //是否读完,未读完全部数据,则应答0
slave_1();
else
slave_0();
} //停止总线
stop();
}
void main()
{
uchar send_data[16]={1,9,8,8,0,5,2,3,1,9,8,8,0,9,0,6};//要写入到AT24C1024数据
uchar receive_data[16]={0}; //存储从AT24C1024读出的数据
while(1)
{
delay(300); //延时等待蕊片复位
write_1024(send_data); //调用写AT24C1024程序
delay(1000); //AT24C1024写入延时
read_1024(receive_data); //调用读AT24C1024程序
}
}
更多追问追答
追问
感谢您的回答,希望您能将你的程序与proteus结合起来,给我一个仿真图,谢谢......
追答
参考下
展开全部
也许你的程序没有问题,仿真时将单片机的时钟频率设计低一点看看,比如12M,不行的话,1M试试。
追问
感谢您的回答,不过我用了一下1M的还是没用!哎,纠结了好多天,就是不知道为什么,如果您有做好了的程序与仿真图啊之类的,麻烦您发一下,有劳了....
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
邮箱?
追问
可以发我邮箱1057064438@qq.com,但如果可以的话,还是直接在知道里回答,以免今后有人犯跟我同样的错误,可以给别人一点启示...谢谢!!!
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询