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