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   83 / 175
(#) cpt.zoltan.simon válasza silent15 hozzászólására (») Jan 9, 2017 /
 
Az interrupt handler:

  1. //Timer3 Interrupt handler starts conversion in every 250ms on K-Type Thermocoupler
  2. void TIM3_IRQHandler            (void)  __irq{
  3. NVIC->ICER[0] |= 0x20000000; //Disable TIM3 interrupt
  4. //IDE ÍROD AMIT PERIÓDIKUSAN SZERETNÉL
  5.  
  6. //Erase all bits needed for clean exit
  7. TIM3->SR--;     //Clear TIM3 Status register: Update Interrupt Flag
  8. NVIC->ICPR[0] |= 0x20000000; //Clear pending TIM2 interrupt
  9. NVIC->ISER[0] |= 0x20000000; //Enable TIM3 interrupt
  10.         }


Ez pedig a TIMER-hez a header file

  1. //TIM2-CR1
  2. #define         CKD(x)  (x << 8)
  3. #define         APRE(x) (x << 7)
  4. #define         CMS(x)  (x << 5)
  5. #define         DIR(x)  (x << 4)
  6. #define         OPM(x)  (x << 3)
  7. #define         URS(x)  (x << 2)
  8. #define         UDIS(x) (x << 1)
  9. #define         CEN(x)  (x << 0)
  10.  
  11. //TIM2->CR2
  12. #define         TI1S(x) (x << 7)
  13. #define         MMS(x)  (x << 4)
  14. #define         CCDS(x) (x << 3)
  15.  
  16. //TIM2->CCMR1 (input mode)
  17. #define         IC2F(x)         (x << 12)              
  18. #define         IC2PSC(x)       (x << 10)
  19. #define         CC2S(x)         (x << 8)
  20. #define         IC1F(x)         (x << 4)
  21. #define         IC1PSC(x)       (x << 2)
  22. #define         CC1S(x)         (x << 0)
  23.  
  24. //TIM2->CCER
  25. #define         CC1E(x)         (x << 0)
  26. #define         CC1P(x)         (x << 1)
  27.  
  28. //TIM2->DIER
  29. #define         TIE(x)          (x << 6)
  30. #define         CC4IE(x)        (x << 4)
  31. #define         CC3IE(x)        (x << 3)
  32. #define         CC2IE(x)        (x << 2)
  33. #define         CC1IE(x)        (x << 1)
  34. #define         UIE(x)          (x << 0)
(#) cpt.zoltan.simon hozzászólása Jan 10, 2017 /
 
Helló!

Van egy 429I Discovery board-om. A rajta lévő F103 két átforrasztható jumperrel tud csatlakozni a 429 PA9,10 lábaira USART céljából. Tehát a 429-re megírt USART az STLINK-en keresztül ki tudna dumálni a PC-nek putty-nak, hyperterm-nek.
Nagyon kevés infó van erről. És ez nem ugyan az mint az SWO ami a PB3 lábra menne. Az egész abból indult ki, hogy szeretném használni a Keil printf(Debug) screen-jét egy kis kényelem gyanánt.
Szóval van itt olyan aki már STLINK-V2-t rá tudta bírni hogy Debug mellett ugyan azon a szingli USB kábelen virtuális soros port legyen?
(#) icserny válasza cpt.zoltan.simon hozzászólására (») Jan 10, 2017 /
 
Az UART csatlakozás ott van a többi Discovery kártyán is, de nem jó semmire, mert az STLINK V2 firmware nem biztosít virtuális soros portot hozzá.

Amit te keresel, az valószínűleg a semihosting, amihez nem kell külön drót, hanem a debuggeren keresztül (SWDIO) kommunikál.
(#) cpt.zoltan.simon válasza icserny hozzászólására (») Jan 10, 2017 /
 
Végülis mindegy melyikkel foglalkozom. SWDIO talán annyiból jobb lenne, ahogy láttam core szinten van implementálva, és a Cortex mag része. Ilyen formán a core-cm4.h file-ban találtam is hozzá rutinokat. Jó kérdés, hogy hogy fog működni.
Akárhogy is, azt szeretném elérni, és ebben kérném a segítséget hogy:
Egy db USB kábel az ST-Link-en
PC képernyőre írja ki amit szeretnék debug jelleggel. pl a Printf ablakba.
Jah és a watch windows nem ér!
(#) icserny válasza cpt.zoltan.simon hozzászólására (») Jan 10, 2017 /
 
Erre gondoltál? STM32F4 Discovery and printf() redirection to debug viewer in Keil MDK-ARM Bővebben: Link
(#) cpt.zoltan.simon válasza icserny hozzászólására (») Jan 10, 2017 /
 
Pontosan erre. És végig is csináltam, csak éppen nem jelenik meg semmi a Printf ablakban.
(#) csabeszq válasza cpt.zoltan.simon hozzászólására (») Jan 10, 2017 /
 
Nem értek a dologhoz de itt egy cikk, hogyan lehet az ST-LINK V2-t SWO pinnel kiegészíteni:

https://lujji.github.io/blog/stlink-clone-trace/

Én rendeltem olyan st-link v2-t, amin van SWO:

https://www.aliexpress.com/item/Best-Quality-ST-Link-stlink-V2-for-...6.html
(#) csabeszq hozzászólása Jan 10, 2017 /
 
DMA-ról kérdeznék, ADC-t mintavételezek:
- circular módban folyamatosan jár
- normal módban feltölti a puffert és leáll

A kérdés normal módra vonatkozik. 32 mintavételes puffereket szeretnék, először az elsőt töltöm fel, utána a következőt,... viszont néha leállítom, amikor befejeztem a mintavételezést. Olyankor nem töltök fel több puffert.

Normal módot csak úgy tudtam újraindítani, hogy DMA disable -> DMA enable. Bármilyen flag-et töröltem (GL1, TC1, HT1, TE1), semmi sem történt, nem indult újra. Ez a helyes újraindítás, vagy van egyéb szebb módja is, hogy a lejárt DMA-t újraindítsam?
A hozzászólás módosítva: Jan 10, 2017
(#) csatti2 válasza csabeszq hozzászólására (») Jan 10, 2017 /
 
Jól csináltad. Idézet a kézikönyvből:
Idézet:
„If the channel is configured in noncircular mode, no DMA request is served after the last
transfer (that is once the number of data items to be transferred has reached zero). In order
to reload a new number of data items to be transferred into the DMA_CNDTRx register, the
DMA channel must be disabled.”
A hozzászólás módosítva: Jan 10, 2017
(#) icserny válasza cpt.zoltan.simon hozzászólására (») Jan 11, 2017 /
 
Idézet:
„...végig is csináltam, csak éppen nem jelenik meg semmi a Printf ablakban.”

Ezen az oldalon azt írják, hogy az STM32F429 Discovery kártyán az SB9 átkötést össze kell forrasztani. Gondolom, ez viszi el az SWO jelet az STlink-re.
(#) cpt.zoltan.simon válasza icserny hozzászólására (») Jan 11, 2017 /
 
Igen. Az is megtörtént. Ma majd jobban nekiugrom kialudtam magam. Igazság szerint (mellesleg, jelen helyzetben) nem sok értelme van a szenvedésemnek, a vége úgyis egy valós debug port valódi usart csatival (RJ11). Csak a kíváncsiság hajt(ott), ennél több időt viszont nem vagyok hajlandó egy zsákutcára àlldozni.
(#) csabeszq hozzászólása Jan 12, 2017 /
 
Egy vicces bug az STM32 API-ban. A problémám az, hogy 2 eszköz DMA-zik interrupttal, az egyik LCD-re és az interrupt sok számítást igényelt, a másik ADC-t mintavételez DMA-val, gyors reakcióra van szükség, viszont gyorsan véget is ér a rutin.

Azt vártam, hogy az ADC DMA interrupt preemptíven belehív az LCD interruptjába, amikor az éppen szüttyög, viszont API doksi ide, vagy oda, nem hívott az semmit. Megvárta, míg az LCD szépen lassan kiszámolja a végeredményt, utána pedig már sajnos késő volt.

A hibás kód:
  1. // 2 bit preemptív interruptnak, 2 bit alprioritásnak
  2. NVIC_PriorityGroupConfig( NVIC_PriorityGroup_2 );
  3.  
  4. NVIC_InitTypeDef NVIC_InitStructure;
  5.  
  6. // Ez lenne az ADC interrupt: 0/0 prioritással
  7. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  8. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  9. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  10. NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
  11. NVIC_Init(&NVIC_InitStructure);
  12.  
  13. // Ez pedig az LCD interrupt 2/1 prioritással
  14. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  15. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  16. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  17. NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
  18. NVIC_Init(&NVIC_InitStructure);


Az élet szép és jó, csakhogy a fenti kód nem működik.
Pár sort hozzá kellett raknom:
  1. // külön azért még beállítom a prioritást, mert fentebb úgysem fog sikerülni
  2. NVIC_SetPriority(DMA1_Channel1_IRQn, NVIC_EncodePriority(5,0,0));
  3. NVIC_SetPriority(DMA1_Channel5_IRQn, NVIC_EncodePriority(5,2,1));
  4. // az NVIC_EncodePriority(5,2,1)-ból az 5 jelenti a 2+2 bitet.
  5. // gondolom rajtam kívül mindenkinek tök logikus, hogy ha 2+2 bitet használsz
  6. // (prioritás/alprioritás), akkor 5-öt kell tenned az NVIC_EncodePriority-be.
  7. // Ki debuggoltam és ez adta a jó eredményt a köztes számításoknál.
  8. // Nem kell mindenen fennakadni, legyünk toleránsak a másként gondolkodók iránt.
  9. // - 0+4 bitnél 7-et írj
  10. // - 1+3 bitnél 6-ot
  11. // - 2+2 bitnél 5-öt
  12. // - 3+1 bitnél 4-et
  13. // - 4+0 bitnél 3-at


Szóval miután ügyesen még kézzel is beállítottuk a jó prioritást, valóban bele fog hívni az ADC csatorna DMA interruptja az LCD DMA interruptjába. Hurrá.
A hozzászólás módosítva: Jan 12, 2017
(#) csabeszq válasza csabeszq hozzászólására (») Jan 12, 2017 /
 
Ennyi elég és nem is fog bajt okozni később:

  1. NVIC_SetPriority(DMA1_Channel5_IRQn, NVIC_EncodePriority(5,2,1));
  2. NVIC_EnableIRQ(DMA1_Channe5_IRQn);


Az eredeti kóddal az a baj, hogy rossz regiszterbe ír, így jobb mellőzni a hívását, ha nem akarunk meglepetést később magunknak.
A hozzászólás módosítva: Jan 12, 2017
(#) csatti2 válasza csabeszq hozzászólására (») Jan 12, 2017 /
 
Azok a "másként gondolkodók" azért nem teljesen hülyék.

Az általad most használt funkciók a CMSIS részei, amit az összes hasonló ARM procihoz terveztek, legyen az M0, M3, M4, stb. és gyártsa az ST, NXP, Atmel, stb. . A specifikáció szerint max. 256 szint lehetséges, amiből az IC tervezője dönti el, hogy hány szintet implementál (min. 8, azaz 3bit). Mivel mindig az alsó nem használt bitek 0-ák, ezért a forráskódok elméletileg kompatibilisek maradnak akkor is ha egy több prioritásszintű uC-ről egy kevesebb szintet használó uC-re viszik át, lévén csak a legfinomabb prioritást hangoló bit(ek) vesznek el. Mivel a te általad használt uC 4 bitet használ a lehetséges 7-ből, ezért hát a 2+2bit konfiguráció teljesen jól kijön a 7-2 = 5 egyenlet megoldásaként .

Bónusz infó: Bár a subprioritás szintek első ránézésre (és második, harmadik stb. ránézésre is ) eléggé haszontalannak tűnnek, azért van némi hasznuk. Ezek a szintek ugyanis nem játszanak szerepet a megszakítások megszakításánál (nested interrupt ugye) csak a sorban álló ugyanolyan főprioritású megszakítások végrehajtási sorrendjénél számít az értékük.
A hozzászólás módosítva: Jan 12, 2017
(#) csabeszq válasza csatti2 hozzászólására (») Jan 13, 2017 /
 
Egyébként menet közben rájöttem, hogy nem bugos a kód.

Statikus konstruktor hívta meg az NVIC_Init-et és félreszámolt. Miután átraktam, hogy a main után állítsa be az interruptokat, működött.

Nem hasznontalan a szubprioritás. Nem mindig akarom, hogy egymást megszakítsák a rutinok, néha elég, ha sorrendben végrehajtódnak. Valljuk be, nehezebb preemption-ös interrupt handlert írni, mint ha nem lenne. Szórakozásból eszembe nem jutna saját magamat szívatni.

Csak akkor szakítsák meg egymást, ha indokolt, egyébként egyik lefuthat a másik után.
A hozzászólás módosítva: Jan 13, 2017
(#) icserny válasza cpt.zoltan.simon hozzászólására (») Jan 15, 2017 / 1
 
printf átirányítás SWO kimenentre Keil MDK alatt

Idézet:
„Végig is csináltam, csak éppen nem jelenik meg semmi a Printf ablakban.”

Nem csodálom, mert úgy látom, hogy az ebben a cikkben leírt printf átirányítás nem működik. Leírom, hogy nekem hogy sikerült:

0. Keil MDK Lite 5.20 van telepítve nálam. STM32F103C8T8-cal kísérleteztem, de ennek nincs jelentősége. A PB3 kivezetés az SWO kimenet.

1. Trace engedélyezés (úgy, ahogy a fenti cikkben írják): Trace enable pipa, CPU frekvencia a ténylegesen beállított legyen, s az ITM Stimulus Port 0-nál legyen pipa (lehet a többinél is, de ez kell)

2. Első körben csak ITM_SendChar(ch); hívásokkal próbálkoztam, ehhez nem kellett semmilyen bűvészkedés (ch helyére valamilyen karakterkódot vár a függvény).

Fordítás, debug módban programfuttatás esetén szépen pötyögtek a karakterek a debug printf ablakba.

3. Printf átirányítás: egy UART átirányítási mintapélda alapján az alábbi kódot szúrtam be a programba, s így működött a printf() debugolás is.

  1. //----- print átirányítás SWO kimenetre ------------
  2. #include <stdio.h>
  3. #pragma import(__use_no_semihosting_swi)
  4.  
  5. struct __FILE { int handle; /* Add whatever you need here */ };
  6.  
  7. FILE __stdout;
  8. FILE __stdin;
  9.  
  10. int fputc(int ch, FILE *f) {
  11.   ITM_SendChar(ch);
  12.   return (ch);
  13. }
  14.  
  15. void _sys_exit(int return_code) {
  16. label:  goto label;  /* endless loop */
  17. }
A hozzászólás módosítva: Jan 15, 2017

Blinky.zip
    
(#) Suncorgo hozzászólása Jan 22, 2017 /
 
Sziasztok, sajnos az STM32F103-ban nincs EEPROM. Lehetséges a FLASH egy adott szabad területét, pl. a végét EEPROM-ként használni? Hogyan?
A hozzászólás módosítva: Jan 22, 2017
(#) icserny válasza Suncorgo hozzászólására (») Jan 22, 2017 /
 
Innen kezdve olvass időben visszafelé.
(#) csabeszq hozzászólása Jan 23, 2017 /
 
ADC kérdésem lenne. Két csatornán mintavételezek, néha szükségem lenne injected ADC-re, hogy beolvassam a joystick állását.

Beállítás:
  1. // injected csatornák beállítása
  2. ADC_InjectedSequencerLengthConfig(ADC1, 1);
  3. ADC_InjectedSequencerLengthConfig(ADC2, 1);
  4. ADC_InjectedChannelConfig( ADC1, getADCChannel(PIN_JOYX), 1, ADC_SampleTime_1Cycles5 );
  5. ADC_InjectedChannelConfig( ADC2, getADCChannel(PIN_JOYY), 1, ADC_SampleTime_1Cycles5 );
  6. ADC_ExternalTrigInjectedConvConfig( ADC1, ADC_ExternalTrigInjecConv_None );
  7. ADC_ExternalTrigInjectedConvConfig( ADC2, ADC_ExternalTrigInjecConv_None );
  8.  
  9. ...
  10.  
  11. // injected ADC indítása
  12. ADC_SoftwareStartInjectedConvCmd( ADC1, ENABLE );
  13. while(ADC_GetSoftwareStartInjectedConvCmdStatus(ADC1) != RESET);
  14.  
  15.  
  16. unsigned joyx = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_1);


A probléma az, hogy kizárólag az ADC1 dolgozik, ADC2 nem. Párhuzamosan egyszerre kellene master/slave ADC-nek olvasni a joysticket, ez pedig nem történik meg. Mi lehet a hiba?

ADC_Mode_RegInjecSimult-ot használok...
A hozzászólás módosítva: Jan 23, 2017
(#) csabeszq válasza csabeszq hozzászólására (») Jan 23, 2017 /
 
Így működik, csak nem szeretném külön-külön kézzel indítgatni a 2 ADC-t: Jó lenne, ha tényleg párhuzamosan mennének.

  1. ADC_SoftwareStartInjectedConvCmd( ADC1, ENABLE );
  2. ADC_SoftwareStartInjectedConvCmd( ADC2, ENABLE );
  3. while(ADC_GetSoftwareStartInjectedConvCmdStatus(ADC1) != RESET);
  4. while(ADC_GetSoftwareStartInjectedConvCmdStatus(ADC2) != RESET);
  5.  
  6. unsigned joyx = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_1);
  7. unsigned joyy = ADC_GetInjectedConversionValue(ADC2, ADC_InjectedChannel_1);
(#) icserny válasza csabeszq hozzászólására (») Jan 23, 2017 /
 
- Az ADC DUALMODE biteket mire állítottad?
- Sorrend: van egy olyan megjegyzés, hogy a fenti biteket a konfigurálás elején célszerű nullázni (independent mód), és csak a konfigurálás végén beállítani.
(#) csabeszq válasza icserny hozzászólására (») Jan 23, 2017 /
 
ADC_Mode_RegInjecSimult (00001)

A duális mód működik, szépen mintavételezem mindkét csatornát, az érkező ADC 32 bites, alsó 16 ADC1, a felső 16 ADC2.

Az injected mód gondolom nem így működik. A JDR1..4 regiszterek 16 bitesek, szóval nincs értelme 32 bites értéket kiolvasni belőle.

Egyszerre kellene indítani a 2 ADC-t, de csak az egyik indul el, vagy nem tudom, hogy a másik hol tárolódik el.
A hozzászólás módosítva: Jan 23, 2017
(#) icserny válasza csabeszq hozzászólására (») Jan 23, 2017 /
 
Injektált csatornák szimultán konverziójánál az adatlap szerint mindegyik ADC saját JDRx regiszterében lesz az adat (tehát ADC1_JDR1, ADC2_JDR1 stb).

Reguláris csatornák szimultán konverziójánál az ADC2 eredménye valóban átkerülhet az ADC1 adatregiszterének felső felébe, de ehhez a DMA bitet engedélyezni kell:
Idézet:
„In dual ADC mode, to read the slave converted data on the master data register, the DMA bit must be enabled even if it is not used to transfer converted regular channel data.”
(#) csabeszq válasza icserny hozzászólására (») Jan 23, 2017 / 1
 
Regisztráltattam magamat az st.com-on, így hozzá tudtam férni a példa adatbázisukhoz. Ott en.stsw-stm32028.zip néven (AN3116) hozzáférhetőek az ADC példaprogramok. Nem tudtam, hogy ingyenesek, de szerencsére elég volt szimplán a regisztráció.

A példákból 5 perc alatt kiderült a hiba, 2 sor hiányzott:

  1. ADC_ExternalTrigInjectedConvCmd( ADC1, ENABLE );
  2. ADC_ExternalTrigInjectedConvCmd( ADC2, ENABLE );


Magyarul engedélyezni kellett az injected triggert, onnantól ment minden flottul. Mindig tanul az ember.
(#) csatti2 válasza csabeszq hozzászólására (») Jan 23, 2017 /
 
Sőt, ha céges emailre regisztráltál, akár még ingyen uC-ket is kérhetsz tőlük mintaként. Csak ne élj vissza vele, mert másokkal is kiszúrhatsz.
(#) kapu48 válasza Suncorgo hozzászólására (») Jan 24, 2017 /
 
(#) csabeszq hozzászólása Jan 26, 2017 /
 
Egy videó a készülő oszcilloszkópról:
Link itt

Kapcsolási rajz csatolva.

A fenti sorban 4 érték van 2 csatornához:
- átlag, min, max, effektív érték
- lent az időosztás, min-max alapján számított frekvencia

A trigger láthatóan még nem megy, a PGA-val (programozható erősítéssel) sem járok sehol.

A mintavételezést a TIM1 timer indítja. 5 kHz-es PWM teszt jelet raktam ki egyik pinre, rá egy ellenállás és egy kapacitás.

Érdekességként: amikor LCD-vel kommunikálok, akkor nem mintavételezek. 0.5% körüli ADC zajszintet produkált a 9 MHz-es SPI átvitel az LCD felé. Ez eléggé durva. A kód képes zajszintet is mérni (azt méri, hogy a 0 jel mennyire stabil). Amikor a teszt PWM-et felkapcsolom, láthatóan romlik a zajszint. Magyarul ha mintavételezésnél se teszt PWM, se LCD nincs, akkor pontos. Ekkor 0.1% hibahatár alá kerül a mintavételezés.
A hozzászólás módosítva: Jan 26, 2017
(#) csatti2 válasza csabeszq hozzászólására (») Jan 26, 2017 /
 
Jelenleg egy próbapanelen dugdostál össze egy kezdetleges áramkört mindenféle szűrés és analóg leválasztás nélkül. Ez van. Majd ha megtervezed nyákra, akkor figyelj oda ezekre.

Azt a nagyértékű kondit a referenciafeszültségen majd gondold át. Az semmit sem szűr a nagyfrekvenciás zajokból, ráadásul potenciálisan stabilitási problémák lehetnek vele.

A trimmerre semmi szükség. Használj két nagy értékű ellenállást ellenállásosztóban egy 100nF-os kondival szűrve. A referenciafeszt (virtuális föld) úgyis a tápfesz közepén lesz a legjobb elhelyezned. A másik lehetőség, hogy egy "charge pump" IC-vel csinálsz magadnak negatív tápfeszt, ekkor azonban gond lehet a használt műveleti erősítőiddel (túl nagy lesz a tápfesz).
(#) benjami válasza csabeszq hozzászólására (») Jan 26, 2017 /
 
Szerintem érdemes körbenézni az ARM-es digit szkóp projectek között (van egy pár darab), onnan lehet ötleteket meríteni. Nekem van is egy DSO138-asom, a régebbi verziós szoftverének elérhető a forráskódja. Ugyanezzel a 48 lábú stm32f103-al van az is megcsinálva, igaz az csak egy csatornás. Az stm32f429-et tartalmazó discovery panelemhez is van szkóp project forrásostul, az már több csatornás.
Amúgy nem túl lassú az SPI kijelző ehhez? A DSO138-ban 8bites párhuzamos a kijelző, a discovery-n meg 18bites párhuzamos, ott nincs is sebesség probléma.
(#) csabeszq válasza benjami hozzászólására (») Jan 27, 2017 /
 
Amikor a feleségemnek azt javasolgatom, hogy nem kell főzni, rendeljünk ebédet, finoman szólva is elhajt a csudába. Hagyni kell a gyermeket önállóan játszani, nem kell készen mindent a kezébe adni.

A DSO138 egy csatornás, nincs benne PGA és egy rahedli pénzért adják. Annyiba kerül, amennyit szerintem nem ér.
A hozzászólás módosítva: Jan 27, 2017
Következő: »»   83 / 175
Bejelentkezés

Belépés

Hirdetés
Lapoda.hu     XDT.hu     HEStore.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