STM32F030 硬體I2C驅動 AT24C16

2021-07-23 22:09:48 字數 4534 閱讀 5834

網路上很多f1系列的atc24的讀寫程式,但f0幾乎沒有。由於f0完全重寫了i2c,所以以往的**並不能直接使用,修改事件、介面上會浪費很多時間,特別是對於使用f0系列進行入門的新手。

在此十分感謝 暢學電子網 的對於at24c16的資料,特別是at24c16位址的解釋。除錯過程中這篇文章給了很大的幫助。建議不想只當伸手黨的同志們認真閱讀,否則只會ctrl c ctrl v,你又怎麼能說自己是嵌入式開發者?

廢話不多說,進入正題。(哈哈,每篇文章都用這個開頭)

static void initi2c()

一樣的配置方案,i2c_timing的意思請移步本部落格gy30那篇文章。

i2c引腳為pb8 與pb9(使用的c8t6,f4p6可以用pa的)

#define at24c16_base_address 0xa0

void at24c16_writebyte(uint8_t page,uint8_t wordaddress,uint8_t data);

uint8_t at24c16_readbyte(uint8_t page,uint8_t wordaddress);

void at24c16_pagewrite(uint8_t page,uint8_t wordaddress,uint8_t length,uint8_t*

data);

void at24c16_sequentialread(uint8_t page,uint8_t wordaddress, uint8_t length , uint8_t* p);

void at24c16_writebyte(uint8_t page,uint8_t wordaddress,uint8_t data)

wordaddress |= ( page &

0x0f ) <<

4; while(i2c_getflagstatus(i2c1, i2c_flag_busy) != reset);//if busy

i2c_transferhandling(i2c1,at24c16_base_address | ( ( page &

0xf0 ) >>

3 ),2,i2c_autoend_mode,i2c_generate_start_write);

while(i2c_getflagstatus(i2c1, i2c_flag_txis) == reset);//if write ok

i2c_senddata(i2c1,wordaddress);

while(i2c_getflagstatus(i2c1, i2c_flag_txis) == reset);//if write ok

i2c_senddata(i2c1,data);

while(i2c_getflagstatus(i2c1, i2c_flag_stopf) == reset);

}uint8_t at24c16_readbyte(uint8_t page,uint8_t wordaddress)

wordaddress |= ( page &

0x0f ) <<

4; while(i2c_getflagstatus(i2c1, i2c_flag_busy) != reset);//if busy

i2c_transferhandling(i2c1,at24c16_base_address | ( ( page &

0xf0 ) >>

3 ),1,i2c_softend_mode,i2c_generate_start_write);

while(i2c_getflagstatus(i2c1, i2c_flag_txis) == reset);//if write ok

i2c_senddata(i2c1,wordaddress);

while(i2c_getflagstatus(i2c1, i2c_flag_tc) == reset);

i2c_transferhandling(i2c1,at24c16_base_address | ( ( page &

0xf0 ) >>

3 ),1,i2c_autoend_mode,i2c_generate_start_read);

while(i2c_getflagstatus(i2c1, i2c_flag_rxne) == reset);

recev = i2c_receivedata(i2c1);

while(i2c_getflagstatus(i2c1, i2c_flag_stopf) == reset);

return recev;

}

下面是頁讀取,頁寫入:

void at24c16_pagewrite(uint8_t page,uint8_t wordaddress,uint8_t length,uint8_t* data)

wordaddress |= ( page & 0x0f ) << 4;

while(i2c_getflagstatus(i2c1, i2c_flag_busy) != reset);//if busy

i2c_transferhandling(i2c1,at24c16_base_address | ( ( page & 0xf0 ) >> 3 ),length + 1,i2c_autoend_mode,i2c_generate_start_write);

while(i2c_getflagstatus(i2c1, i2c_flag_txis) == reset);//if write ok

i2c_senddata(i2c1,wordaddress);

for(i = 0;i < length; i++)

while(i2c_getflagstatus(i2c1, i2c_flag_stopf) == reset);

}void at24c16_sequentialread(uint8_t page,uint8_t wordaddress, uint8_t length , uint8_t* p)

wordaddress |= ( page & 0x0f ) << 4;

while(i2c_getflagstatus(i2c1, i2c_flag_busy) != reset);//if busy

i2c_transferhandling(i2c1,at24c16_base_address | ( ( page & 0xf0 ) >> 3 ),1,i2c_softend_mode,i2c_generate_start_write);

while(i2c_getflagstatus(i2c1, i2c_flag_txis) == reset);//if write ok

i2c_senddata(i2c1,wordaddress);

while(i2c_getflagstatus(i2c1, i2c_flag_tc) == reset);

i2c_transferhandling(i2c1,at24c16_base_address | ( ( page & 0xf0 ) >> 3 ),length,i2c_autoend_mode,i2c_generate_start_read);

for(i = 0;i < length;i++)

while(i2c_getflagstatus(i2c1, i2c_flag_stopf) == reset);

}

感覺沒什麼說的,gy30那篇文章基本都說完了,添點小知識點吧。

i2c_autoend_mode,顧名思義,操作length位元組後自動新增stop。

i2c_softend_mode ,同樣顧名思義,操作length位元組後需要手動新增stop。( i2c_generatestop() )

這個模式比自動多了一步,需要 i2c_getflagstatus(i2c1, i2c_flag_tc) ,translate completed,是否傳輸完成,自動模式下訪問這個會得到reset值,然而手動模式下需要訪問他,然後生成stop。

然後……差不多了吧?舉個 上面**的例子吧,我覺得很多人不會看……

所以在編寫程式對at24c16第100頁的第3個位元組進行寫資料的時候,步驟如下:

1)傳送起始訊號;

2)傳送器件位址0xa6(1010 0110,1010是固定位址,011是頁位址的高三位,0表示寫操作);

3)傳送操作位址0x43(0100 0011,0100是頁位址的低四位,0011是頁位址偏移量,即第100頁內的第三個位元組,

4)傳送要寫的資料,

5)傳送終止訊號。

我相信各位最起碼都看了at24c16的位址了,0xa0。(再次引用暢學電子網的)

p0p1p2為頁位址高三位,傳送的字位址(wordaddress)高四位為頁位址的第四位,低四位為字位址。

at24c16有128頁,每頁16bytes。所以正好匹配上。

寫的間隔至少為5ms,否則用迴圈等待的話i2c會卡死。

微控制器 stm32f030 硬體 I2C

參考文章 i2c hard.c 檔案 include i2c hard.h static int i2c timeout 0 void i2c1 port init void void i2c1 init void brief 從i2c1匯流排上的某一器件的某一起始位址中讀取一定位元組的資料到陣列中...

STM32F030開發環境搭建

長話短說,由於突然要除錯別人畫的一塊板子,用的是stm32f030除錯乙個adc.include stm32f0xx hal.h 這裡這個標頭檔案要放在其他標頭檔案前面,就是乙個順序問題。不然會報錯一堆未定義。這個問題可能以後編譯器會優化吧,目前先記著。然後需要編譯除錯。我只有dap link,但是...

STM32F030的IAP應用簡介

可以看到函式用了for迴圈將向量表拷貝到0 x20000000 sram的基位址,即將向量表由flash對映到了sram。所以在mdk裡面設定flash偏移位址的時候,同時要設定sram偏移位址。如下截圖 iap set void 函式 falsh address sram address 0x02...