我用MSP430G2553的任意两个端口作为SCL,SDA进行IIC对24C02EEPOM的写入与写出。可是调试了好几天了,都没成功。大神快来看看吧!!!!
我把文件上传了,是TXT格式的,在IAR中打开调试。。。
/*用P.2--> SCL P1.3-->SDA
在其上面输入输出高低电位**************/
#include<msp430.h>
#include<msp430g2553.h>
#define SCL_H P1OUT|=BIT2
#define SCL_L P1OUT&=~BIT2
#define SDA_H P1OUT|=BIT3
#define SDA_L P1OUT&=~BIT3
#define uchar unsigned char
#define uint unsigned int
/*******************************************
函数名称:delay
功 能:延时约15us的时间
参 数:无
返回值 :无
********************************************/
void delay(void)
{
uchar i;
for(i=0;i<30;i++)//大约5uS延时
;
}
/*******************************************
函数名称:start
功 能:完成IIC的起始条件操作
参 数:无
返回值 :无
********************************************/
void start(void)
{
SCL_H; //起始状态是SCL和SDL上面的信号都为高
SDA_H;
delay();
SDA_L;//起始状态关键信号
delay();
SCL_L;
delay();
}
/*******************************************
函数名称:stop
功 能:完成IIC的结束条件操作
参 数:无
返回值 :无
********************************************/
void stop(void)
{
SCL_L;
SDA_L;
delay();
SCL_H;
delay();
SDA_H;//结束状态关键信号
delay();
}
/*******************************************
函数名称:ack_0
功 能:完成IIC的(写数据)成功判断条件操作,从24C02芯片发送一个0,
让主机即MSP430单片机进行判断
参 数:无
返回值 :无
********************************************/
void ack_0(void)
{
uint i=0;
SCL_L;
delay();
P1DIR&=~BIT3;//改变P1.3的端口状态,设置P1.3为输入端口
SCL_H;//时钟线为高电平,用于检测SDA的数值
delay();
while((P1IN&BIT3)&&(i<300))
i++;
return ;
}
/*******************************************
函数名称:Nack_1()
功 能:完成IIC的(读数据)成功判断条件操作,主机即MSP430单片机发送一个1,
让芯片24C02自己进行判断
参 数:无
返回值 :无
********************************************/
void Nack_1()
{
SCL_L;
SDA_L;
delay();
SDA_H;//给SDA线上发送一个高电平,让EEPOM自己去判断
delay();
SCL_H;
return;
}
/*******************************************
函数名称:write1byte()
功 能:向IIC总线发送一个字节的数据
参 数:wdata--发送的数据
返回值 :无
********************************************/
void write1byte(uchar date)
{
uchar i;
SCL_L;
for(i=8;i>0;i--)
{
SCL_L;
if(date&0x80)
{
SDA_H;
}
else
{
SDA_L;
}
delay();
SCL_H;
delay();
date<<=1;//将数据左移一位
}
return;
}
/*******************************************
函数名称:read1byte
功 能:从IIC总线读取一个字节
参 数:无
返回值 :读取的数据
********************************************/
uchar read1byte(void)
{
uchar read_data=0x00,i;
uchar flag;
for(i=0;i<8;i++)
{
SDA_H;
delay();
P1DIR&=~BIT3;
delay();
SCL_H;
delay();
flag=(P1IN&BIT3);//P1.3输入的值
read_data<<=1;
if(flag)
read_data|=0x01;
SCL_L;
delay();
}
P1DIR|=BIT3;
return read_data;
}
/*******************************************
函数名称:24C02write_byte()
功 能:通过IIC总线给24C02中写入数据
参 数:24C02要写的地址,要写入的数据
//24C02芯片共有255个字节,从0x00~0xff
返回值 :无
********************************************/
void _24C02write_byte(uchar adrr1,uchar number)
{
uchar adrress1=0xa0;//这个要看相应的要传芯片的地址和写入模式
start();
write1byte(adrress1);//发送从接收器的地址
ack_0();
write1byte(adrr1);//发送从接收器的某个地址开始写入
ack_0();
write1byte(number);//发送具体的数据
for(uint m=0;m<10000;m++)
{;}
ack_0();
stop();
}
/*******************************************
函数名称:24C02read_byte()
功 能:通过IIC总线将24C02中相应地址的数据读入单片机MSP430中
参 数:24C02要读出的地址//24C02芯片共有255个字节,从0x00~0xff
返回值 :有
*******************************************/
uchar _24C02read_byte(uchar adrr2)
{
uchar temp;
uchar adrress2=0xa0;//这个要看相应的要传芯片的地址和写入模式
start();
write1byte(adrress2);//控制字节,从接收器的地址
ack_0();
write1byte(adrr2);//发送地址字节
ack_0();
adrress2=0xa1;
start();
write1byte(adrress2);//控制字节,从接收器的模式
ack_0();
temp=read1byte();
for(uint q=0;q<10000;q++)
Nack_1();
stop();
return temp;
}
/*******************************************
主函数
*******************************************/
void main(void)
{
uchar adrr1=0x00;
uchar number=0x0f;
P2SEL=0x00;
P2DIR=0XFF;
P2OUT=0X1F;
_24C02write_byte(adrr1,number);
for(uint i=0;i<50000;i++)
{;}
P2OUT=_24C02read_byte(adrr1);
}
此帖出自
小平头技术问答
先说说你的ack_0. 等待从设备回ACK的时候是SCL等于低的时候,你都拉高了,才去读,显然有问题,而且你读完ack状态,退出函数的时候,SDA还是输入吧,然后你“ write1byte(adrr2);//发送地址字节”都没把SDA设置成输出,这能写出去吗。当然问题可能不仅仅有这些,你把协议好好捋一遍吧。
坛子里有模拟I2C的例程,你可以参考一下,我就发过一个449读时钟还是传感器的来着,当然,你自己能写出来最好,这样收获最大。
一周热门 更多>