-*-记录给自己备忘,供大家交流,
-*-相关时序可以在 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)); }