日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]最近剛買回一塊AT24C256 EEPROM ,容量為32K Byte ,數(shù)據(jù)地址寬度為 16Bit ,支持IIC 1M (5V)400K (2.7V) 速度模式 ,利用AVR M16 片內(nèi)IIC 可以高速穩(wěn)定地讀取數(shù)據(jù)…… 爽! 經(jīng)過(guò)調(diào)試的,與各位大蝦分享分享。程序如

最近剛買回一塊AT24C256 EEPROM ,容量為32K Byte ,數(shù)據(jù)地址寬度為 16Bit ,支持IIC 1M (5V)400K (2.7V) 速度模式 ,利用AVR M16 片內(nèi)IIC 可以高速穩(wěn)定地讀取數(shù)據(jù)…… 爽! 經(jīng)過(guò)調(diào)試的,與各位大蝦分享分享。




程序如下:(winavr)

#include
#include
#include
#include
#define FREQ 8
#include
#include
#include

#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
//管腳定義
#define pinSCL 0 //PC0 SCL
#define pinSDA 1 //PC1 SDA
//為保險(xiǎn)起見,最好在SCL/SDA接上1~10K的外部上拉電阻到VCC。

#define fSCL 1000000 //TWI時(shí)鐘為1000KHz
//預(yù)分頻系數(shù)=1(TWPS=0)
#if F_CPU < fSCL*36
#define TWBR_SET 2; //TWBR必須大于等于10
#else
#define TWBR_SET (F_CPU/fSCL-16)/2; //計(jì)算TWBR值
#endif

#define TW_ACT (1<//TWCR只能IN/OUT,直接賦值比邏輯運(yùn)算(|= &=)更節(jié)省空間

#define SLA_24CXX 0xA0 //24Cxx系列的廠商器件地址(高四位)
#define ADDR_24C256 0x00
// AT24C256的地址線A2/1/0全部接地,SLAW=0xA0+0x00<<1+0x00,SLAR=0xA0+0x00<<1+0x01

//TWI_操作狀態(tài)
#define TW_BUSY 0
#define TW_OK 1
#define TW_FAIL 2
//TWI_讀寫命令狀態(tài)
#define OP_BUSY 0
#define OP_RUN 1


//TWI讀寫操作公共步驟
#define ST_FAIL 0 //出錯(cuò)狀態(tài)
#define ST_START 1 //START狀態(tài)檢查
#define ST_SLAW 2 //SLAW狀態(tài)檢查
#define ST_WADDR_H 3 //ADDR狀態(tài)檢查
#define ST_WADDR_L 4 //ADDR狀態(tài)檢查
//TWI讀操作步驟
#define ST_RESTART 5 //RESTART狀態(tài)檢查
#define ST_SLAR 6 //SLAR狀態(tài)檢查
#define ST_RDATA 7 //讀取數(shù)據(jù)狀態(tài)檢查,循環(huán)n字節(jié)
//TWI寫操作步驟
#define ST_WDATA 8 //寫數(shù)據(jù)狀態(tài)檢查,循環(huán)n字節(jié)

#define FAIL_MAX 1 //重試次數(shù)最大值

void delay_nms(uint ms)//若干毫秒延時(shí)
{
int i;
for(i=0;i{
_delay_loop_2(FREQ*250);
}
}

unsigned char TWI_RW(unsigned char sla,unsigned int addr,unsigned char *ptr,unsigned int len);

unsigned char BUFFER[256]; //緩沖區(qū)
void Test(void);

struct str_TWI //TWI數(shù)據(jù)結(jié)構(gòu)
{
volatile unsigned char STATUS; //TWI_操作狀態(tài)
unsigned char SLA; //從設(shè)備的器件地址
unsigned char ADDR_H; //從設(shè)備的數(shù)據(jù)地址
unsigned char ADDR_L; //從設(shè)備的數(shù)據(jù)地址
unsigned char *pBUF; //數(shù)據(jù)緩沖區(qū)指針
unsigned int DATALEN; //數(shù)據(jù)長(zhǎng)度
unsigned char STATE; //TWI讀寫操作步驟
unsigned char FAILCNT; //失敗重試次數(shù)
};

struct str_TWI strTWI; //TWI的數(shù)據(jù)結(jié)構(gòu)變量

//AT24C256的讀寫函數(shù)(包括隨機(jī)讀,連續(xù)讀,字節(jié)寫,頁(yè)寫)
//根據(jù)sla的最低位決定(由中斷程序中判斷)
//bit0=1 TW_READ 讀
//bit0=0 TW_WRITE 寫
// sla 器件地址(不能搞錯(cuò))
// addr EEPROM地址(0~32767)
// *ptr 讀寫數(shù)據(jù)緩沖區(qū)
// len 讀數(shù)據(jù)長(zhǎng)度(1~32768),寫數(shù)據(jù)長(zhǎng)度(1 or 8 or 16 or 32 or 64)
// 返回值 是否能執(zhí)行當(dāng)前操作
unsigned char TWI_RW(unsigned char sla,unsigned int addr,unsigned char *ptr,unsigned int len)
{
// unsigned char i;
if (strTWI.STATUS==TW_BUSY)
{//TWI忙,不能進(jìn)行操作
return OP_BUSY;
}
strTWI.STATUS=TW_BUSY;
strTWI.SLA=sla;
strTWI.ADDR_H=(unsigned char)((addr>>8)&0xff);
strTWI.ADDR_L=(unsigned char)(addr&0xff);
strTWI.pBUF=ptr;
strTWI.DATALEN=len;
strTWI.STATE=ST_START;
strTWI.FAILCNT=0;
TWCR=(1< return OP_RUN;
}

SIGNAL(SIG_2WIRE_SERIAL)
{//IIC中斷
unsigned char action,state,status;
action=strTWI.SLA&TW_READ; //取操作模式
state=strTWI.STATE;
status=TWSR&0xF8; //屏蔽預(yù)分頻位
if ((status>=0x60)||(status==0x00))
{//總線錯(cuò)誤或從機(jī)模式引發(fā)的中斷,不予處理
return;
}
switch(state)
{
case ST_START: //START狀態(tài)檢查
if(status==TW_START)
{//發(fā)送start信號(hào)成功
TWDR=strTWI.SLA&0xFE; //發(fā)送器件地址寫SLAW
TWCR=TW_ACT; //觸發(fā)下一步動(dòng)作,同時(shí)清start發(fā)送標(biāo)志
}
else
{//發(fā)送start信號(hào)出錯(cuò)
state=ST_FAIL;
}
break;
case ST_SLAW: //SLAW狀態(tài)檢查
if(status==TW_MT_SLA_ACK)
{//發(fā)送器件高位地址成功
TWDR=strTWI.ADDR_H; //發(fā)送eeprom地址
TWCR=TW_ACT; //觸發(fā)下一步動(dòng)作
}
else
{//發(fā)送器件地址出錯(cuò)
state=ST_FAIL;
}
break;
case ST_WADDR_H: //ADDR狀態(tài)檢查
if(status==TW_MT_DATA_ACK)
{//發(fā)送器件低位地址成功
TWDR=strTWI.ADDR_L; //發(fā)送eeprom地址
TWCR=TW_ACT; //觸發(fā)下一步動(dòng)作
}
else
{//發(fā)送器件地址出錯(cuò)
state=ST_FAIL;
}
break;
case ST_WADDR_L: //ADDR狀態(tài)檢查
if(status==TW_MT_DATA_ACK)
{//發(fā)送eeprom地址成功
if (action==TW_READ)
{//讀操作模式
TWCR=(1< }
else
{//寫操作模式
TWDR=*strTWI.pBUF++; //寫第一個(gè)字節(jié)
strTWI.DATALEN--;
state=ST_WDATA-1; //下一步將跳到WDATA分支
TWCR=TW_ACT; //觸發(fā)下一步動(dòng)作
}
}
else
{//發(fā)送eeprom地址出錯(cuò)
state=ST_FAIL;
}
break;
case ST_RESTART: //RESTART狀態(tài)檢查,只有讀操作模式才能跳到這里
if(status==TW_REP_START)
{//發(fā)送restart信號(hào)成功
TWDR=strTWI.SLA; //發(fā)器件地址讀SLAR
TWCR=TW_ACT; //觸發(fā)下一步動(dòng)作,同時(shí)清start發(fā)送標(biāo)志
}
else
{//重發(fā)start信號(hào)出錯(cuò)
state=ST_FAIL;
}
break;
case ST_SLAR: //SLAR狀態(tài)檢查,只有讀操作模式才能跳到這里
if(status==TW_MR_SLA_ACK)
{//發(fā)送器件地址成功
if (strTWI.DATALEN--)
{//多個(gè)數(shù)據(jù)
TWCR=(1< }
else
{//只有一個(gè)數(shù)據(jù)
TWCR=TW_ACT; //設(shè)定NAK,觸發(fā)下一步動(dòng)作
}
}
else
{//發(fā)送器件地址出錯(cuò)
state=ST_FAIL;
}
break;
case ST_RDATA: //讀取數(shù)據(jù)狀態(tài)檢查,只有讀操作模式才能跳到這里
state--; //循環(huán),直到讀完指定長(zhǎng)度數(shù)據(jù)
if(status==TW_MR_DATA_ACK)
{//讀取數(shù)據(jù)成功,但不是最后一個(gè)數(shù)據(jù)
*strTWI.pBUF++=TWDR;
if (strTWI.DATALEN--)
{//還有多個(gè)數(shù)據(jù)
TWCR=(1< }
else
{//準(zhǔn)備讀最后一個(gè)數(shù)據(jù)
TWCR=TW_ACT; //設(shè)定NAK,觸發(fā)下一步動(dòng)作
}
}
else if(status==TW_MR_DATA_NACK)
{//已經(jīng)讀完最后一個(gè)數(shù)據(jù)
*strTWI.pBUF++=TWDR;
TWCR=(1< strTWI.STATUS=TW_OK;
}
else
{//讀取數(shù)據(jù)出錯(cuò)
state=ST_FAIL;
}
break;
case ST_WDATA: //寫數(shù)據(jù)狀態(tài)檢查,只有寫操作模式才能跳到這里
state--; //循環(huán),直到寫完指定長(zhǎng)度數(shù)據(jù)
if(status==TW_MT_DATA_ACK)
{//寫數(shù)據(jù)成功
if (strTWI.DATALEN)
{//還要寫
TWDR=*strTWI.pBUF++;
strTWI.DATALEN--;
TWCR=TW_ACT; //觸發(fā)下一步動(dòng)作
}
else
{//寫夠了
TWCR=(1< strTWI.STATUS=TW_OK;
//啟動(dòng)寫命令后需要10ms(最大)的編程時(shí)間才能真正的把數(shù)據(jù)記錄下來(lái)
//編程期間器件不響應(yīng)任何命令
}
}
else
{//寫數(shù)據(jù)失敗
state=ST_FAIL;
}
break;
default:
//錯(cuò)誤狀態(tài)
state=ST_FAIL;
break;
}

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除( 郵箱:macysun@21ic.com )。
換一批
延伸閱讀
關(guān)閉