Fórum témák

» Több friss téma
Fórum » ARM - Miértek hogyanok
 
Témaindító: gtk, idő: Jún 26, 2007
Lapozás: OK   69 / 177
(#) don_peter válasza Topi hozzászólására (») Máj 18, 2016 /
 
Köszi, pont erre voltam kíváncsi.
Kacsingatok az ARM-ek irányába is, szóval majd ki akarom próbálni mit is tud.
(#) SBahadurD válasza SBahadurD hozzászólására (») Máj 19, 2016 / 2
 
Ha érdekel valakit:
FMC esetén SDRAM-ból való futtatáshoz az SDRAM-t át kell mappelni a NAND Bank 2/PCCARD területre, ha kódot akarunk futtatni belőle. Innentől kezdve az SDRAM bank1 címe 0xC0000000 helyett a 0x80000000-on, az SDRAM bank2 címe 0xD0000000 helyett 0x90000000-on fog kezdődni.
A remappeléshez a Syscfg memory map regiszterének 10-es bitjét 1-be kell állítani.
(#) nanasi hozzászólása Máj 27, 2016 /
 
Sziasztok!

lenne 1kérdésem:
F3Disocvery kártyával szeretnék bemenő jel kitöltési tényezőt mérni.
bldc motort vezérelnék szervo jellel. a szervo jel Teljes periódus 20msec a vezélrlés 1ms-2ms között van(5és 10%között van a kitöltési tényező)

timer input capture mode + megszakitásokkal kellene valamit csinálni?
köszi
(#) cimopata hozzászólása Jún 6, 2016 /
 
Üdv.

HAL könyvtárban melyik az a függvény ami meghívódik ha a PWM pulzus véget ér?
Pontosabban STM32-n TIM16-al akarok egy meghívást ha a számláló eléri a megadott értéket.

  1. void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
  2. {
  3.         if(htim->Instance==TIM3)
  4.                 {
  5.         GPIOA->ODR = GPIOA->ODR | 0x08;
  6.                 GPIOA->ODR = GPIOA->ODR & 0xFFF7;
  7.                 }
  8. }


Ezt próbáltam de nem akar menni.
(#) cimopata hozzászólása Jún 7, 2016 /
 
Sikerült rájönnöm, bár az időzítók mind el voltak indítva és a hozzá tartozó megszakítások is de még be kellett tennem + ba ezt és végül másik időzítővel oldottam meg.
  1. HAL_TIM_OC_Start_IT(&htim3,TIM_CHANNEL_2);


Másik kérdés: Van egy művelet ami nagyon sokáig tart egész pontosan 12,5us.
Milyen módon lehetne gyorsítani a művelet végzését mert ez kicsit soknak tűnik?
  1. duty_n1 = (aram_ref * (duty_n0+1))/(aram_dis+1);

aram_dis long típus a másik 3 mind short típusú változó.
A hozzászólás módosítva: Jún 7, 2016
(#) SBahadurD válasza cimopata hozzászólására (») Jún 7, 2016 /
 
Valószínűleg az osztás az, ami baromi hosszú. Milyen magú mikrovezérlőd van? Cortex M3-ban vans már szorzó, Cortex-M4-ben osztó is. Ezekkel nem kéne eddig tartania. Ha csak nem nagyon alacsony a órajel.
(#) don_peter válasza cimopata hozzászólására (») Jún 7, 2016 /
 
Nem float típusúnak kellene lennie az osztás miatt?
Lebegőpontos számot kapsz osztás után, vagy is kaphatsz.
Bár ez pont nem is volt kérdés.
Gyorsítani ezt nem hiszem, hogy lehet, ha csak nem az órajelet emeled.
(#) cimopata válasza SBahadurD hozzászólására (») Jún 7, 2016 /
 
STM32F030 48Mhz-en megy.
(#) SBahadurD válasza cimopata hozzászólására (») Jún 7, 2016 /
 
Cortex M0 és 48 MHz? Hát akkor attól nehéz sokat várni. Esetleg lehet, hogy ha nagyjából sejted, hogy milyen értékeket vársz, akkor esetleg lehet optimalizálni. Disassemblyben meg lehet nézni, hogy milyen asm kódot fordít ide a fordító.
(#) cimopata válasza SBahadurD hozzászólására (») Jún 7, 2016 /
 
Oké akkor ezzel majd még kezdek valamit egyenlőre kihúzom így.
Viszont mértem egy másik rész is ahol szorzok és az még durvább

A GPIOA 100ns-körül van ami elhanyagolható a mérés szempontjából viszont ez az egyszerű szorzás 22us-ig tart ami tényleg rengeteg.
  1. GPIOA->ODR = GPIOA->ODR | 0x10;                        
  2. aram_dis=aram_dis*0,97;
  3. GPIOA->ODR = GPIOA->ODR & 0xFFEF;
(#) cimopata hozzászólása Jún 7, 2016 /
 
Másik amit nem értek, hogy van két timer (3,14) Be van állítva a 3-as 480-as előosztásra és 1000-ig számol. Ez 10ms periódus idő és 10-ig számol azaz aza 100us impulzust csinál. A képen ez a sárga ami stimmel is.
Viszont a timer 14-el vannak bajok (kék) aminek 48 az órajel osztása és 10-ig számol. Ez 10us-re kellene hogy kijöjjön.
Amikor a periódus végez megszakításban billegteti az egyik kimenetet de mint látható elég durva hibával.
Oké hogy a megszakítás + kimenet billegtetése kissé késlelteti a dolgokat de itt már magában a periódusidőval bajok vannak ugyanis 10us helyett 10-12% al mindig több.

A 10ms-alatt kellene csináljon pontosan 1000 tűskét de a nagyobb periódusidő miatt ez jó ha 910-920.

Miért van ez?

IMAG0525.jpg
    
(#) don_peter válasza cimopata hozzászólására (») Jún 7, 2016 /
 
Itt is lebegőpontos szorzás van.. Nem lehet, hogy emiatt van a gond?
Típusmódosítókkal teszteld, hátha segít..

Idézet:
„Viszont a timer 14-el vannak bajok (kék) aminek 48 az órajel osztása és 10-ig számol. Ez 10us-re kellene hogy kijöjjön.”
Csinál valamit megszakításban?
(#) SBahadurD válasza don_peter hozzászólására (») Jún 7, 2016 /
 
Hát igen, a lebegőpontos szorzás az még belerondít a dolgokba... De ha a feladat ezt követeli, akkor ez van.
Viszont, mivel itt az egyik szorzó operandus konstans, megoldhatod pl. táblázattal is a dolgot, ha maradt elég programmemóriád, és esetleg a változó operandusról is lehet tudni nagyjából, hogy milyen értékeket vesz fel, hogy lesz később az eredmény feldolgozva, stb... Vannak trükközési lehetőségek kis megszorítással...
(#) cimopata válasza don_peter hozzászólására (») Jún 7, 2016 /
 
Idézet:
„Itt is lebegőpontos szorzás van.. Nem lehet, hogy emiatt van a gond?
Típusmódosítókkal teszteld, hátha segít..”


Lecseréltem egy egyszerűbb megoldásra. Így már csak 12,5us
  1. aram_dis=aram_dis*97;
  2. aram_dis=aram_dis/100;


Idézet:
„Csinál valamit megszakításban?”


Csinál igen. Kiolvassa a mintát az ADC tárolóból de az nem több 1us-nál.
A hozzászólás módosítva: Jún 7, 2016
(#) don_peter válasza cimopata hozzászólására (») Jún 7, 2016 /
 
Akkor ez pont semmit nem ért.
Előzőleg is pont ennyi volt a mért sebesség.

És nem lehet, hogy ennek a kiolvasása adódik össze hosszútávon és eredményezi a sebesség csökkenést?
Mert gondolom a megszakításba azért csak van még néhány utasítás.
Egy PIN magas majd alacsony szintre állítása, megszakítás flag törlése, esetleg egy feltétel...stb (csak ötletelek)
(#) cimopata válasza don_peter hozzászólására (») Jún 7, 2016 /
 
Jelenleg 500 mintát veszek de annak kell 5,65ms mire látom hogy befejezi az utolsót is. 0,65ms-el több a kelleténél.
(#) cimopata válasza don_peter hozzászólására (») Jún 7, 2016 /
 
Berakom a kódot hogy érthető legyen.
  1. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  2.         {
  3.                 if(htim->Instance==TIM3)
  4.                                 {      
  5.                                 ...// most nem lényeg
  6.                                 }
  7.                                
  8.  
  9.  
  10.                 if(htim->Instance==TIM14)
  11.                                 {      
  12.                                        
  13.                                         if(minta<500)
  14.                                                 {
  15.                                                 GPIOA->ODR = GPIOA->ODR | 0x10;
  16.                                        
  17.                                         //aram_dis=aram;                                       
  18.                                        
  19.                                         /*ADC1->CHSELR  = 1<<2; //IN_2 kijelölés , P2 poti mérés
  20.                                         ADC1->CR  = 5;
  21.  
  22.                                         while( !(ADC1->ISR & (1<<2)) );
  23.                                         aram = ADC1->DR;*/             
  24.                                         aram= ADC1->DR;
  25.                                         minta++;
  26.                                         aram_sum=aram+aram_sum;
  27.                                         if(minta==500)
  28.                                                 {
  29.                                                          
  30.                                                 aram_dis=(aram_sum/minta)-offset;
  31.                                                
  32.                                                
  33.                                                
  34.                                        
  35.                                                 aram_dis=aram_dis*97;
  36.                                                         aram_dis=aram_dis/100;
  37.                                                          
  38.                                                        
  39.                                                 }
  40. GPIOA->ODR = GPIOA->ODR & 0xFFEF;
  41.                                                 }
  42.                                        
  43.                                 }      
  44.         }


Tim3 10m-onként hívódik meg tim 14 nek kellene 10us-onként. Az egésu megszakítás minden benne levő művelettel nem több mint 1us. A PIN billegtetése a belépésél és a kilépésnél van szóval mindent beleérve 1us.
A hozzászólás módosítva: Jún 7, 2016
(#) don_peter válasza cimopata hozzászólására (») Jún 7, 2016 /
 
Ez csak a timer3 rész nem?
A megszakításra lennék kíváncsi, mert gondolom az teljesen külön van ARM-nél is.

Egy észrevétel..
A switch() elosztót nézd meg, hogy mire fordítja ASM-ben és esetleg azt cseréld le if feltételre, szerintem ott nyerhetsz még időt.

Egyébként miért kell 500 minta?
Mert gondolom úgy is az átlagot fogod megkapni a végén nem?
Lehet elég lenne sokkal kevesebb minta.
Én például 10 mintát és annak az átlagát szoktam venni áram és feszültség mérésnél is..
Nem igen kell több.
A hozzászólás módosítva: Jún 7, 2016
(#) cimopata válasza don_peter hozzászólására (») Jún 7, 2016 /
 
Csináltam egy ilyet:

  1. void TIM3_IRQHandler(void)
  2. {
  3.   /* USER CODE BEGIN TIM3_IRQn 0 */
  4. GPIOA->ODR = GPIOA->ODR | 0x08;
  5.   /* USER CODE END TIM3_IRQn 0 */
  6.   HAL_TIM_IRQHandler(&htim3);
  7.   /* USER CODE BEGIN TIM3_IRQn 1 */
  8. GPIOA->ODR = GPIOA->ODR & 0xFFF7;
  9.   /* USER CODE END TIM3_IRQn 1 */
  10. }
  11.  
  12. /**
  13. * @brief This function handles TIM14 global interrupt.
  14. */
  15. void TIM14_IRQHandler(void)
  16. {
  17.   /* USER CODE BEGIN TIM14_IRQn 0 */
  18. GPIOA->ODR = GPIOA->ODR | 0x10;
  19.   /* USER CODE END TIM14_IRQn 0 */
  20.   HAL_TIM_IRQHandler(&htim14);
  21.   /* USER CODE BEGIN TIM14_IRQn 1 */
  22. GPIOA->ODR = GPIOA->ODR & 0xFFEF;
  23.   /* USER CODE END TIM14_IRQn 1 */
  24. }


Sárga a timer3 kék a timer 14

Egy kép teljes 10ms a másik nagyítva.
(#) cimopata hozzászólása Jún 7, 2016 /
 
Csináltam most egy olyat is hogy kiszedtem mindent a programból csak maradt a 3 üres megszakítás meghívása de így is ugyan az a helyzet. Az mondjuk elég érdekes hogy semmit nem csinál így is benne van a megszakításban 3,5us-ig.
(#) don_peter válasza cimopata hozzászólására (») Jún 7, 2016 /
 
No igen ez így már elég érdekes
Hirtelen nem is tudok mit mondani..

Tápfesz mennyire stabil?
Mert esetleg, attól lehet ilyesmi, hogy a kvarcot zavarja így az órajeled változik.
(#) benjami válasza cimopata hozzászólására (») Jún 7, 2016 /
 
Mekkora lehet az aram_dis legnagyobb értéke? Úgy kell megválasztani a szorzót, hogy az utána történő osztás a kettő egész számú hatványával történjen (ez ugye csak bittologatást jelent).
(#) Atielektro válasza cimopata hozzászólására (») Jún 7, 2016 /
 
STM32Cube-bal generált kódot használsz? Ha igen, akkor számítsd bele, hogy belegenerálja a SysTic megszakítását, ami magas prioritású, így simán csúszhat a user megszakítások kiszolgálása, ez lehet egy ok a nem determinisztikus időközre így vagy úgy.
A másik, hogy megnyitottad már ezeket az IRQ handlereket? elég terjengős a belük, én nagyon nem szeretem őket.
(#) cimopata válasza don_peter hozzászólására (») Jún 7, 2016 /
 
Nincs kvarc. HSI RC-ról megy azt valahogy felszorozza meg PLL-lel játszik.

Gondoltam erre is de úgy vagyok vele hogy akkor a 10ms-sem lenne annyi hanem az is több lenne mert az is csak órajelekről pörgeti a számolást.

Viszont átírtam a timer beállítást.
  1. void MX_TIM14_Init(void)
  2. {
  3.  
  4.   htim14.Instance = TIM14;
  5.   htim14.Init.Prescaler = 1;
  6.   htim14.Init.CounterMode = TIM_COUNTERMODE_UP;
  7.   htim14.Init.Period = 240;
  8.   htim14.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  9.   HAL_TIM_Base_Init(&htim14);
  10.  
  11. }


Eddig 48 előosztás volt és 10 az init perios ami adta volna a 10-et. Értelem szerűen átírtam először 1/480-ra, de úgy kereken 20us- ot adott. Na mondom mi a f. azt meg hogy? Befeleztem aminek jóformán semmi értelme, viszont így kiadja a 10us-ot. Mi ebben a ráció?
(#) cimopata válasza Atielektro hozzászólására (») Jún 7, 2016 /
 
Igen STMCUBE-al. Jelenlegi tapasztalatom szintjén sajnos jelenleg ezzel tudok csak dolgozni. Így is el szöszmötölök vele... You know what I mean
(#) cimopata válasza Atielektro hozzászólására (») Jún 7, 2016 /
 
Egyébként nem is a nem determinisztikus időközökkel van a baj mert akkor ez csupán csúszást jelentene hanem itt jóformán olyan mintha tovább számolna és emiatt kissebb nagyobb késés hanem 10%-al lassabb.
(#) Atielektro válasza cimopata hozzászólására (») Jún 7, 2016 /
 
Ha jól emlékszem, akkor a SysTick CTRL regiszterének 0-ázása kikapcsolja a SysTick-et, így hiába van engedélyezve a megszakítás, számolás nélkül sokminden nem lesz belőle:

SysTick->CTRL = 0; -át dobd be valahová a kód elejére, a gyári init-ek után.

Egyébkánt a 3.5 usec 48 MHz-es órajel mellet ( ha az átfutásokból jól vettem ki, akkor ennyi az órajeled ) 168 utasítás. Kicsit sokat időzik a cucc azokban a Handler-ekben. Valamennyit az is segíthet első körben, ha feltolod az optimalizációt, ha ezzel még nem próbálkoztál.

Nem rossz az a Cube, én is azt használom, csak időkritikus részeknél haszontalan, de konfigurálásoknál szeretem, bár így is sokszor kell a debugger-ben nézegetni, hogy melyik bitet mire állította a kód...
A hozzászólás módosítva: Jún 7, 2016
(#) cimopata válasza Atielektro hozzászólására (») Jún 7, 2016 /
 
Idézet:
„Valamennyit az is segíthet első körben, ha feltolod az optimalizációt, ha ezzel még nem próbálkoztál.”


Jelenleg tök üres a program. Mit értesz optimalizáció alatt? A terjengős belekre gondolsz mert olyan szinten nem tartok, hogy azokba piszkáljak.

Egyébként mit mondasz a jelenlegi 1/240 beállításra mert ezzel konkrétan 5us-ot kellene hogy adjon, de így ad csak 10us-ot.
(#) Atielektro válasza cimopata hozzászólására (») Jún 7, 2016 /
 
A fordító beállítására gondolok. keil-ben 3 szint van és talán, ha jól emlékszem, 1-esen dogozik alapból.

A prescaler értéklhez hozzáadtál fejben egyet? Mert nekem 10 usec jön ki.

[240*(1+prescaler)]/48MHz = 10 usec

Bővebben

A 10. oldalon találsz erre egy összefüggést
A hozzászólás módosítva: Jún 7, 2016
(#) cimopata válasza Atielektro hozzászólására (») Jún 7, 2016 /
 
Idézet:
„A fordító beállítására gondolok. keil-ben 3 szint van és talán, ha jól emlékszem, 1-esen dogozik alapból.”


Level3-on van.

Idézet:
„[240*(1+prescaler)]/48MHz = 10 usec”


Ezt nem tudtam így már ok. Kösz.
Következő: »»   69 / 177
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem