STM32模擬IIC讀寫EEPROM

2021-10-03 07:06:45 字數 3623 閱讀 5306

本人在最近的專案中,需要讀寫eeprom裡面的內容並分析。該eeprom晶元為microchip technology公司的24lc02b系列。用stm32f103晶元做主機通過iic介面去和它通訊。

首先介紹晶元的基本特性,容量為 :256 x 8bit ,2kbit共有256位元組 ;位址和資料都是8bit;電源供電2.5v-5.5v;iic支援最高速率400k;支援單位元組寫和按頁寫兩種,寫資料後最大需要延時5ms;支援連續讀,單位元組讀和隨機讀取3種讀方式。總的說來這顆ic很大眾,操作簡單。

主機stm32f1本來想用硬體iic,找了例程,網上資料一大堆,也沒成功,所以用的模擬iic。波形雖然不太好看,但還是挺好用。

主機模擬iic用的pb10和pb11,scl時鐘的週期為7us.**如下:

#define see_i2c_clk                      rcc_apb1periph_i2c2

#define see_i2c_scl_pin gpio_pin_10 /* pb.10 */

#define see_i2c_scl_gpio_port gpiob /* gpiob */

#define see_i2c_scl_gpio_clk rcc_apb2periph_gpiob

#define see_i2c_sda_pin gpio_pin_11 /* pb.11 */

#define see_i2c_sda_gpio_port gpiob /* gpiob */

#define see_i2c_sda_gpio_clk rcc_apb2periph_gpiob

#define sda_in()

#define sda_out() //io操作函式

#define read_sda gpio_readinputdatabit(see_i2c_scl_gpio_port,see_i2c_sda_pin)//輸入sda

#define iic_sda_up gpio_setbits(see_i2c_scl_gpio_port,see_i2c_sda_pin)

#define iic_sda_down gpio_resetbits(see_i2c_scl_gpio_port,see_i2c_sda_pin)

#define iic_scl_up gpio_setbits(see_i2c_scl_gpio_port,see_i2c_scl_pin)

#define iic_scl_down gpio_resetbits(see_i2c_scl_gpio_port,see_i2c_scl_pin)

#define eeprom_addr 0xa0 //eeprom的器件位址

#define page_size 8 //按頁寫時,一頁大小為8位元組

#define rom_size 256 //整個rom大小是256位元組

#define i2c_buf_len 256

uint8_t i2c_rec[i2c_buf_len];

static void delay_us(u32 t)

}static void delay_ms(u32 t)

}void iic_init(void)

//產生iic起始訊號

void iic_start(void)

void iic_stop(void)

//等待應答訊號到來//返回值:1,接收應答失敗// 0,接收應答成功

u8 iic_wait_ack(void)

} iic_scl_down; //時鐘輸出0

sda_out();

return 0;

} //產生ack應答

void iic_ack(void)

//不產生ack應答

void iic_nack(void)

void iic_send_byte(u8 txd)

else

txd<<=1;

delay_us(1); //對tea5767這三個延時都是必須的

iic_scl_up;

delay_us(4);//delay_us(2);

iic_scl_down;

delay_us(2);

} }

//讀1個位元組,ack=1時,傳送ack,ack=0,傳送nack

u8 iic_read_byte(unsigned char ack)

if (!ack)

iic_nack();//傳送nack

else

iic_ack(); //傳送ack

return receive;

#endif

} void i2c_writebyte(uint8_t word_addr, uint8_t data)

void i2c_writebytepage(uint8_t word_addr,const uint8_t *pdata)

iic_stop();//產生乙個停止條件

delay_ms(5);//寫操作時,最後的延時不得小於3ms

}void readlenbyte(u8 *pbuf,u16 len)

{ u16 t;

iic_start();

iic_send_byte(eeprom_addr); //傳送寫命令

iic_wait_ack();

delay_us(5);

iic_send_byte(0x0); //傳送暫存器位址

iic_wait_ack();

delay_us(5);

iic_start();

iic_send_byte(0xa1); //進入接收模式

iic_wait_ack();

for(t=0;t這兩個函式要根據自己pin腳去修改。

採集的波形如下

最後總結遇到的問題:

1.剛開始沒有注意到寫操作後延時,只給了200us,造成寫完一筆資料後,iic的讀寫操作都失敗,後來給了10ms的延時就ok了;

2.網上找的**不夠嚴謹,很多毛刺,需要自己再除錯;

3.stm32f1xx的硬體iic比較複雜,我以前只用過stm32f0的,剛開始不知道,調了2天也沒搞定硬體iic通訊,建議對iic或stm32f1不熟悉,謹慎使用其硬體iic。

4.由於我的平台限制,stm32供電3.3v,eeprom供電為5v。雖然讀寫也成功了,但是建議讀者最好使二者電平匹配的。

5.iic的通訊線要接上拉電阻,要不然沒有輸出。

stm32軟體模擬iic

iic inter integrated circuit 匯流排是一種由philips公司在80年代開發的兩線式序列匯流排,用於連線微控制器及其外圍裝置。它是半雙工通訊方式。iic匯流排最主要的優點是其簡單性和有效性。由於介面直接在元件之上,因此iic匯流排占用的空間非常小,減少了電路板的空間和晶元...

stm32模擬iic暫存器配置

io方向設定 define mpu sda in define mpu sda out io操作函式 define mpu iic scl pbout 10 scl define mpu iic sda pbout 11 sda define mpu read sda pbin 11 輸入sda 每...

stm32(十四)IIC總結

一 iic匯流排知識 sda 雙向資料線,主機可以通過sda線傳送資料給集群,集群也可以通過sda線傳送資料給主機 scl 時鐘訊號線,驅動資料線收發資料的脈衝訊號由scl提供,scl脈衝訊號永遠由主機發出 在匯流排上sda和scl都有上拉電阻,因為iic匯流排介面的晶元sda,scl輸出都是開漏輸...