调了几天的存储芯片24C02,感觉程序上没有什么问题啊。可是程序总是卡在ACK()中的while里。不知道什么原因。望有经验的大神帮忙解决下。不胜感激。
#include "msp430x26x.h"
#define uchar unsigned char
#define uint unsigned int
#define TRUE 1
#define FALSE 0
#define CPU_F ((double)16000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
#define SDA_H P4OUT |=BIT5
#define SDA_L P4OUT &=~BIT5
#define SCL_H P4OUT |=BIT6
#define SCL_L P4OUT &=~BIT6
#define SDA_TRUE P4IN&BIT5
#define SDA_IN P4DIR &=~BIT5
#define SDA_OUT P4DIR |=BIT5
void AT24C02_Init() //初始化,需将时钟线和数据线拉高
{
P4DIR |=BIT5+BIT6; //AT24C02 SDA SCL
SDA_H;
SCL_H;
}
void AT24C02_START() //起始条件,SCL高电平时候,SDA的一个下降沿
{
SDA_OUT;
SDA_H;
delay_us(10);
SCL_H;
delay_us(10);
SDA_L;
delay_us(10);
SCL_L;
}
void AT24C02_STOP() //停止条件,SCL高电平时候,SDA的一个上升沿
{
SDA_OUT;
SDA_L;
delay_us(7);
SCL_H;
delay_us(7);
SDA_H;
delay_us(7);
}
void ACK()
{
//unsigned char i=0;
SDA_H;
delay_us(10);
SCL_H;
delay_us(10);
SDA_IN;
//while(SDA_TRUE&&(i<255)) i++;
while(SDA_TRUE);
SCL_L;
delay_us(10);
SDA_OUT;
}
void AT24C02_send_char(unsigned char data) //IIC协议要求从高位开始传送,传送1字节
{
unsigned char i=0;
SDA_OUT;
SCL_L; //此时,SCL被拉低,才允许SDA变化
SDA_H;
delay_us(5);
for(i=0;i<8;i++)
{
if(data&(0x80>>i))
SDA_H;
else
SDA_L;
SCL_H; //拉高SCL,不允许SDA变化
delay_us(10);
SCL_L;
delay_us(10); //拉低SCL,开始下1bit传送
}
SDA_H; //释放数据线
delay_us(5);
}
unsigned char AT24C02_receive_char()
{
//SCL低电平 SDA高电平
unsigned char temp=0,i=0;
SCL_L;
SDA_H;
SDA_IN;
for(i=0;i<8;i++)
{
SCL_H;
delay_ms(3);
if(SDA_TRUE)
temp=temp|(0x80>>i);
SCL_L;
delay_ms(2);
}
SDA_OUT;
return temp;
}
void AT24C02_write_byte(unsigned char address,unsigned char data)
{
AT24C02_START();
AT24C02_send_char(0xa0);
ACK();
AT24C02_send_char(address);
ACK();
AT24C02_send_char(data);
ACK();
AT24C02_STOP();
}
unsigned char AT24C02_read_byte(unsigned char address)
{
unsigned val=0;
AT24C02_START();
AT24C02_send_char(0xa0);
ACK();
AT24C02_send_char(address);
ACK();
AT24C02_START();
AT24C02_send_char(0xa1);
ACK();
val=AT24C02_receive_char();
AT24C02_STOP();
return val;
}
void main()
{
unsigned char r=0;
WDTCTL =WDTPW+WDTHOLD; //停止开门狗
CLK_Init();
AT24C02_Init();
AT24C02_write_byte(0x10,0x12);
Delay_ms(5);
r=AT24C02_read_byte(0x10);
while(1);
} |