Hi,
I am using the DS1307 library for STM32L152. The original library for STM32F429 is at here: stm32f4-discovery.com/.../
It seems a complete library however after few modification to STM32L I cant read/write DS1307. what ever is received is 1.
int main(void) { TM_DS1307_Time_t tim; SystemCoreClockSetHSI(); GPIO_RCC_configuration(); GPIO_configuration(); Init_SPI(); uart1_configuration(); I2C2_init(); TIM4_configuration(); TM_DS1307_SetDateTime(&tim); while(1) { tim.seconds=TM_DS1307_GetSeconds(); sprintf(str," \r\ns=%u",tim.seconds); uart_out_str(str); delay_ms(1000); } }
result is
s=1 s=1 s=1 s=1 s=1 s=1
I see signals in scope and there is a delay about 200ms when reading from DS1307 (reading timeout). when I debug, DR changes between 0xD0 and 0xD1. How can I find where the problem is?
Have you enabled the I2C peripheral clock? Can you see the peripheral registers in the debugger? Have you spoken to the author of the library?
Hi, I2C Peripheral clock is enabled and I see the signals in scope. Yes I see peripheral registers in debugger they change according to the program flow. No, I have not yet spoken to him. I think problem is at start function. because program waits there, I2C looks so busy.
/* Wait till I2C is busy */ TM_I2C_Timeout = TM_I2C_TIMEOUT; while (!(I2Cx->SR1 & I2C_SR1_SB)) { if (--TM_I2C_Timeout == 0x00) { return 1; } }
I found another library which is a little smaller in size. It is written for STM32F0 but I try to understand below function, is there a way to transfer it to STM32L1XX?
void I2C_TransferHandling( I2C_TypeDef * I2Cx, uint16_t Address, uint8_t Number_Bytes, uint32_t ReloadEndMode, uint32_t StartStopMode )
Is there equivalent in STM32L1xx?
void I2C_WrReg(uint8_t Reg, uint8_t Dat){ while(I2C_GetFlagStatus(DS_I2C, I2C_FLAG_BUSY) == SET); I2C_TransferHandling(DS_I2C, DS_ADDR, 1, I2C_Reload_Mode, I2C_Generate_Start_Write); while(I2C_GetFlagStatus(DS_I2C, I2C_FLAG_TXIS) == RESET); I2C_SendData(DS_I2C, Reg); while(I2C_GetFlagStatus(DS_I2C, I2C_FLAG_TCR) == RESET); I2C_TransferHandling(DS_I2C, DS_ADDR, 1, I2C_AutoEnd_Mode, I2C_No_StartStop); while(I2C_GetFlagStatus(DS_I2C, I2C_FLAG_TXIS) == RESET); I2C_SendData(DS_I2C, Dat); while(I2C_GetFlagStatus(DS_I2C, I2C_FLAG_STOPF) == RESET); I2C_ClearFlag(DS_I2C, I2C_FLAG_STOPF); }
Why this simple code fails to work
while(1) { TM_I2C_Start(I2C2, 0xD0, 0, I2C_ACK_ENABLE) ; //write mode TM_I2C_WriteData(I2C2, 0); //select register 0x0 TM_I2C_Stop(I2C2); //stop TM_I2C_Start(I2C2, 0xD0, 1, I2C_ACK_ENABLE) ; //read mode sec = TM_I2C_ReadNack(I2Cx); sprintf(str," :\r\ns=%u",sec); uart_out_str(str); }
In debugger I get AF=1. why ack failures?
I tried a modification on the code written for eeprom. I see that I don't receive ack for address sent and in the debugger ADDR is never set so where is probably the problem?
Oh my God!!
DS1307 supply voltage is 4.5-5.5V. this was the problem. After changing the supply from 3.3V to 5V the problem solved :)