-*-記錄給自己備忘,供大家交流,
-*-相關時序可以在 eeprom datasheet 上面可以看到,在此不做解釋
作者: 棒糖 Cavin
平台:keil5 & STM32G031KE8T6
時間:20201101
1、硬件IIC不需要自己去生成開始位結束位,只需調用配置函數LL_I2C_HandleTransfer,通過設置參數來進行收發
2、注意參數設定,例如 LL_I2C_MODE_AUTOEND 和 LL_I2C_GENERATE_START_WRITE 是用於寫操作、LL_I2C_MODE_SOFTEND 和 LL_I2C_GENERATE_START_READ 是用於讀操作
要注意分別。
3、加入超時設定,如果記時到及時退出並清空相應標志位,我把它寫成一個函數,有不妥之處但無傷大雅。
4、一次STOP之后還是要等待5ms以上以便eeprom寫入數據,連續寫時由於只有一個stop位只會等待一次,但注意別超過頁字節數。
以下是源碼:
1 /************************************************************* 2 Function Name: E2PROM_Write_Byte 3 Function Description: 輪詢寫字節,不超過一頁數據,作為頁寫入輔助 4 Inputs: TargetAddress(DeviceAddress設備地址+DataAddress字節地址), 5 *pdata -數據指針, 6 txLen -數據長度, 7 timeout-超時時間 8 Outputs: 正常0/異常1 9 Notes: 10 *************************************************************/ 11 uint8_t EEPROM_Write_Byte(uint8_t DeviceAddress, uint8_t MemAddress, uint8_t *pData, uint8_t TxLen,uint16_t Timeout) 12 { 13 /* 等待I2C總線空閑,超時進行錯誤處理 */ 14 while(LL_I2C_IsActiveFlag_BUSY(I2C1) == SET){ 15 /* 確認是否使能 */ 16 if(!LL_I2C_IsEnabled(I2C1)) 17 { 18 LL_I2C_Enable(I2C1); 19 } 20 /* clear RXNE flag */ 21 if (LL_I2C_IsActiveFlag_RXNE(I2C1)) 22 { 23 LL_I2C_ReceiveData8(I2C1); /* 讀出來清除標志位 */ 24 } 25 26 /* End of Transfer */ 27 if(LL_I2C_IsActiveFlag_STOP(I2C1)) 28 { 29 LL_I2C_ClearFlag_STOP(I2C1); 30 } 31 32 /* Clear NACKF Flag */ 33 if(LL_I2C_IsActiveFlag_NACK(I2C1)) 34 { 35 LL_I2C_ClearFlag_NACK(I2C1); 36 } 37 38 if(LL_SYSTICK_IsActiveCounterFlag()) 39 { 40 if (Timeout-- == 0) 41 { 42 EEPROM_ClearCR(); 43 return 1; 44 } 45 } 46 } 47 /* 發送器件地址 */ 48 LL_I2C_HandleTransfer(I2C1, DeviceAddress, LL_I2C_ADDRSLAVE_7BIT, (TxLen+1), LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE); 49 /* 等待發送 */ 50 /* RESET: When next data is written in Transmit data register. 51 SET: When Transmit data register is empty. */ 52 while(!LL_I2C_IsActiveFlag_TXE(I2C1)){ 53 if (LL_SYSTICK_IsActiveCounterFlag()) 54 { 55 if (Timeout-- == 0) 56 { 57 LL_I2C_ClearFlag_TXE(I2C1); 58 EEPROM_ClearCR(); 59 return 1; 60 } 61 } 62 } 63 /* 發送寄存器地址 */ 64 LL_I2C_TransmitData8(I2C1, MemAddress); 65 66 /* 發送數據 */ 67 while(TxLen>0){ 68 69 if(LL_I2C_IsActiveFlag_TXE(I2C1)){ 70 LL_I2C_TransmitData8(I2C1, *pData); 71 pData++; 72 TxLen--; 73 if (LL_SYSTICK_IsActiveCounterFlag()) 74 { 75 if (Timeout-- == 0) 76 { 77 LL_I2C_ClearFlag_TXE(I2C1); 78 EEPROM_ClearCR(); 79 return 1; 80 } 81 } 82 } 83 } 84 85 /* 等待停止位 */ 86 while(LL_I2C_IsActiveFlag_STOP(I2C1) ==RESET) 87 { 88 if (LL_SYSTICK_IsActiveCounterFlag()) 89 { 90 if (Timeout-- == 0) 91 { 92 EEPROM_ClearCR(); 93 return 1; 94 } 95 } 96 } 97 /* CLEAR FLAG */ 98 EEPROM_ClearCR(); 99 return 0; 100 }
/************************************************************* Function Name: EEPROM_Error_Callback Function Description: 錯誤處理,清除寄存器和標志位 Inputs: Outputs: Notes: *************************************************************/ void EEPROM_ClearCR(void){ /* Clear NACKF Flag */ LL_I2C_ClearFlag_NACK(I2C1); /* Clear STOP Flag */ LL_I2C_ClearFlag_STOP(I2C1); /* Clear Configuration Register 2, */ I2C1->CR2 &= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_HEAD10R | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_RD_WRN)); }