新唐 linux教程與M051 IIC使用程序
新唐M051單片機的 IIC使用的程序:#include "SmartM_M0.h"
#define DEBUGMSG printf
#define EEPROM_SLA 0xA0
#define EEPROM_WR 0x00
#define EEPROM_RD 0x01
#define I2C_CLOCK 13
#define PAGE_SIZE 8
/*****************************************
*函數(shù)名稱:Timed_Write_Cycle
*輸 入:無
*輸 出:無
*功 能:同步的寫周期
******************************************/
void Timed_Write_Cycle(void)
{
while (I2STATUS != 0x18)
{
//啟動
I2CON |= STA;
I2CON |= SI;
while ((I2CON & SI) != SI);
I2CON &= ((~STA) & (~SI));
//設備地址
I2DAT = EEPROM_SLA | EEPROM_WR;
I2CON |= SI;
while ((I2CON & SI) != SI);
}
if (I2STATUS != 0x18) //檢查應答
{
DEBUGMSG("Not ACK returned!");
}
//停止
I2CON |= STO;
I2CON |= SI;
while (I2CON & STO);
}
/*****************************************
*函數(shù)名稱:I2CInit
*輸 入:無
*輸 出:無
*功 能:I2C初始化
******************************************/
VOID I2CInit(VOID)
{
P3_PMD &= ~(Px4_PMD | Px5_PMD);
P3_PMD |= (Px4_OD | Px5_OD); //使能I2C0引腳
P3_MFP &= ~(P34_T0_I2CSDA | P35_T1_I2CSCL);
P3_MFP |= (I2CSDA | I2CSCL); //選擇P3.4,P3.5作為I2C0功能引腳
APBCLK |= I2C0_CLKEN; //使能I2C0時鐘
I2CLK = I2C_CLOCK;
I2CON |= ENSI; //使能I2C
}
/*****************************************
*函數(shù)名稱:AT24C0XWrite
*輸 入:unAddr 寫地址
pucData 寫數(shù)據(jù)
unLength 寫長度
*輸 出:TRUE/FALSE
*功 能:AT24C0X寫數(shù)據(jù)
******************************************/
BOOL AT24C0XWrite(UINT32 unAddr,UINT8 *pucData,UINT32 unLength)
{
UINT32 i;
I2CON |= STA; //啟動
I2CON |= SI;
while ((I2CON & SI) != SI);
I2CON &= ((~STA)&(~SI));
if (I2STATUS != 0x08)
{
DEBUGMSG("I2CStart fail,I2STATUS %02X
",I2STATUS);
return FALSE;
}
//進入讀寫控制操作
I2DAT = EEPROM_SLA | EEPROM_WR;
I2CON |= SI;
while ((I2CON & SI) != SI);
if (I2STATUS != 0x18)
{
DEBUGMSG("I2C write control fail
");
return FALSE;
}
//寫地址
I2DAT = unAddr;
I2CON |= SI;
while ((I2CON & SI) != SI);
if (I2STATUS != 0x28)
{
DEBUGMSG("I2C write addr fail
");
return FALSE;
}
//寫數(shù)據(jù)
for(i=0; i{
I2DAT = *(pucData+i);
I2CON |= SI;
while ((I2CON & SI) != SI);
if (I2STATUS != 0x28)
{
DEBUGMSG("I2C write data fail
");
return FALSE;
}
}
//停止
I2CON |= STO;
I2CON |= SI;
while (I2CON & STO);
//DEBUGMSG("I2C stop ok
");
Timed_Write_Cycle();
return TRUE;
}
/*****************************************
*函數(shù)名稱:AT24C0XRead
*輸 入:unAddr 讀地址
pucData 讀數(shù)據(jù)
unLength 讀長度
*輸 出:TRUE/FALSE
*功 能:AT24C0X讀數(shù)據(jù)
******************************************/
BOOL AT24C0XRead(UINT32 unAddr,UINT8 *pucData,UINT32 unLength)
{
UINT32 i;
I2CON |= STA; //啟動
I2CON |= SI;
while ((I2CON & SI) != SI);
I2CON &= ((~STA)&(~SI));
if (I2STATUS != 0x08)
{
DEBUGMSG("I2CStart fail,I2STATUS %02X
",I2STATUS);
return FALSE;
}
//進入讀寫控制操作
I2DAT = EEPROM_SLA | EEPROM_WR;
I2CON |= SI;
while ((I2CON & SI) != SI);
if (I2STATUS != 0x18)
{
DEBUGMSG("I2C write control fail
");
return FALSE;
}
//寫入讀地址
I2DAT = unAddr;
I2CON |= SI;
while ((I2CON & SI) != SI);
if (I2STATUS != 0x28)
{
DEBUGMSG("I2C write addr fail
");
return FALSE;
}
// 重新啟動
I2CON |= STA;
I2CON |= SI;
while ((I2CON & SI) != SI);
I2CON &= ((~STA)&(~SI));
if (I2STATUS != 0x10)
{
DEBUGMSG("I2C repeated start fail
");
return FALSE;
}
//進入讀操作
I2DAT = EEPROM_SLA | EEPROM_RD;
I2CON |= SI;
while ((I2CON & SI) != SI);
if (I2STATUS != 0x40)
{
DEBUGMSG("I2C write control fail
");
while (1);
}
//讀取數(shù)據(jù)
I2CON |= AA;
for(i=0; i{
I2CON |= SI;
while ((I2CON & SI) != SI);
if (I2STATUS != 0x50)
{
DEBUGMSG("I2C read fail
");
return FALSE;
}
*(pucData+i) = I2DAT;
}
//發(fā)送NACK到AT24C02,執(zhí)行斷開連接操作
I2CON &= (~AA);
I2CON |= SI;
while ((I2CON & SI) != SI);
//停止
I2CON |= STO;
I2CON |= SI;
while (I2CON & STO);
DEBUGMSG("I2C read ok
");
return TRUE;
}
VOID AT24C02ContinousWrite(UINT32 unAddr,UINT8 *pucData,UINT32 unLength)
{
UINT32 i,m,n;
UINT32 unCurWirteCount=0;
//if(unLength <= 32)
m = PAGE_SIZE-(unAddr % PAGE_SIZE); //與當前每頁32個字節(jié)已剩下多少個字節(jié)
if(unLength <= m)
{
AT24C0XWrite(unAddr,pucData,unLength);
}
else
{
AT24C0XWrite(unAddr,pucData,m);
unLength -=m;
unCurWirteCount+=m;
m = unLength/PAGE_SIZE;
n = unLength%PAGE_SIZE;
for(i=0; i{
AT24C0XWrite(unAddr+unCurWirteCount,pucData+unCurWirteCount,PAGE_SIZE);
unCurWirteCount += PAGE_SIZE;
}
AT24C0XWrite(unAddr+unCurWirteCount,pucData+unCurWirteCount,n);
}
}
/*****************************************
*函數(shù)名稱:main
*輸 入:無
*輸 出:無
*功 能:函數(shù)主體
******************************************/
INT32 main(VOID)
{
UINT8 i,buf[32];
Un_Lock_Reg(); //ISP下載時保護FLASH存儲器
PWRCON |= XTL12M_EN; //默認時鐘源為外部晶振
while((CLKSTATUS & XTL12M_STB) == 0); //等待12MHz時鐘穩(wěn)定
CLKSEL0 = (CLKSEL0 & (~HCLK)) | HCLK_12M; //設置外部晶振為系統(tǒng)時鐘
UartInit(12000000,9600); //波特率設置為9600bps
I2CInit();
DEBUGMSG("I2C Test
");
// while(1)
// {
for(i=0; i{
buf[i]=0x55;
}
DEBUGMSG("
AT24C0XWrite Test
");
AT24C0XWrite(0,buf,sizeof(buf)); //執(zhí)行寫操作
Delayms(500);
//==================================================
DEBUGMSG("AT24C0XRead Test
");
for(i=0; i{
buf[i]=0x00;
}
AT24C0XRead(0,buf,sizeof(buf)); //執(zhí)行讀操作
for(i=0; i<10; i++)
{
DEBUGMSG("%02X ",buf[i]); //打印讀取的數(shù)值
}
Delayms(500);
// }
while(1);
}
編輯:zzy 最后修改時間:2022-05-28