|
分享該例程是因為雖然網上已經有很多關于at24c芯片的讀寫程序,可是我在不停查資料的情況下還是用了十天時間才把程序調通。查到的每個資料都對我有幫助,但仍不夠用。考慮到其它新人或者會遇到同樣的情況,決定把程序分享出來,希望對初學者有所幫助。
關于芯片的接法,只說三點,一個是寫保護口wp,可以接在一個IO口上,寫芯片前要拉低,如果不希望芯片內容被改變,就拉高。第二個是A1腳,也就是芯片的2腳。這是器件的地址選擇腳,可以接VCC或地,對應器件地址不同,我的程序中是直接接地。有資料說該腳懸空與接地等效,我偷懶就沒接。結果不穩定。所以最后還是接地了。第三是SCL與SDA線應接上拉電阻。我偷懶沒接。把stc32g12k128內置的上拉電阻打開了,語句是P1PU=0x30;
本例程提供了四個讀寫at24c1024的函數,下面分別介紹:
一、頁寫函數
void Page_Write(unsigned char addr,unsigned char SLAW) /* WordAddress,First Data Address,Byte lenth */
功能:向at24c1024寫入一頁數據
參數1:SLAW-器件地址加頁地址首位(P0);在A1腳接地時,常用的是兩個值,0xa0和0xa2,分別表示芯片的前256頁和后256頁
參數2:addr-器件的頁地址,與參數1共同決定數據寫入的位置,取值0-255間.
這個函數很簡潔好用,只是它在寫入時要占用最前面的兩個字節,分別寫入的是上述兩個參數值。在寫入相對獨立的數據,很方便,但寫入大批量數據時,因每頁插入了兩個字節。所以讀出時多了點麻煩。
這個函數還有一個優點,是使用了IIC-DMA功能,運行時占用mcu時間少。有利提高mcu使用效率。
二、隨機寫函數
void WriteNbyte(unsigned int addr, unsigned char *p, unsigned int number,unsigned char SLAW) //
功能:向at24c1024指定地址寫入數據。
參數1:SLAW-與上一個函數相同,器件地址加頁地址首位(P0);在A1腳接地時,常用的是兩個值,0xa0和0xa2,分別表示芯片的前256頁和后256頁
參數2:addr-這是個16位地址,高位是頁地址,與前面的相同,低位是字節地址。這使得該函數能在任意位置寫入內容。靈活方便。
參數3:number-寫入字節數,如果前面的字節地址是0的話,number最大可以是256.如果字節地址不是0,則number一般設的小與256,例字節地址是0x09(addr的低位),則number最大可以是246,如果超過這個數值,則地址到255后,寫入的數據不是依次后延存儲,而是反回本頁地址0處開始存放。并依次向后存儲。這不方便提取,也容易覆蓋其它數據。(就是說芯片的地址指針不會自動跨頁)
參數4:p-這是緩沖區地址,在本例程中。寫數據緩沖區使用的DmaTxBuffer[256],大了沒用。在前面的頁寫函數中也需要用到這個緩沖區,只是默認是它。沒有當參數寫出來。
三、隨機讀函數
void ReadNbyte(unsigned int addr, unsigned char *p, unsigned int number,unsigned char SLAW)
功能:讀取指定地址處的數據
參數1:SLAW-與前面的函數相同,表示芯片地址和區地址(分辨前256和后156頁)
參數2:addr-字節地址,16位的,與SLAW里的p0值共同決定要讀的字節的具體地址
參數3:number-本次讀取的字節數,在讀取數據時芯片的內部地址指針能不能自動跨頁我沒有試過。權當不能跨頁使用,就是說每次調用讀函數,讀取的數據不超過256,原理與寫函數類似。
參數4:p-讀緩沖區,本例程中用DmaRxBuffer[6400],雖然每次調用讀函數,讀取的數據不超過256字節,但在循環語句調用讀函數時,如果緩沖區指針不復位,則可以繼續依次向后存放讀出的數據。所以我用了一個很大的緩沖區。減少向屏傳送數據的次數。
四、使用IIC-DMA的讀函數
void read_iicbydma(unsigned int addr,unsigned int number,unsigned char *p,unsigned char SLAW)
這個函數的功能與參數與上一個相同,不做重復說明了。寫這個函數是因為它使用了IIC-DMA功能,因而工作時對mcu的占用少。提高mcu使用效能。
前面介紹的四個函數,兩個基本讀寫,兩個采用了IIC-DMA功能讀寫。比較一下發現論單任務完成速度,基本函數快些,但占用mcu時間多。
為了展示前面四個函數的用法,又寫了兩個函數,一個往at24c1024里寫入批量圖像數據,一個從at24c1024里讀出數據并送屏幕顯示出來
void transfer_image(unsigned int addr,unsigned char *p,unsigned char number_page,unsigned char SLAW)//向芯片送圖像數據number_page是頁數
void disp_at24c1024(unsigned int x,unsigned int y,unsigned int addr,unsigned char number_page,unsigned char SLAW)//讀出數據并送屏顯示
函數中x,y表示在屏上顯示的起始位置,我把屏分成四份,用四個數組文件(pic01.h;pic02.h;pic03.h;pic04.h)放圖像數據,顯示屏為320x240。單個圖的尺寸為160x100。這兩個函數屬于普通編程,不多說了。
在規劃at24c1024空間時,我在前區存入兩個圖像,其SLAW值為0xa0;在后區存入兩個圖像文件,其SLAW值為0xa2.在例程中可以注意一下。
這里分區存放數據。沒有選擇連續存放,是考慮編程簡單些。一個不常用的程序,寫得復雜了沒益處。
下面是主程序:
#include "STC32G.H"
#include "mcu_initial.h"
#include "tft_320_drv.h"
#include "pic00.h"
//#include "pic01.h"
//#include "pic02.h"
//#include "pic03.h"
//#include "pic04.h"
unsigned char extern xdata DmaRxBuffer[];
unsigned char extern xdata DmaTxBuffer[];
bit extern busy;
//unsigned int cnt;
void main(void)
{
mcu_initial();
lcd_initial();
display_black();
//因為內存空間有限,寫圖像數據進at24c1024時,分四次寫入(兩次也能行)每次打開一個寫語句,并修改對應的頭文件例pic01.h
//transfer_image(0,pic01,125,0xa0);//從地址0x00開始,存入125頁數據,打開時要有頭文件pic01.h配合
//transfer_image(32000,pic04,125,0xa0);//從地址32000開始,存入125頁數據,打開時要有頭文件pic04.h配合
//transfer_image(32000,pic02,125,0xa2);//這是在后區。,打開時要有頭文件pic02.h配合
//transfer_image(0,pic03,125,0xa2);//這個也是后區,打開時要有頭文件pic03.h配合
disp_32x32(32,64,pin,red, yellow);//寫入完成標志
disp_at24c1024(0,0,0,125,0xa0);
disp_at24c1024(160,100,32000,125,0xa0);
disp_at24c1024(0,100,0,125,0xa2);
disp_at24c1024(160,0,32000,125,0xa2);
Delay10ms();
display_image(0, 200,320,40,pic00);
while(1);
}
運行時先分批打開寫入數據函數,把圖像數據寫進芯片。就可以看到完整的圖像顯示了。
考慮到寫入速度比較慢。在寫入時加了計數顯示。能看到寫入的進程。
例程采用了lcm功能,lcm_dma功能和iic_dma功能。所以運行相關函數前要做好 相關設置,具體設置多數放在mcu_initial.c模式中了。少數在函數里。
考慮到寫at24c1024的速度可能比讀慢些。所以讀寫函數采用了不同的iic速度設置。讀程序時可以注意一下。主要是IIC_DMA頁寫時速度快了好像不行。所以用了230K,其它用了800k.
附圖是顯示的圖像效果和整機實況,看整機實況請不要仔細看,因為我的at24c1024芯片是用鐵絲綁在洞洞板上,然后飛線連接的。老師看到會踢死我的。
完整例程見附件,歡迎指點,歡迎吐槽。
|
評分
-
查看全部評分
|