SDA_INPUT; //SDA變?yōu)檩斎肟?/div>
for(i= 0;i < 8;i++) //讀出8位(1個(gè)字節(jié))數(shù)據(jù)
{
Delayus(10);
SCL_OUTPUT; //SCL低,這時(shí)允許從I2C發(fā)送數(shù)據(jù)到SDA上
Delayus(10);
SCL_INPUT; //SCL高,準(zhǔn)備讀取SDA上的數(shù)據(jù)
Delayus(10);
dat<<= 1; //讀取的數(shù)據(jù)左移一位,從最高位讀起
if(SDA_INDATA)
{
dat++; //如果DSA為高,則讀取的數(shù)據(jù)加1
}
Delayus(10);
}
SCL_OUTPUT; //SCL拉低,準(zhǔn)備下一個(gè)數(shù)據(jù)變化
Delayus(10);
if(!ack) //
{
SDA_INPUT; //發(fā)送NACK
}
else
{
SDA_OUTPUT; //發(fā)送ACK
}
Delayus(10);
SCL_INPUT; //SCL高
Delayus(10);
SCL_OUTPUT; //SCL低
Delayus(10);
return(dat); //返回讀到的數(shù)據(jù)
}
//從固定地址讀一字節(jié)
unsigned charEEPROM_ReadByte(unsigned int add)
{
unsignedchar data;
I2C_Start(); //發(fā)送起始信號(hào)
I2C_WriteByte(EEPROM_BUS_ADDRESS | ((add>> 8) << 1));
//寫器件地址和頁(yè)地址的高3位
I2C_WriteByte(add); //寫頁(yè)地址的低4位和頁(yè)地址內(nèi)部偏移量
I2C_Start(); //發(fā)送起始信號(hào)
I2C_WriteByte(EEPROM_BUS_ADDRESS | 0x01); //發(fā)送讀命令
data= I2C_ReadByte(0); //讀一個(gè)字節(jié)
I2C_Stop(); //發(fā)送結(jié)束信號(hào)
returndata;
}
//向固定地址寫一字節(jié)
void EEPROM_WriteByte(unsignedint add,unsigned char data)
{
I2C_Start(); //發(fā)送起始信號(hào)
I2C_WriteByte(EEPROM_BUS_ADDRESS | ((add>> 8) << 1));
//寫器件地址和頁(yè)地址的高3位
I2C_WriteByte(add); //寫頁(yè)地址的低4位和頁(yè)地址內(nèi)部偏移量
I2C_WriteByte(data); //寫一個(gè)字節(jié)數(shù)據(jù)
I2C_Stop(); //發(fā)送結(jié)束信號(hào)
Delayms(10);
}
//us級(jí)別的延時(shí)函數(shù)
void Delayus(unsigned int lus)
{
while(lus--)
{
_delay_loop_2(3);
//_delay_loop_2(1)是延時(shí)4個(gè)時(shí)鐘周期,參數(shù)為3則延時(shí)12
//個(gè)時(shí)鐘周期,本實(shí)驗(yàn)用12M晶體,則12個(gè)時(shí)鐘周期為12/12=1us
}
}
//ms級(jí)別的延時(shí)函數(shù)
void Delayms(unsigned int lms)
{
while(lms--)
{
Delayus(1000); //延時(shí)1ms
}
}
9.2 基于硬件接口的AT24C02的讀寫實(shí)驗(yàn)
9.2.1、實(shí)例功能
AVR單片機(jī)提供了實(shí)現(xiàn)標(biāo)準(zhǔn)2先串行總線通信TWI(兼容I2C總線)硬件接口。其主要性能和特點(diǎn)有:
● 簡(jiǎn)單,但是強(qiáng)大而靈活的串行通信接口,只需要兩根線;
● 支持主機(jī)和從機(jī)操作;
● 器件可以作為發(fā)送器,也可以作為接收器;
● 7位地址空間,最大允許有128個(gè)從機(jī);
● 支持多主機(jī)模式;
● 最高可達(dá)400K的數(shù)據(jù)傳輸率;
● 全可編程的從機(jī)地址
● 地址監(jiān)聽中斷可以是AVR單片機(jī)從休眠狀態(tài)喚醒。
AVR的TWI是支持I2C通信的硬件接口,使用硬件接口的優(yōu)點(diǎn)是可以直接使用硬件接口完成I2C通信,而不必使用I/O口模擬I2C的時(shí)序。比軟件模擬要簡(jiǎn)單,代碼短,效率高。
本實(shí)例包括三個(gè)功能模塊,分別介紹如下:
● 單片機(jī)系統(tǒng):利用ATmega16單片機(jī)與AT24C16通信,實(shí)現(xiàn)數(shù)據(jù)的讀寫,并使用LED指示讀寫數(shù)據(jù)是否正確。
● 外圍電路:外圍電路分兩部分:LED顯示電路(實(shí)現(xiàn)指示讀寫數(shù)據(jù)是否正確)、AT24C16通信電路(實(shí)現(xiàn)對(duì)AT24C16的讀寫操作)。
● 軟件程序:編寫軟件,實(shí)現(xiàn)利用AVR的硬件I2C接口對(duì)AT24C16進(jìn)行數(shù)據(jù)讀寫數(shù)據(jù)功能。
通過本實(shí)例的學(xué)習(xí),掌握以下內(nèi)容:
● 理解AVR單片機(jī)硬件I2C接口的特點(diǎn)、原理。
● 掌握AVR單片機(jī)硬件I2C接口的控制時(shí)序和控制方法流程。
● 掌握使用查詢方法對(duì)AT24C16進(jìn)行操作的軟件編程。
9.2.2 器件和原理
上一示例中我們已經(jīng)對(duì)I2C總線的特點(diǎn)、原理進(jìn)行了了解,并且通過利用I/O口模擬I2C總線時(shí)序的方法實(shí)現(xiàn)對(duì)AT24C16的讀寫。
在本例中我們學(xué)習(xí)使用AVR提供的硬件I2C接口。
1、TWI模塊描述
AVR的TWI模塊由總線接口單元、比特率發(fā)生器、地址匹配單元和控制單元等模塊構(gòu)成。
● SDA和SCL引腳
SDA和SCL是AVR單片機(jī)TWI接口的引腳。引腳的輸出驅(qū)動(dòng)器包含一個(gè)波形斜率限制器,以滿足TWI規(guī)范;引腳的輸入部分包含尖峰抑制但愿,以去除小于50ns的毛刺。
●波特率發(fā)生器
TWI工作在主控器模式時(shí),又該控制單元產(chǎn)生TWI時(shí)鐘信號(hào),并驅(qū)動(dòng)時(shí)鐘線SCL,
●總線接口單元
這個(gè)單元包括:數(shù)據(jù)和地址移位寄存器、起始、停止信號(hào)控制和總線仲裁判定的硬件電路。
● 地址匹配單元
地址匹配單元將檢測(cè)總線上接收到的地址是否與TWAR寄存器中的7位地址相匹配。如果匹配成功,將通知控制單元轉(zhuǎn)入適當(dāng)?shù)牟僮鳡顟B(tài)。TWI可以響應(yīng),也可以不響應(yīng)主控器對(duì)其的尋址訪問。
● 控制單元
控制單元監(jiān)聽TWI總線,并根據(jù)TWI控制寄存器的設(shè)置作出相應(yīng)的響應(yīng)。
當(dāng)在TWI總線上產(chǎn)生需要應(yīng)用程序干預(yù)處理的事件時(shí),先對(duì)TWI的中斷標(biāo)志位TWINT進(jìn)行相應(yīng)設(shè)置,在下一個(gè)時(shí)鐘周期時(shí),將表示這個(gè)事件的狀態(tài)字寫入TWI狀態(tài)寄存器TWSR中。在其他情況下,TWSR中的內(nèi)容為一個(gè)表示無事件發(fā)生的狀態(tài)字。一旦TWINT標(biāo)志位置1,就會(huì)將時(shí)鐘線SCL拉低,暫停TWI總線上的傳送,讓用戶程序處理事件。
在下列事件出現(xiàn)時(shí),TWINT標(biāo)志位設(shè)為“1”:
● 在TWI傳送完一個(gè)起始或再次起始(START/RESTART)信號(hào)后;
● 在TWI傳送完一個(gè)主控器尋址讀/寫(SLA+R/W)數(shù)據(jù)后;
● 在TWI傳送完一個(gè)地址字節(jié)后;
● 在TWI丟失總線控制權(quán)后;
● 在TWI被主控器尋址(地址匹配成功)后;
● 在TWI接收到一個(gè)數(shù)據(jù)字節(jié)后;
● 在作為被控器時(shí),TWI接收到停止或再次起始信號(hào)后;
● 由于非法的起始或停止信號(hào)造成總線上的沖突出錯(cuò)時(shí)。
2、TWI寄存器
1)、波特率寄存器 TWBR
file:///C:/Users/m/AppData/Local/Temp/msohtmlclip1/01/clip_image016.jpg
TWBR用于設(shè)置波特率發(fā)生器的分頻因子,波特率發(fā)生器是一個(gè)頻率分頻器,當(dāng)工作在主控器模式下,它產(chǎn)生和提供SCL引腳上的時(shí)鐘信號(hào)。
在主機(jī)模式下,TWBR的值應(yīng)大于10,否則可能會(huì)產(chǎn)生不正確的輸出。尤其在中斷模式下,TWBR的值應(yīng)大于10。
2)、控制寄存器 TWCR
file:///C:/Users/m/AppData/Local/Temp/msohtmlclip1/01/clip_image018.jpg
TWCR用來控制TWI操作。例如使能TWI接口;在總線上加起始和終止信號(hào);產(chǎn)生ACK應(yīng)答等。
● 位7–TWINT:TWI中斷標(biāo)志位。當(dāng)TWI接口完成當(dāng)前工作并期待應(yīng)用程序響應(yīng)時(shí),該位被置位。如果全局中斷控制位和TWCR寄存器中的TWIE位都置位,則MCU將跳到TWI中斷向量處。一旦TWINT標(biāo)志位被置位,,時(shí)鐘線SCL將被拉位低。在執(zhí)行中斷服務(wù)程序時(shí),TWINT標(biāo)志位不會(huì)由硬件自動(dòng)清零,必須通過由軟件將該位寫為“1”來清零,清零TWINT標(biāo)志位將開始TWI接口的操作,因此對(duì)TWI寄存器TWAR、TWI狀態(tài)寄存器TWSR、TWI數(shù)據(jù)寄存器TWDR的訪問,必須在清零TWINT標(biāo)志位前完成。
● 位6—TWEA:TWI應(yīng)答(ACK)允許位。TWEA位控制應(yīng)答ACK信號(hào)的發(fā)生。如果TWEA位置1,則在器件作為主控器接收器時(shí),接收到一個(gè)數(shù)據(jù)字節(jié)時(shí), ACK脈沖將在TWI總線上發(fā)生。如果清零TWEA位,將使器件暫時(shí)虛擬地脫離TWI總線。
● 位5—TWSTA:TWI起始(START)信號(hào)狀態(tài)位。當(dāng)要將器件設(shè)置為串行總線上的主控器時(shí),須設(shè)置TWSTA位為1.TWI借口硬件將檢查總線是否空閑。如果總線空閑,將在總線上發(fā)送一個(gè)起始信號(hào);如果總線不空閑,則TWI將等待總線上一個(gè)停止信號(hào)被檢測(cè)后,再發(fā)出一個(gè)新的起始信號(hào),以獲得總線的控制權(quán)而成為主控器。當(dāng)起始信號(hào)發(fā)出后,硬件將自動(dòng)清零TWSTA位。
● 位4—TWSTO:TWI停止(STOP——信號(hào)狀態(tài)位。當(dāng)芯片工作在主控模式時(shí),設(shè)置TWSTO位為1,將在總線上產(chǎn)生一個(gè)終止信號(hào)。當(dāng)終止信號(hào)發(fā)出后,TWSTO位將被自動(dòng)清零。
● 位3—TWWC:TWI寫沖突標(biāo)志位。當(dāng)TWINT為0時(shí),試圖向TWI寫數(shù)據(jù),TWWC位將被置1;當(dāng)TWINT位為1時(shí),寫數(shù)據(jù)時(shí),TWWC由硬件自動(dòng)清零。
● 位2—TWEN:TWI允許位。TWEN用于使能TWI接口操作和激活TWI接口。該位置1,則TWI接口模塊將I/O引腳PC0、PC1轉(zhuǎn)換為SCL和SDA引腳。如果該位清零,則TWI模塊將被關(guān)閉,所有TWI傳輸將被終止,PC0、PC1轉(zhuǎn)換為普通I/O引腳。
● 位1—保留位。讀出總為0;
● 位0—TWIE:TWI中斷使能位。當(dāng)該位為1,并且全局終端也使能時(shí),只要TWINT標(biāo)志為1,TWI中斷請(qǐng)求就使能。
4)狀態(tài)寄存器 TWSR
file:///C:/Users/m/AppData/Local/Temp/msohtmlclip1/01/clip_image020.jpg
● 位【7:3】--TWS:TWI狀態(tài)位。這5位反映了TWI邏輯狀態(tài)和TWI總線的狀態(tài)。不同的狀態(tài)碼表示不同的操作狀態(tài),具體可查詢數(shù)據(jù)手冊(cè)獲得。注意,從TWSR寄存器中讀取的值包括了5位狀態(tài)值和2位預(yù)分頻值。因此,在檢查狀態(tài)位時(shí),應(yīng)該將預(yù)分頻器位屏蔽,使?fàn)顟B(tài)檢驗(yàn)與預(yù)分頻器無關(guān)。
● 位2—保留。讀出始終為0;
● 位【1:0】--TWPS:TWI預(yù)分頻器位。這些位能讀能寫,用于設(shè)置波特率的預(yù)分頻率。如下表所示。
file:///C:/Users/m/AppData/Local/Temp/msohtmlclip1/01/clip_image022.jpg
5)數(shù)據(jù)寄存器 TWDR
file:///C:/Users/m/AppData/Local/Temp/msohtmlclip1/01/clip_image024.jpg
在發(fā)送模式下,TWDR寄存器的內(nèi)容為下一個(gè)要傳送的字節(jié);在接受模式下,TWDR寄存器的內(nèi)容為最后接受的字節(jié)。當(dāng)TWI不處在字節(jié)移位操作過程時(shí),該寄存器可以被讀寫即當(dāng)TWI中斷標(biāo)志位置位時(shí),該寄存器可以被寫入。在第一次TWI中斷發(fā)生前,數(shù)據(jù)寄存器不能由用戶初始化。
6)(被控器)地址寄存器TWAR
file:///C:/Users/m/AppData/Local/Temp/msohtmlclip1/01/clip_image026.jpg
TWAR寄存器高7位的內(nèi)容為被控器的7位地址字。當(dāng)TWI設(shè)置為被控接收器或被控發(fā)送器時(shí),在TWAR中應(yīng)設(shè)置被控器尋址地址。而在主控器模式下,不需要設(shè)置TWAR。
9.2.3、電路連接
本例中的電路連接與上一實(shí)例完全相同,在此不再說明。
需要提醒的是,在AT24C16的接口電路中,我們?cè)陔娐钒迳显黾恿藘蓚(gè)上拉電阻,這兩個(gè)上拉電阻分別接在SCL和SDA引腳上。
9.2.4 利用硬件TWI接口實(shí)現(xiàn)I2C總線的讀寫
1、程序功能
程序的功能是使用單片機(jī)的硬件TWI接口實(shí)現(xiàn)I2C總線的讀寫操作,然后將讀出數(shù)據(jù)通過LED指示正確與否。硬件TWI接口可以使用查詢和中斷兩種方式實(shí)現(xiàn)I2C總線的讀寫,在本實(shí)例中我們使用查詢法實(shí)現(xiàn),下一實(shí)例中我們?cè)儆懻撌褂弥袛喾绞降牟僮鳌?/font>
2函數(shù)說明
本程序多個(gè)功能函數(shù),分別是:
● TWI硬件i2c總線操作相關(guān)函數(shù):
void I2C_Init(void); //I2C端口初始化
unsigned char I2C_Start(void); //發(fā)送起始信號(hào)
void I2C_Stop(void); //發(fā)送結(jié)束信號(hào)
unsigned char I2C_WriteByte(unsigned char dat); //寫一個(gè)字節(jié)
unsigned char I2C_ReadByte(unsigned char ack); //讀一個(gè)字節(jié)
unsigned char EEPROM_ReadByte(unsigned intadd); //從固定地址讀一字節(jié)
void EEPROM_WriteByte(unsigned intadd,unsigned char data); //向固定地址寫一字節(jié)
void EEPROM_ReadPage(unsigned intadd,unsigned char n,unsigned char *data);
//多字節(jié)讀操作
void EEPROM_WritePage(unsigned intadd,unsigned char n,unsigned char *data);
//多字節(jié)寫操作
● 延時(shí)相關(guān)函數(shù):
void Delayus(unsigned intlus); //us延時(shí)函數(shù)
void Delayms(unsigned int lms); //ms延時(shí)函數(shù)
由于WINAVR自帶函數(shù)庫(kù)中的延時(shí)函數(shù)使用起來很不方便,并且晶振頻率不同,延時(shí)時(shí)間也有區(qū)別,所以本實(shí)例中自己寫了兩個(gè)延時(shí)函數(shù)。
3、使用WINAVR開發(fā)環(huán)境,使用的是外部12M的晶振,所以需要將makefile文件中的時(shí)鐘頻率修改為12M。另外在程序燒錄到單片機(jī)的時(shí)候,熔絲位也要選擇為外部12M晶振(注意是晶振,不是外部振蕩器,一定不要選擇錯(cuò)了,否則會(huì)導(dǎo)致單片機(jī)不能再燒寫程序)。
4、程序說明
在本實(shí)例中我們不但實(shí)現(xiàn)了使用AVR單片機(jī)的硬件TWI接口,通過查詢方法實(shí)現(xiàn)了對(duì)AT24C16的讀寫,并且通過控制LED的亮滅來指示讀出的數(shù)據(jù)是否正確。
在程序中我們使用查詢法實(shí)現(xiàn)對(duì)AT24C16的讀寫,寫操作的具體步驟是:
1)TWI寄存器配置;
2)發(fā)送START信號(hào);
3)輪詢等待TWINT置位,TWINT置位表示START信號(hào)已發(fā)出;
4)發(fā)送寫器件地址,到TWDR寄存器,清零TWINT標(biāo)志位,等待TWINT再次置位,再次置位表示數(shù)據(jù)已發(fā)送完成;
5)讀取總線狀態(tài)是否是器件地址發(fā)送完成并收到ACK;
6)發(fā)送數(shù)據(jù)地址,并清零TWINT標(biāo)志位,然后等待TWINT再次置位,再次置位表示數(shù)據(jù)已發(fā)送完成;
7)讀取總線狀態(tài)是否是器件地址發(fā)送完成并收到ACK;
8)發(fā)送數(shù)據(jù)字節(jié),并清零TWINT標(biāo)志位,然后等待TWINT再次置位,再次置位表示數(shù)據(jù)已發(fā)送完成;
9)讀取總線狀態(tài)是否是器件地址發(fā)送完成并收到ACK;
10)數(shù)據(jù)寫操作結(jié)束,發(fā)送終止信號(hào)。
讀操作的具體步驟是:
1)TWI寄存器配置;
2)發(fā)送START信號(hào);
3)輪詢等待TWINT置位,TWINT置位表示START信號(hào)已發(fā)出;
4)發(fā)送寫器件地址,到TWDR寄存器,清零TWINT標(biāo)志位,等待TWINT再次置位,再次置位表示數(shù)據(jù)已發(fā)送完成;
5)讀取總線狀態(tài)是否是器件地址發(fā)送完成并收到ACK;
6)發(fā)送數(shù)據(jù)地址,并清零TWINT標(biāo)志位,然后等待TWINT再次置位,再次置位表示數(shù)據(jù)已發(fā)送完成;
7)讀取總線狀態(tài)是否是器件地址發(fā)送完成并收到ACK;
8)發(fā)送重復(fù)開始(RESTART)信號(hào),并清零TWINT標(biāo)志位,然后等待TWINT再次置位,再次置位表示發(fā)送重復(fù)開始信號(hào)完成;
9)發(fā)送讀數(shù)據(jù)信號(hào),并等待發(fā)送完成ACK,判斷總線狀態(tài)是否正確;
10)讀取TWDR的值,并根據(jù)是否讀取完最后一個(gè)字節(jié),發(fā)送ACK或NACK;
11)數(shù)據(jù)讀取完畢,發(fā)送終止信號(hào)。
5、程序代碼
由于本實(shí)例的程序量比較大,這里就不再列出了,直接放在附件里面。
9.3 使用中斷方法實(shí)現(xiàn)TWI總線的讀寫
9.3.1、實(shí)例功能
在前面的實(shí)例中我們分別學(xué)習(xí)了使用模擬I2C總線和硬件TWI接口實(shí)現(xiàn)對(duì)AT24C16的讀寫,這兩種方法都存在編程比較復(fù)雜,代碼執(zhí)行效率低等缺點(diǎn)。在本實(shí)例中我們將學(xué)習(xí)使用中斷方法實(shí)現(xiàn)對(duì)AT24C16的讀寫;中斷方法的優(yōu)點(diǎn)是執(zhí)行效率高,不占用CPU過多時(shí)間,從而使CPU能有更多的時(shí)間處理別的任務(wù),非常適合實(shí)時(shí)多任務(wù)系統(tǒng)中使用。
本實(shí)例包括三個(gè)功能模塊,分別介紹如下:
● 單片機(jī)系統(tǒng):利用ATmega16單片機(jī)的硬件TWI接口實(shí)現(xiàn)對(duì)AT24C16的讀寫,并將讀取出來的數(shù)據(jù)通過串口發(fā)送到計(jì)算機(jī),同時(shí)利用LED指示讀出的數(shù)據(jù)是否正確。
● 外圍電路:外圍電路分三部分:串口電路部分(實(shí)現(xiàn)將讀取的數(shù)值送到計(jì)算機(jī)的功能)、LED顯示電路(指示讀取的數(shù)據(jù)是否正確)、AT24C16接口電路(實(shí)現(xiàn)對(duì)AT24C16的讀寫)。
● 軟件程序:編寫軟件,實(shí)現(xiàn)使用中斷方法對(duì)AT24C16進(jìn)行數(shù)據(jù)的讀寫。
通過本實(shí)例的學(xué)習(xí),掌握以下內(nèi)容:
● 理解使用中斷方法實(shí)現(xiàn)TWI總線的接口設(shè)計(jì)方法和程序設(shè)計(jì)。
9.3.2、器件和原理
前面的實(shí)例中我們已經(jīng)了解了TWI總線的使用方法以及I2C總線的通信協(xié)議和操作時(shí)序,在此我們不再重復(fù)。
9.3.3、電路連接
本實(shí)例的電路由三部分:串口轉(zhuǎn)換電路、LED顯示電路、AT24C16接口電路。這些電路我們?cè)谇懊嬉呀?jīng)介紹過,在此不再說明。
需要提醒的是,在AT24C16的接口電路中,我們?cè)陔娐钒迳显黾恿藘蓚(gè)上拉電阻,這兩個(gè)上拉電阻分別接在SCL和SDA引腳上。
9.3.4 程序設(shè)計(jì)
1、程序功能
程序的功能是使用單片機(jī)的TWI硬件接口,實(shí)現(xiàn)在中斷方式下對(duì)AT24C16的讀寫,然后將讀出數(shù)據(jù)通過串口發(fā)送到計(jì)算機(jī),并且在電路板上通過LED的亮滅指示讀取的數(shù)據(jù)是否正確。
2函數(shù)說明
本程序多個(gè)功能函數(shù),分別是:
● 端口初始化函數(shù),設(shè)置各端口的初始工作狀態(tài)。
● 串口通信相關(guān)函數(shù):
void Usart_Init(void); //USART寄存器設(shè)置
void Usart_PutChar(unsigned charcTXData); //字節(jié)發(fā)送函數(shù)
這些函數(shù)已經(jīng)在前面的實(shí)例中做過介紹,在此不再重復(fù)。
● AT24C16操作相關(guān)函數(shù):
void I2C_Init(void); //I2C端口初始化
unsigned char EEPROM_ReadWrite(unsigned charI2C_Add,unsigned int add,
unsignedchar n,unsigned char *data);
//讀寫數(shù)據(jù)操作,參數(shù)分別是:器件地址,數(shù)據(jù)地址,數(shù)據(jù)長(zhǎng)度,讀寫的數(shù)據(jù)
● 延時(shí)相關(guān)函數(shù):
void Delayus(unsigned intlus); //us延時(shí)函數(shù)
void Delayms(unsigned intlms); //ms延時(shí)函數(shù)
由于WINAVR自帶函數(shù)庫(kù)中的延時(shí)函數(shù)使用起來很不方便,并且晶振頻率不同,延時(shí)時(shí)間也有區(qū)別,所以本實(shí)例中自己寫了兩個(gè)延時(shí)函數(shù)。
3、使用WINAVR開發(fā)環(huán)境,使用的是外部12M的晶振,所以需要將makefile文件中的時(shí)鐘頻率修改為12M。另外在程序燒錄到單片機(jī)的時(shí)候,熔絲位也要選擇為外部12M晶振(注意是晶振,不是外部振蕩器,一定不要選擇錯(cuò)了,否則會(huì)導(dǎo)致單片機(jī)不能再燒寫程序)。
4、程序說明
在本實(shí)例中我們不但實(shí)現(xiàn)了使用AVR單片機(jī)的硬件TWI接口,通過中斷方法實(shí)現(xiàn)了對(duì)AT24C16的讀寫,并且將讀出的數(shù)據(jù)通過串口發(fā)送到計(jì)算機(jī)進(jìn)行顯示,同時(shí)通過控制LED的亮滅來指示讀出的數(shù)據(jù)是否正確。
使用中斷方法的處理步驟和查詢法的步驟基本一致,不同之處在于在中斷方式下不用使程序在等待中斷標(biāo)志位置位時(shí)一直處于等待狀態(tài),而是在中斷標(biāo)志置位后自動(dòng)進(jìn)入中斷處理函數(shù)。