|
最近在調(diào)試24c256,出了點(diǎn)問(wèn)題老是找不出毛病,就是對(duì)24C256寫數(shù)據(jù)的時(shí)候,前面有可能用得好好的,后面就突然數(shù)據(jù)開(kāi)始錯(cuò)位了
正常讀出來(lái)的數(shù)據(jù)應(yīng)該是這樣的:1803041000030028130161
但是出現(xiàn)問(wèn)題后讀出來(lái)的數(shù)據(jù)都是:
0627110546002812016100
0627110712000004000000
0627150724000004000000
(我是每次寫入16字節(jié)的數(shù)據(jù),前11個(gè)字節(jié)是有效,后5個(gè)是補(bǔ)零)
我每次只寫16個(gè)字節(jié)的數(shù)據(jù),寫入的間隔時(shí)間也不短,出問(wèn)題是應(yīng)該是地址錯(cuò)位了。
但是程序里面是沒(méi)有問(wèn)題的。所以想請(qǐng)問(wèn)大神們,有什么原因可能導(dǎo)致我出現(xiàn)這個(gè)問(wèn)題,謝謝
下面我貼下我的程序,請(qǐng)幫忙看下
這是main里使用的:
IIC_Transmit(0xA0,Wddr, &Savedata[0], 16);//往24C256寫入數(shù)據(jù)
Delayms(400);
下面是24c256的子程序:
**************************************************************************************************************************/
/*
********************************************************
函數(shù)名稱:void AT24C256_Init(void)
函數(shù)功能:初始化IO口
********************************************************
*/
void AT24C256_Init(void)
{
DDRE |= 0xC0;
PORTE |= 0xC0;
}
/*
********************************************************
函數(shù)名稱:static void IIC_delay(void)
函數(shù)功能:延時(shí)
********************************************************
*/
static void IIC_delay(void)
{
asm("nop");
}
/*
********************************************************
函數(shù)名稱:static void IIC_delay(void)
函數(shù)功能:主機(jī)發(fā)送開(kāi)始信號(hào)
********************************************************
*/
static void IIC_Start(void)
{
MODE_OUT;
SDA_H;
asm("nop");
SCL_H;
asm("nop");
asm("nop");
asm("nop");
SDA_L;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
SCL_L;
asm("nop");
asm("nop");
}
/*
********************************************************
函數(shù)名稱:static void IIC_Stop(void)
函數(shù)功能:主機(jī)發(fā)送結(jié)束信號(hào)
********************************************************
*/
static void IIC_Stop(void)
{
MODE_OUT;
SCL_L;
asm("nop");
asm("nop");
SDA_L;
asm("nop");
asm("nop");
SCL_H;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
SDA_H;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
}
/*
********************************************************
函數(shù)名稱: static unsigned char IIC_ACK_Check(void)
函數(shù)功能: 主機(jī)成功發(fā)送一個(gè)字節(jié)數(shù)據(jù)后,AT24C256會(huì)發(fā)送一
應(yīng)答信號(hào)。
返回值 : 1 沒(méi)有應(yīng)答信號(hào),即從機(jī)沒(méi)有成功接收到數(shù)據(jù)
0 有應(yīng)答信號(hào),即從機(jī)已接收到了數(shù)據(jù)
********************************************************
*/
static unsigned char IIC_ACK_Check(void)
{
unsigned char Bitmun;
MODE_IN;
SCL_L;
asm("nop");
asm("nop");
SDA_H;
asm("nop");
asm("nop");
SCL_H;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
Bitmun = PINE;
SCL_L;
asm("nop");
asm("nop");
Bitmun =(Bitmun >> 7)&0x01;
return Bitmun;
}
/*
********************************************************
函數(shù)名稱: static void IIC_NO_ACK(void)
函數(shù)功能: 主機(jī)發(fā)送一個(gè)字節(jié)數(shù)據(jù)后,
不會(huì)檢測(cè)從機(jī)的應(yīng)答信號(hào)
********************************************************
*/
static void IIC_NO_ACK(void)
{
MODE_OUT;
SCL_L;
asm("nop");
asm("nop");
SDA_H;
asm("nop");
asm("nop");
SCL_H;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
SCL_L;
asm("nop");
asm("nop");
}
/*
********************************************************
函數(shù)名稱: static void IIC_ACK_Creat(void)
函數(shù)功能: 主機(jī)向從機(jī)請(qǐng)求一個(gè)字節(jié)數(shù)據(jù)后,
發(fā)送應(yīng)答信號(hào),告訴從機(jī)繼續(xù)發(fā)送數(shù)據(jù)。(連讀讀模式)
********************************************************
*/
static void IIC_ACK_Creat(void)
{
MODE_OUT;
SCL_L;
asm("nop");
asm("nop");
SDA_L;
asm("nop");
asm("nop");
SCL_H;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
SCL_L;
asm("nop");
asm("nop");
}
/*
********************************************************
函數(shù)名稱: static void IIC_Send8Bit(unsigned char SendByte)
函數(shù)功能: 主機(jī)發(fā)送一個(gè)字節(jié)數(shù)據(jù)
********************************************************
*/
static void IIC_Send8Bit(unsigned char SendByte)
{
char counter;
MODE_OUT;
SDA_L;
asm("nop");
asm("nop");
asm("nop");
for (counter = 8; counter >0; counter--)
{
SCL_L;
asm("nop");
asm("nop");
if (SendByte & 0x80)
{
SDA_H;
asm("nop");
}
else
{
SDA_L;
asm("nop");
asm("nop");
}
SCL_H;
asm("nop");
SendByte = SendByte << 1;
}
SCL_L;
asm("nop");
asm("nop");
}
/*
********************************************************
函數(shù)名稱: static unsigned char IIC_Receive8Bit(void)
函數(shù)功能: 主機(jī)接收一個(gè)字節(jié)數(shù)據(jù)
********************************************************
*/
static unsigned char IIC_Receive8Bit(void)
{
char counter;
unsigned char ReceiveByte=0;
unsigned char IOstatus=0;
MODE_IN;
SCL_L;
asm("nop");
asm("nop");
SDA_H;
asm("nop");
asm("nop");
for (counter = 8; counter > 0; counter--)
{
SCL_L;
asm("nop");
asm("nop");
SCL_H;
asm("nop");
asm("nop");
IOstatus = PINE;
ReceiveByte = ReceiveByte<<1;
ReceiveByte |= (IOstatus >>7)& 0x01;
}
SCL_L;
return ReceiveByte;
}
/*
********************************************************
函數(shù)名稱: char IIC_Transmit(unsigned char lcv_device,unsigned int liv_addr,unsigned char *lcv_pdata, char counter)
函數(shù)功能: 主機(jī)往指定地址發(fā)送數(shù)據(jù)
unsigned char lcv_device 從機(jī)地址
unsigned int liv_addr 從機(jī)內(nèi)部存儲(chǔ)地址
unsigned char *lcv_pdata 發(fā)送數(shù)據(jù)緩存區(qū)
char counter 發(fā)送多少個(gè)數(shù)據(jù)
返回值 : 1 寫入數(shù)據(jù)失敗
0 寫入成功
注: AT24C256在連續(xù)讀寫過(guò)程中,會(huì)自動(dòng)增加地址,但是不會(huì)自動(dòng)跳轉(zhuǎn)到下一頁(yè),
所以要注意連續(xù)讀寫過(guò)程中不要超過(guò)頁(yè)的存儲(chǔ)空間,避免最先存儲(chǔ)的數(shù)據(jù)被覆蓋從而導(dǎo)致
數(shù)據(jù)丟失。
********************************************************
*/
char IIC_Transmit(unsigned char lcv_device,unsigned int liv_addr,unsigned char *lcv_pdata, char counter)
{
IIC_Start();
/* 發(fā)送從機(jī)地址 */
IIC_Send8Bit(lcv_device);
if ( IIC_ACK_Check() ) //調(diào)用函數(shù)char IIC_ACK_Check(void),沒(méi)有從機(jī)回應(yīng)則結(jié)束本次發(fā)送。
{
IIC_Stop();
return FAIL;
}
/* 發(fā)送內(nèi)存地址*/
IIC_Send8Bit((unsigned char)(liv_addr >> 8) & 0x0FF); //高八位
if ( IIC_ACK_Check()) //調(diào)用函數(shù)char IIC_ACK_Check(void),沒(méi)有從機(jī)回應(yīng)則結(jié)束本次發(fā)送。
{
IIC_Stop();
return FAIL;
}
IIC_Send8Bit((unsigned char)((liv_addr)&0x0FF)); //低八位
if ( IIC_ACK_Check()) //調(diào)用函數(shù)char IIC_ACK_Check(void),沒(méi)有從機(jī)回應(yīng)則結(jié)束本次發(fā)送。
{
IIC_Stop();
return FAIL;
}
/* 發(fā)送數(shù)據(jù) */
for(;counter > 0;counter-- )
{
IIC_Send8Bit(*lcv_pdata);
if ( IIC_ACK_Check()) //調(diào)用函數(shù)char IIC_ACK_Check(void),沒(méi)有從機(jī)回應(yīng)則結(jié)束本次發(fā)送。
{
IIC_Stop();
return FAIL;
}
lcv_pdata++;
}
IIC_Stop();
return SUCCEED;
}
/*
********************************************************
函數(shù)名稱 : char IIC_Receive(unsigned char lcv_device, unsigned int liv_addr, unsigned char *lcv_pdata, char counter)
函數(shù)功能 : 主機(jī)接收數(shù)據(jù)
unsigned char lcv_device 從機(jī)地址
unsigned int liv_addr 從機(jī)內(nèi)部存儲(chǔ)地址
unsigned char *lcv_pdata 發(fā)送數(shù)據(jù)緩存區(qū)
char counter 發(fā)送多少個(gè)數(shù)據(jù)
返回值 : 1 讀數(shù)據(jù)失敗
0 讀成功
注: AT24C256在連續(xù)讀寫過(guò)程中,會(huì)自動(dòng)增加地址,但是不會(huì)自動(dòng)跳轉(zhuǎn)到下一頁(yè),
所以要注意連續(xù)讀寫過(guò)程中不要超過(guò)頁(yè)的存儲(chǔ)空間,避免最先存儲(chǔ)的數(shù)據(jù)被覆蓋從而導(dǎo)致
數(shù)據(jù)丟失。
讀模式: 需要先配置為寫模式,然后才能改為讀模式
********************************************************
*/
char IIC_Receive(unsigned char lcv_device, unsigned int liv_addr, unsigned char *lcv_pdata, char counter)
{
/* 先將從機(jī)配置為寫模式 */
IIC_Start();
/* 發(fā)送從機(jī)地址 */
IIC_Send8Bit(lcv_device);
if ( IIC_ACK_Check())//調(diào)用函數(shù)char IIC_ACK_Check(void),沒(méi)有從機(jī)回應(yīng)則結(jié)束本次發(fā)送。
{
IIC_Stop();
return FAIL;
}
/* 發(fā)送內(nèi)存地址 */
IIC_Send8Bit((unsigned char)((liv_addr >> 8)&0x0FF));
if ( IIC_ACK_Check()) //調(diào)用函數(shù)char IIC_ACK_Check(void),沒(méi)有從機(jī)回應(yīng)則結(jié)束本次發(fā)送。
{
IIC_Stop();
return FAIL;
}
IIC_Send8Bit((unsigned char)((liv_addr)&0x0FF));
if ( IIC_ACK_Check()) //調(diào)用函數(shù)char IIC_ACK_Check(void),沒(méi)有從機(jī)回應(yīng)則結(jié)束本次發(fā)送。
{
IIC_Stop();
return FAIL;
}
/* 然后將從機(jī)配置為寫模式 */
IIC_Start();
/* 發(fā)送從機(jī)地址 */
IIC_Send8Bit(lcv_device+1);
if ( IIC_ACK_Check()) ////調(diào)用函數(shù)char IIC_ACK_Check(void),沒(méi)有從機(jī)回應(yīng)則結(jié)束本次發(fā)送。
{
IIC_Stop();
return FAIL;
}
for( ; counter > 0; )
{
*lcv_pdata = IIC_Receive8Bit();
counter--;
if ( counter >0)
{
IIC_ACK_Creat();
lcv_pdata++ ;
}
}
IIC_NO_ACK();
IIC_Stop();
return SUCCEED;
}
|
|