<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl-pl">
<link rel="self" type="application/atom+xml" href="https://forum.atnel.pl/feed.php?f=46&amp;t=10652&amp;mode" />

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2015-02-14T15:22:45+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=46&amp;t=10652&amp;mode</id>
<entry>
<author><name><![CDATA[damiandoles]]></name></author>
<updated>2015-02-14T15:22:45+01:00</updated>
<published>2015-02-14T15:22:45+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=10652&amp;p=118948#p118948</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=10652&amp;p=118948#p118948"/>
<title type="html"><![CDATA[[STM32F0 Discovery][C/CoCoox] Komunikacja z PCF8583]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=10652&amp;p=118948#p118948"><![CDATA[
Witam wszystkich serdecznie,<br /><br />Chciałbym prosić o pomoc w analizie błędów inicjalizacji i komunikacji z zegarem RTC, który wszyscy znają. Chciałbym przedstawić kod, który nie działa - opisać objawy i spytać o parę rzeczy, które mnie nurtują. A więc do rzeczy. Najpierw Kod:<br /><br />[syntax=c]#define PCF8583_ADDR          ((uint16_t)(0x50))<br />#define I2C_SCL GPIO_Pin_6<br />#define I2C_SDA GPIO_Pin_7<br /><br />// Registers<br />#define PCF8583_SEC_REG  ((uint8_t)(0x02))<br />#define PCF8583_MIN_REG  ((uint8_t)(0x03))<br />#define PCF8583_HOU_REG  ((uint8_t)(0x04))<br />#define PCF8583_DAY_REG  ((uint8_t)(0x05))<br />#define PCF8583_MON_REG  ((uint8_t)(0x06))<br /><br />void PCF8583_Setup(void);<br />uint8_t PCF8583_RegRead(uint8_t reg);<br />void PCF8583_RegWrite(uint8_t reg, uint8_t data);<br /><br />void PCF8583_Setup(void)<br />{<br />GPIO_InitTypeDef GPIO_InitStructure;<br />I2C_InitTypeDef  I2C_InitStructure;<br /><br />RCC_I2CCLKConfig(RCC_I2C1CLK_HSI);<br />RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);<br />RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);<br /><br />GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_1); //scl<br />GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_1); //sda<br /><br />GPIO_StructInit(&amp;GPIO_InitStructure);<br />GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;<br />GPIO_InitStructure.GPIO_Pin = I2C_SCL | I2C_SDA; //scl - pb6 ; sda - pb7<br />GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;<br />GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;<br />GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;<br /><br />GPIO_Init(GPIOB, &amp;GPIO_InitStructure);<br /><br />I2C_DeInit(I2C1);<br /><br />I2C_StructInit(&amp;I2C_InitStructure);<br />I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;<br />I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;<br />I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;<br />I2C_InitStructure.I2C_DigitalFilter = 0;<br />I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;<br />I2C_InitStructure.I2C_OwnAddress1 = 0;<br />I2C_InitStructure.I2C_Timing = 0x40B22536;<br />I2C_Init(I2C1, &amp;I2C_InitStructure);<br /><br />I2C_Cmd(I2C1, ENABLE);<br />}<br /><br /><br />uint8_t PCF8583_RegRead(uint8_t reg)<br />{<br />// kopia kodu z AVR<br />//TWI_Start();<br />//TWI_Write(PCF8583AddressWrite); //0xA0<br />//TWI_Write(address); //rejestr<br />//TWI_Start();<br />//TWI_Write(PCF8583AddressRead); //0xA1<br />//read_data = TWI_Read(NACK);<br />//TWI_Stop();<br /><br />/*<br />I2C_GenerateSTART(I2C1, ENABLE);<br />I2C_SendData(I2C1,(uint32_t) 0x50); //address write<br />I2C_SendData(I2C1, reg); //register to read<br />I2C_GenerateSTART(I2C1, ENABLE);<br />I2C_SendData(I2C1,(uint32_t) 0x50); //address read<br />tmp = I2C_ReceiveData(I2C1);<br />I2C_GenerateSTOP(I2C1, ENABLE);<br />*/<br /><br />uint8_t tmp = 0xFF;<br /><br />I2C_TransferHandling(I2C1, PCF8583_ADDR, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);<br />while(!(I2C1-&gt;ISR &amp; I2C_ISR_TXIS));<br /><br />I2C_SendData(I2C1, reg);<br />while(!(I2C1-&gt;ISR &amp; I2C_ISR_TC));<br /><br />I2C_TransferHandling(I2C1, PCF8583_ADDR, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);<br />while(!(I2C1-&gt;ISR &amp; I2C_ISR_RXNE));<br /><br />tmp = I2C_ReceiveData(I2C1);<br /><br />while(!(I2C1-&gt;ISR &amp; I2C_ISR_STOPF));<br />I2C1-&gt;ICR = I2C_ICR_STOPCF;<br /><br />return(tmp);<br />}<br /><br />void PCF8583_RegWrite(uint8_t reg, uint8_t data)<br />{<br />I2C_TransferHandling(I2C1, PCF8583_ADDR, 1, I2C_Reload_Mode, I2C_Generate_Start_Write);<br />while(!(I2C1-&gt;ISR &amp; I2C_ISR_TXIS));<br /><br />I2C_SendData(I2C1, reg);<br />while(!(I2C1-&gt;ISR &amp; I2C_ISR_TCR));<br /><br />I2C_AutoEndCmd(I2C1, ENABLE);<br />while(!(I2C1-&gt;ISR &amp; I2C_ISR_TXIS));<br /><br />I2C_SendData(I2C1, data);<br /><br />I2C_ReloadCmd(I2C1, DISABLE);<br /><br />while(!(I2C1-&gt;ISR &amp; I2C_ISR_STOPF));<br />I2C1-&gt;ICR = I2C_ICR_STOPCF;<br />}[/syntax]<br /><br />Adres urządzenia zgodnie z datasheetem - 0b101000 A0 RW. U mnie pin A0 zwarty jest do masy, więc adres wygląda następująco: 0b1010000 - 0x50. STM32 z tego co rozumiem wymaga adresów 7 bitowych a najmłodszy bit R/W ustawia sam np. przy wywołaniu funkcji: <br />- I2C_TransferHandling<br /><br />Dobrze rozumiem ? <br /><br />Po drugie, czy adresowanie 0x50 jest wystarczające, czy mam używać jakiś operacji bitowych ? Nie mogę znaleźć o tym informacji. <br /><br />Po trzecie, czy jest jakaś różnica, jeśli tak to jaka w inicjalizacji GPIO oraz I2C ? Że najpierw np. zegar RCC peryferiów, potem struktura GPIO, potem funkcje alternatywne, dalej jakiś DeInit, itd.<br /><br />Po czwarte, o co chodzi w polu struktury I2C_InitStructure.I2C_Timing = 0x40B22536; ? Tzn. rozumiem, że chodzi o częstotliwość zegara I2C, ale jak oblicza się tę wartość ? Zaraz ktoś odeśle mnie do skomplikowanego manuala Cortexa - tak, czytam, analizuje, mam ciągle otwarty, ale nie dla wszystkich jest on łatwy i czytelny.<br /><br />Teraz do rzeczy: problem jest taki, że gdy wywołuję w main.c funkcję odczytu rejestru z RTC, czyli:<br /><br />[syntax=c]sec =  PCF8583_RegRead(PCF8583_SEC_REG); // rejestr 0x02[/syntax]<br /><br />gdzie zmienna sec to uint8_t, program zawiesza się i zostaje w pierwszej pętli while tejże funkcji -&gt; while(!(I2C1-&gt;ISR &amp; I2C_ISR_TXIS)); z której już nigdy nie wychodzi. Jak mam rozumieć ten błąd ? Czy w tym wypadku w ogóle generowane jest cokolwiek ? Czy ten kod w ogóle jest dobry ? Napisałem go na bazie exampli od ST. Rezystory podciągające 10kΩ, długość lini to ~ 15cm więc nie ma to znaczenia. Układ RTC sprawny, wielokrotnie używany.<br /><br />Będę wdzięczny za jakiekolwiek wskazówki z I2C do STMów, bo totalnie tego nie ogarniam. Dzięki z góry !<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1669">damiandoles</a> — 14 lut 2015, o 15:22</p><hr />
]]></content>
</entry>
</feed>