|
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
jure94 Član
Pridružen-a: Sre 05 Maj 2010 17:11 Prispevkov: 433 Aktiv.: 2.56 Kraj: Jesenice / Lj
|
Objavljeno: Čet Okt 30, 2014 6:05 pm Naslov sporočila: |
|
|
No, da še jaz napišem par vrstic, ker se ravno učim programiranja STM32.
Veliko je primerov na internetu, me pa moti, ker jih kar veliko uporabja knižnjice. Sem se učim tako, da berem user manual in iz primerov vidim samo princip delovanja (res je da do USB-ja še nisem prišel, takrat bo vrjetno drugače ).
Torej, ker se mi ne mudi in to delam za hobby, imam dovolj časa, da velikokrat preberem user manual (pač tisti del ki je trenutno zanimiv) in iz primerov vidim princip delovanja, nato pa sam napišem vse (in ker nisem ravno velik poznavalec C-ja to traja malo dlje). Se pa s tem naučim veliko več, kot če bi kopiral example in se ne bi poglobil kako deluje (če bi se pa poglobil in vse razumel sem pa s časom tam-tam, kot če napišem vse sam).
Lp
|
|
Nazaj na vrh |
|
|
jure94 Član
Pridružen-a: Sre 05 Maj 2010 17:11 Prispevkov: 433 Aktiv.: 2.56 Kraj: Jesenice / Lj
|
Objavljeno: Sre Nov 19, 2014 7:29 pm Naslov sporočila: |
|
|
Upam, da bo to prava tema za vprašanje.
Uporabljam STM32F401RE in me zanima, kako izračunam, kakšne vrednosti naj zapišem v I2C CCR in TRISE registra za 100kHz I2C.
SYSCLK je 168 MHz, APB1 prescaler je 4, torej to znese 42 MHz. V I2C_CR2_FREQ[5:0] imam vrednost 42 (0b101010), saj naj bi bila ta vrednost enaka hitrosti ure APB.
Zanima me pa, kako izračunam vrednost, ki jo moram zapisati v I2C_CCR_CCR[11:0] za 100kHz hitrist I2C. Sicer je podana formula, ampak, če računam po njej dobim rezultat, ki se ga ne da vpisati. Če računam po primeru, ki je:
Citiram: |
If FREQR = 08, TPCLK1= 125 ns so CCR must be programmed with 0x28
(0x28 <=> 40d x 125 ns = 5000 ns |
dobim:
Koda: |
FREQ[5:0] = 42 (=0x2A) -> Tpclk1 = 1/42 s
X*(1/42)s=5000ns
X=210000 kar je 0x33450 (veliko preveč, glede na to, da je prostora samo za 12 bitov)
|
Zanima me, kaj sem zgrašil v datasheetu (če se komu da, lahko še št. strani) in kako se to pravilno izračuna.
Upam, da je vprašanje dovolj jasno.
Lp,
Jure
|
|
Nazaj na vrh |
|
|
tilz0R Član
Pridružen-a: Čet 31 Maj 2012 15:39 Prispevkov: 898 Aktiv.: 6.24 Kraj: Črnomelj
|
Objavljeno: Sre Nov 19, 2014 7:35 pm Naslov sporočila: |
|
|
F401 ima 84MHz clock, 168 ne bo šlo.
APB1 ima v tem primeru prescaler nastavljen na 2, torej še vedno je clock 42MHz.
Nastaviti moraš frequency range, max rise time in frekvenco (oziroma prescaler neke vrste).
Koda iz STD periph driverjev (vrednost I2C_InitStruct->I2C_ClockSpeed je v hercih):
Koda: |
void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct)
{
uint16_t tmpreg = 0, freqrange = 0;
uint16_t result = 0x04;
uint32_t pclk1 = 8000000;
RCC_ClocksTypeDef rcc_clocks;
/* Check the parameters */
assert_param(IS_I2C_ALL_PERIPH(I2Cx));
assert_param(IS_I2C_CLOCK_SPEED(I2C_InitStruct->I2C_ClockSpeed));
assert_param(IS_I2C_MODE(I2C_InitStruct->I2C_Mode));
assert_param(IS_I2C_DUTY_CYCLE(I2C_InitStruct->I2C_DutyCycle));
assert_param(IS_I2C_OWN_ADDRESS1(I2C_InitStruct->I2C_OwnAddress1));
assert_param(IS_I2C_ACK_STATE(I2C_InitStruct->I2C_Ack));
assert_param(IS_I2C_ACKNOWLEDGE_ADDRESS(I2C_InitStruct->I2C_AcknowledgedAddress));
/*---------------------------- I2Cx CR2 Configuration ------------------------*/
/* Get the I2Cx CR2 value */
tmpreg = I2Cx->CR2;
/* Clear frequency FREQ[5:0] bits */
tmpreg &= (uint16_t)~((uint16_t)I2C_CR2_FREQ);
/* Get pclk1 frequency value */
RCC_GetClocksFreq(&rcc_clocks);
pclk1 = rcc_clocks.PCLK1_Frequency;
/* Set frequency bits depending on pclk1 value */
freqrange = (uint16_t)(pclk1 / 1000000);
tmpreg |= freqrange;
/* Write to I2Cx CR2 */
I2Cx->CR2 = tmpreg;
/*---------------------------- I2Cx CCR Configuration ------------------------*/
/* Disable the selected I2C peripheral to configure TRISE */
I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_PE);
/* Reset tmpreg value */
/* Clear F/S, DUTY and CCR[11:0] bits */
tmpreg = 0;
/* Configure speed in standard mode */
if (I2C_InitStruct->I2C_ClockSpeed <= 100000)
{
/* Standard mode speed calculate */
result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed << 1));
/* Test if CCR value is under 0x4*/
if (result < 0x04)
{
/* Set minimum allowed value */
result = 0x04;
}
/* Set speed value for standard mode */
tmpreg |= result;
/* Set Maximum Rise Time for standard mode */
I2Cx->TRISE = freqrange + 1;
}
/* Configure speed in fast mode */
/* To use the I2C at 400 KHz (in fast mode), the PCLK1 frequency (I2C peripheral
input clock) must be a multiple of 10 MHz */
else /*(I2C_InitStruct->I2C_ClockSpeed <= 400000)*/
{
if (I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_2)
{
/* Fast mode speed calculate: Tlow/Thigh = 2 */
result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 3));
}
else /*I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_16_9*/
{
/* Fast mode speed calculate: Tlow/Thigh = 16/9 */
result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 25));
/* Set DUTY bit */
result |= I2C_DutyCycle_16_9;
}
/* Test if CCR value is under 0x1*/
if ((result & I2C_CCR_CCR) == 0)
{
/* Set minimum allowed value */
result |= (uint16_t)0x0001;
}
/* Set speed value and set F/S bit for fast mode */
tmpreg |= (uint16_t)(result | I2C_CCR_FS);
/* Set Maximum Rise Time for fast mode */
I2Cx->TRISE = (uint16_t)(((freqrange * (uint16_t)300) / (uint16_t)1000) + (uint16_t)1);
}
/* Write to I2Cx CCR */
I2Cx->CCR = tmpreg;
/* Enable the selected I2C peripheral */
I2Cx->CR1 |= I2C_CR1_PE;
/*---------------------------- I2Cx CR1 Configuration ------------------------*/
/* Get the I2Cx CR1 value */
tmpreg = I2Cx->CR1;
/* Clear ACK, SMBTYPE and SMBUS bits */
tmpreg &= CR1_CLEAR_MASK;
/* Configure I2Cx: mode and acknowledgement */
/* Set SMBTYPE and SMBUS bits according to I2C_Mode value */
/* Set ACK bit according to I2C_Ack value */
tmpreg |= (uint16_t)((uint32_t)I2C_InitStruct->I2C_Mode | I2C_InitStruct->I2C_Ack);
/* Write to I2Cx CR1 */
I2Cx->CR1 = tmpreg;
/*---------------------------- I2Cx OAR1 Configuration -----------------------*/
/* Set I2Cx Own Address1 and acknowledged address */
I2Cx->OAR1 = (I2C_InitStruct->I2C_AcknowledgedAddress | I2C_InitStruct->I2C_OwnAddress1);
}
|
_________________ Knowledge sharing is caring.
majerle.eu | stm32f4-discovery.net |
|
Nazaj na vrh |
|
|
jure94 Član
Pridružen-a: Sre 05 Maj 2010 17:11 Prispevkov: 433 Aktiv.: 2.56 Kraj: Jesenice / Lj
|
Objavljeno: Sre Nov 19, 2014 8:20 pm Naslov sporočila: |
|
|
To vem, da je 84MHz max clock, ampak v system_stm32f4xx.c je takole skonfigurirano:
Koda: |
* 5. This file configures the system clock as follows:
*=============================================================================
*=============================================================================
* Supported STM32F40xxx/41xxx devices
*-----------------------------------------------------------------------------
* System Clock source | PLL (HSE)
*-----------------------------------------------------------------------------
* SYSCLK(Hz) | 168000000
*-----------------------------------------------------------------------------
* HCLK(Hz) | 168000000
*-----------------------------------------------------------------------------
* AHB Prescaler | 1
*-----------------------------------------------------------------------------
* APB1 Prescaler | 4
*-----------------------------------------------------------------------------
* APB2 Prescaler | 2
*-----------------------------------------------------------------------------
* HSE Frequency(Hz) | 25000000
*-----------------------------------------------------------------------------
* PLL_M | 25
*-----------------------------------------------------------------------------
* PLL_N | 336
*-----------------------------------------------------------------------------
* PLL_P | 2
*-----------------------------------------------------------------------------
* PLL_Q | 7
*-----------------------------------------------------------------------------
* PLLI2S_N | NA
*-----------------------------------------------------------------------------
* PLLI2S_R | NA
*-----------------------------------------------------------------------------
* I2S input clock | NA
*-----------------------------------------------------------------------------
* VDD(V) | 3.3
*-----------------------------------------------------------------------------
* Main regulator output voltage | Scale1 mode
*-----------------------------------------------------------------------------
* Flash Latency(WS) | 5
*-----------------------------------------------------------------------------
* Prefetch Buffer | ON
*-----------------------------------------------------------------------------
* Instruction cache | ON
*-----------------------------------------------------------------------------
* Data cache | ON
*-----------------------------------------------------------------------------
* Require 48MHz for USB OTG FS, | Disabled
* SDIO and RNG clock |
Bom pregledal zgornjo kodo in upam, da mi bo potem jasno.
Hvala za hiter odgovor.
Lp
|
|
Nazaj na vrh |
|
|
tilz0R Član
Pridružen-a: Čet 31 Maj 2012 15:39 Prispevkov: 898 Aktiv.: 6.24 Kraj: Črnomelj
|
Objavljeno: Sre Nov 19, 2014 9:16 pm Naslov sporočila: |
|
|
To je že res.
Poglej še spodaj, kaj pravi SystemCoreClock spremenljivka in pa nastavitve, kot so PLL.
Sysclock = Crystal[MHz] / PLL_M * PLL_N / PLL_P
Vrjetno so nastavitve takšne:
#define PLL_M 8 //8MHz crystal
#define PLL_N 336
#define PLL_P 4
Če imaš pa nucleo, potem pa brez kristala furaš 16MHz, pa moraš ustrezno spremenit.
V default-u je predviden 25MHz kristal in je PLL tudi nastavljen tako. Preveri.
PS: ja, tako piše v tvojem opisu.
_________________ Knowledge sharing is caring.
majerle.eu | stm32f4-discovery.net
Nazadnje urejal/a tilz0R Sre Nov 19, 2014 10:59 pm; skupaj popravljeno 1 krat |
|
Nazaj na vrh |
|
|
jure94 Član
Pridružen-a: Sre 05 Maj 2010 17:11 Prispevkov: 433 Aktiv.: 2.56 Kraj: Jesenice / Lj
|
Objavljeno: Sre Nov 19, 2014 10:48 pm Naslov sporočila: |
|
|
Hvala za razlago. Imam Nucleo board ja, je pa PLL nastavljen za 25MHz kristal. Me pa zanima ali je dovolj, da spremenim HSE_VALUE v stm32f4xx.h (iz 25000000 v 16000000) in PLL_M na 16, da bo pravilno in, ali samo to dvoje spreminjam, če želim upoirabiti zunanji kristal (in seveda še ustrezne registre)?
Lp
|
|
Nazaj na vrh |
|
|
tilz0R Član
Pridružen-a: Čet 31 Maj 2012 15:39 Prispevkov: 898 Aktiv.: 6.24 Kraj: Črnomelj
|
Objavljeno: Sre Nov 19, 2014 10:52 pm Naslov sporočila: |
|
|
Nobenih registrov ni potrebno spreminjat, če želiš zunanji kristal.
Samo prlimaj gor kristal, ki naj bo cela številka gledano v MHz (4-26MHz) in temu primerno nastavi HSE_VALUE (lahko v stm32f4xx.h ali v preprocesor defines) ter PLL_M na enako vrednost (v MHz).
Če nimaš zunanjega kristala, bo sam štartal z notranjim.
V tem primeru nastavi PLL_M na 16 (ker je notranji HSI RC oscilator 16MHz)
_________________ Knowledge sharing is caring.
majerle.eu | stm32f4-discovery.net |
|
Nazaj na vrh |
|
|
jure94 Član
Pridružen-a: Sre 05 Maj 2010 17:11 Prispevkov: 433 Aktiv.: 2.56 Kraj: Jesenice / Lj
|
Objavljeno: Sre Nov 19, 2014 10:56 pm Naslov sporočila: |
|
|
Sem si že odgovoril, HSE je za zunanji kristal, HSI je pa notranjih 16MHz, torej samo spremenim PLL_M.
Lp
Edit: Sem imel odprto temo in nisem videl odgovora.
|
|
Nazaj na vrh |
|
|
tilz0R Član
Pridružen-a: Čet 31 Maj 2012 15:39 Prispevkov: 898 Aktiv.: 6.24 Kraj: Črnomelj
|
Objavljeno: Sre Nov 19, 2014 11:00 pm Naslov sporočila: |
|
|
Ne pozabi 2x po 22p kondenzatorjev.
_________________ Knowledge sharing is caring.
majerle.eu | stm32f4-discovery.net |
|
Nazaj na vrh |
|
|
jure94 Član
Pridružen-a: Sre 05 Maj 2010 17:11 Prispevkov: 433 Aktiv.: 2.56 Kraj: Jesenice / Lj
|
Objavljeno: Sre Nov 19, 2014 11:17 pm Naslov sporočila: |
|
|
Sem uspešno nastavil vse vrednosti, hvala za pomoč. Me pa samo teoretično zanima, kakšne vrednosti bi moral napisati v registre, da bi lahko imel I2C z 400kHz, če bi imel APB1 hitrost 42MHz, kot je maximum? Sem nekaj računal, pa nikakor ne dobim pravega rezultata.
Lp
|
|
Nazaj na vrh |
|
|
tilz0R Član
Pridružen-a: Čet 31 Maj 2012 15:39 Prispevkov: 898 Aktiv.: 6.24 Kraj: Črnomelj
|
Objavljeno: Sre Nov 19, 2014 11:18 pm Naslov sporočila: |
|
|
Pošteno povedano, pojma nimam.
Uporabljam STD periph driverje in se s tem ne ubadam, ravno zaradi problemov, kot jih imaš ti. Preveč bitov takšnih in drugačnih, kar zna samo glava bolet.
V zgornji kodi imaš pod "else" opcijo za hitrost za 400kHz mode.
Piše tudi sledeče:
/* To use the I2C at 400 KHz (in fast mode), the PCLK1 frequency (I2C peripheral
input clock) must be a multiple of 10 MHz */
_________________ Knowledge sharing is caring.
majerle.eu | stm32f4-discovery.net |
|
Nazaj na vrh |
|
|
jure94 Član
Pridružen-a: Sre 05 Maj 2010 17:11 Prispevkov: 433 Aktiv.: 2.56 Kraj: Jesenice / Lj
|
Objavljeno: Sre Nov 19, 2014 11:31 pm Naslov sporočila: |
|
|
tilz0R je napisal/a: |
Preveč bitov takšnih in drugačnih, kar zna samo glava bolet. |
Zato se pa omejim na ~1 uro reševanje problema , potem pa na google pogledat primere in, če mi še vedno ni jasno vprašam tukaj.
tilz0R je napisal/a: |
Piše tudi sledeče:
/* To use the I2C at 400 KHz (in fast mode), the PCLK1 frequency (I2C peripheral
input clock) must be a multiple of 10 MHz */
|
Vem ja, ampak tudio pri 40MHz se ne izide. Tako kot je sedaj je čisto vredu, če bom pa potreboval 40MHz, se bom pa takrat spet ubadal s tem.
Lp
|
|
Nazaj na vrh |
|
|
tilz0R Član
Pridružen-a: Čet 31 Maj 2012 15:39 Prispevkov: 898 Aktiv.: 6.24 Kraj: Črnomelj
|
Objavljeno: Sre Nov 19, 2014 11:38 pm Naslov sporočila: |
|
|
No sej to je fajn po eni strani.
Evo tako. Odprl sem moj example, ki je na githubu, skompilau kot 400kHz, ter šel debug, v priponki je vrednost strukture I2C1.
Sicer APB1 dela na 45MHz.
CR2 = 0x2D = 45, ti pa dej na 42 = 0x2A.
Opis: |
|
Velikost datoteke: |
14.77 KB |
Pogledana: |
7832 krat |
|
Opis: |
I2C 400kHz Nucleo F401 84MHz |
|
Velikost datoteke: |
15.08 KB |
Pogledana: |
7823 krat |
|
_________________ Knowledge sharing is caring.
majerle.eu | stm32f4-discovery.net |
|
Nazaj na vrh |
|
|
simeon Član
Pridružen-a: Pon 21 Maj 2007 21:55 Prispevkov: 118 Aktiv.: 0.58 Kraj: Šentjernej
|
Objavljeno: Ned Dec 21, 2014 5:39 pm Naslov sporočila: |
|
|
Kočno sem našel čas za stm32f4 in že naletel na težave.
Hočem aktivirati timer in mi naredi X pri #include "stm32f4xx_hal_tim.h"
V čem je težava?
Več v priloženem print scr.
[img]https://drive.google.com/file/d/0B0sF5K6LajLEbHBXUTBDUzZlMUk/view?usp=sharing[/img]
tim
_________________ Sej bo bolš! |
|
Nazaj na vrh |
|
|
tilz0R Član
Pridružen-a: Čet 31 Maj 2012 15:39 Prispevkov: 898 Aktiv.: 6.24 Kraj: Črnomelj
|
Objavljeno: Ned Dec 21, 2014 5:41 pm Naslov sporočila: |
|
|
Dodaj datoteko
stm32f4xx_hal_dma.c v projekt.
Ko boš to storil ti bo verjetno še kakšno vrgel.
Sicer ti pa zraven napake izpisuje tako da samo slediš kaj pravi napaka.
_________________ Knowledge sharing is caring.
majerle.eu | stm32f4-discovery.net |
|
Nazaj na vrh |
|
|
|
|
Ne, ne moreš dodajati novih tem v tem forumu Ne, ne moreš odgovarjati na teme v tem forumu Ne, ne moreš urejati svojih prispevkov v tem forumu Ne, ne moreš brisati svojih prispevkov v tem forumu Ne ne moreš glasovati v anketi v tem forumu Ne, ne moreš pripeti datotek v tem forumu Ne, ne moreš povleči datotek v tem forumu
|
Uptime: 48 dni
Powered by phpBB © 2001, 2005 phpBB Group
|