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   74 / 177
(#) kapu48 válasza icserny hozzászólására (») Aug 20, 2016 /
 
Köszi, ezt a linket!

Pont ilyesmit reméltem találni.

Lesz mivel kísérleteznem a hétvégén.
(#) cimopata hozzászólása Aug 21, 2016 /
 
Szeretnék invertált kimenetet csinálni 2 pwm csatornán. Be is állítottam a 2-3 csatornán a CH2 CH2N illetve a CH3CH3N funkciót. Akárhogy variálom a beállításokat nem hajlandó megjelenni az invertált kimenet ránéznétek a beállításaimra: CH2 CH3 adja a PWM-et de a N-es kimeneteken semmi.

  1. TIM_ClockConfigTypeDef sClockSourceConfig;
  2.   TIM_MasterConfigTypeDef sMasterConfig;
  3.   TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;
  4.   TIM_OC_InitTypeDef sConfigOC;
  5.  
  6.   htim1.Instance = TIM1;
  7.   htim1.Init.Prescaler = 0;
  8.   htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED3;
  9.   htim1.Init.Period = 2600;
  10.   htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  11.   htim1.Init.RepetitionCounter = 0;
  12.   HAL_TIM_Base_Init(&htim1);
  13.  
  14.   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  15.   HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig);
  16.  
  17.   HAL_TIM_PWM_Init(&htim1);
  18.  
  19.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  20.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  21.   HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig);
  22.  
  23.   sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
  24.   sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
  25.   sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
  26.   sBreakDeadTimeConfig.DeadTime = 0;
  27.   sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
  28.   sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  29.   sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
  30.   HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig);
  31.  
  32.   sConfigOC.OCMode = TIM_OCMODE_PWM1;
  33.   sConfigOC.Pulse = 0;
  34.   sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  35.   sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  36.   sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  37.   sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
  38.   sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  39.   HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2);
  40.  
  41.   HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3);
A hozzászólás módosítva: Aug 21, 2016
(#) cimopata hozzászólása Aug 21, 2016 /
 
Egy kép a beállításokról:

DT.jpg
    
(#) cimopata hozzászólása Aug 21, 2016 /
 
Közben sikerült megtalálni hol volt a baj. A cubeMX természetesen nem állít be mindent hiába várjuk el tőle. Mindenhol írja a komplementer kimenetet egyéb beállításait de a legfontosabb hogy bekapcsolni valahogy elfelejti.
Utólag hozzá kellett adjak 2 sort:
  1. TIM1->CCER |= TIM_CCER_CC2NE;
  2.         TIM1->CCER |= TIM_CCER_CC3NE;
(#) cimopata hozzászólása Aug 24, 2016 /
 
Üdv.

Ebben a megszakítás függvényben mit kéne módosítanom hogy visszadja a speed értékét és a main-ben tudjam használni:

  1. void TIM1_BRK_UP_TRG_COM_IRQHandler(void)
  2. {
  3. if(TIM1->SR & TIM_SR_UIF) // if UIF flag is set
  4.   {
  5.   TIM1->SR &= ~TIM_SR_UIF; // clear UIF flag
  6.                 GPIOB->BRR = (1 << 6); //reset PC8     
  7.         GPIOB->BSRR = (1 << 6); //set PC8      
  8.                
  9.         speed_x128=speed_x128 + 10;
  10.         speed_x128buff=speed_x128 & 0xFFF80;
  11.         speed=speed_x128buff >> 7; // osztás 128-al
  12.         if(speed>adc_store[4])
  13.                 {
  14.                         speed=adc_store[4];
  15.                         speed_x128=(adc_store[4] <<7);
  16.                 }
  17.        
  18.  
  19.   }
  20. }
(#) cpt.zoltan.simon válasza cimopata hozzászólására (») Aug 24, 2016 /
 
Nekem van egy nagyon halovány emlékképem, hogy megszakítás az nem adhat vissza értéket. De egyáltalán nem biztos hogy jól tudom. Egyszer mindenesetre én is próbálkoztam vele, és akkor ebben a témában hisztizett a KEIL fordítója.

Én azt csinálnám hogy a speed egy globális változó lenne, mindig olvasható. Az mérete legyen nagyobb mint az értéke lehet, és a legfelső bit legyen az "aktuális" bit. Azaz ISR-en belül 0, azaz ne olvasd az értéket mert éppen újat adok, amikor meg kilépsz a bit legyen 1, tehát aktuális, jó érték. Pl egy unsigned long 31. bitje.
(#) cimopata válasza cpt.zoltan.simon hozzászólására (») Aug 24, 2016 /
 
Ezt nem értem. Igazából az egész dolog nem világos nekem azért mert egy másik programomban amiben ugyan még a lassabb HAL-os megszakítással veszek adott időközönként az ADC-vel mintét amit egy változóba ment és azt utána tudom használni a main-ben.

Ugyan ez itt nem működik. Ha berakom a main-be ott megy.
(#) aticska válasza cimopata hozzászólására (») Aug 24, 2016 / 1
 
volatile ?
(#) cimopata válasza aticska hozzászólására (») Aug 24, 2016 /
 
Másképp kéne deklarálni? Mire gondolsz?
(#) aticska válasza cimopata hozzászólására (») Aug 24, 2016 /
 
Ha megszakításban használsz külső változót, mindenképpen volatile legyen.
(#) killbill válasza cpt.zoltan.simon hozzászólására (») Aug 24, 2016 /
 
Idézet:
„Nekem van egy nagyon halovány emlékképem, hogy megszakítás az nem adhat vissza értéket.”
Igazából kinek is adna vissza értéket? Hiszen nem egy függvényként hívja meg a program egy ponton, hanem a HW indítja el és a végén oda tér vissza, ahol az éppen futott programot megszakította.
(#) cimopata válasza aticska hozzászólására (») Aug 24, 2016 /
 
Átírtam de nem megy.
Nem értem.
Másik programban van hasonló megoldás amikor ac adc vesz mintét 990 minta után átlagol és menti az aram_dis be az eredményt amit utána ugyan úgy használok fel a main-ben akárcsak most használnám a speed-et.

  1. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  2.         {       if(htim->Instance==TIM14)
  3.                                 {      
  4.                                        
  5.                                         if(minta<990)
  6.                                                 {
  7.                                                                
  8.                                         aram= ADC1->DR;
  9.                                         minta++;
  10.                                         aram_sum=aram+aram_sum;
  11.                                         if(minta==990)
  12.                                                 {        
  13.                                                 aram_dis=(aram_sum/(minta+10))-offset;
  14.                                                 if(aram_dis<0){aram_dis=0;}
  15.                                                 }
  16.                                                 }
  17.                                        
  18.                                 }      
  19.        
  20.         }
  21. }
(#) icserny válasza cimopata hozzászólására (») Aug 24, 2016 /
 
A megszakításkérő függvénynek nem lehet visszatérési értéke. Egy (vagy több) volatile tulajdonságú globális változóba természetesen menthet értéke(ke)t.
(#) ha1drp válasza icserny hozzászólására (») Aug 24, 2016 /
 
Ez utóbbi nem tűnik megszakításkezelő függvénynek.
(#) cimopata hozzászólása Aug 24, 2016 /
 
Ha valakinek van gyakorlati ötlete hogy mikén lehetne megoldani, csupa fül vagyok
(#) ha1drp válasza cimopata hozzászólására (») Aug 24, 2016 /
 
Én igazán nem látom mit hol definiáltál, de ha valóban lefut a függvény akkor a biztos hogy rossz helyen definiáltad a speed változót. Alternatíva lehet az extern , ha más ötlet nincs.
(#) cimopata hozzászólása Aug 24, 2016 /
 
  1. #include "stm32f0xx_hal.h"
  2. #include "stm32f0xx.h"
  3.  
  4.  
  5. ADC_HandleTypeDef hadc;
  6.  
  7. TIM_HandleTypeDef htim1;
  8. TIM_HandleTypeDef htim14;
  9.  
  10. void offset(void);
  11. void deadtime_set(void);
  12. void SystemClock_Config(void);
  13. static void MX_GPIO_Init(void);
  14. static void MX_ADC_Init(void);
  15. static void MX_TIM1_Init(void);
  16. static void MX_TIM14_Init(void);
  17. short offset0=0;
  18. short offset1=0;
  19. short pwm=0;
  20. short pwmch1=0;
  21. short pwmch2=0;
  22. short pwmch3=0;
  23. short pwmch4=0;
  24. volatile uint32_t       adc_store[48];
  25. short currentch[2];
  26. short currenttemp;
  27. short currentch0=0;
  28. short currentch1=0;
  29. short current=0;
  30. short currentlim=1000;
  31. short currentreg=0;
  32. short deadtime=0;
  33. short buffer=0;
  34. long buffer2=0;
  35. volatile short speed=0;
  36. short ramp=0;
  37. volatile long speed_x128=0;
  38. volatile long speed_x128buff=0;
  39. int forward=0;
  40. int reverse=0;
  41. int regen=0;
  42. int brake=0;
  43. int FRstate;
  44. int i;
  45.  
  46. int main(void)
  47. {
  48.        
  49.         volatile short  adc_store[48];
  50.        
  51.   HAL_Init();
  52.   SystemClock_Config();
  53.   MX_GPIO_Init();
  54.   MX_ADC_Init();
  55.   MX_TIM1_Init();
  56.   MX_TIM14_Init();
  57.         HAL_Delay(1000);
  58.        
  59.         TIM1->CCER |= TIM_CCER_CC2NE;
  60.         TIM1->CCER |= TIM_CCER_CC3NE;
  61.         RCC->AHBENR |= RCC_AHBENR_DMA1EN;
  62.         RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
  63.        
  64.        
  65.         TIM1->PSC = 1;          // Set prescaler to  (PSC + 1)
  66.         TIM1->ARR = 2048;                 // Auto reload value max pwm érték
  67.         TIM1->DIER = TIM_DIER_UIE; // Enable update interrupt (timer level)
  68.         TIM1->CR1 = TIM_CR1_CEN;   // Enable timer     
  69.         NVIC_EnableIRQ(TIM1_BRK_UP_TRG_COM_IRQn); // Enable interrupt from TIM3 (NVIC level)
  70.        
  71.         ADC1->CFGR1 |=  ADC_CFGR1_DMAEN |       // enable DMA mode
  72.                                                                         ADC_CFGR1_DMACFG;  // DMA circular mode
  73.         ADC1->CR =      ADC_CR_ADEN | // turn on ADC
  74.                                                         ADC_CFGR1_CONT; // enable continuos mode
  75.  
  76.         ADC1->CHSELR =  ADC_CHSELR_CHSEL0 | //csatorna engedélyezés
  77.                                                                         ADC_CHSELR_CHSEL1 |
  78.                                                                         ADC_CHSELR_CHSEL4 |
  79.                                                                         ADC_CHSELR_CHSEL5 |
  80.                                                                         ADC_CHSELR_CHSEL6 |
  81.                                                                         ADC_CHSELR_CHSEL7 ;
  82.  
  83.         DMA1_Channel1->CPAR  = (uint32_t)(&(ADC1->DR)); // peripheral (source) address
  84.         DMA1_Channel1->CMAR  = (uint32_t)(adc_store);             // memory (desination) address
  85.         DMA1_Channel1->CNDTR = 48;                            //  transfers number
  86.         DMA1_Channel1->CCR |= DMA_CCR_PL_0;     // dma priority
  87.         DMA1_Channel1->CCR |= DMA_CCR_CIRC |    // circular mode enable
  88.                                                                                                 DMA_CCR_MINC |    // memory increment mode enable
  89.                                                                                                 DMA_CCR_MSIZE_0  | // memory size 16 bits
  90.                                                                                                 DMA_CCR_PSIZE_0 ;  // peripheral size 16 bits
  91.         DMA1_Channel1->CCR |= DMA_CCR_EN ;      // Enable channel
  92.         ADC1->CR = ADC_CR_ADSTART;
  93.         HAL_Delay(1);
  94.         offset0= adc_store[0];
  95.         offset1= adc_store[1];
  96.         offset0= 2048-offset0; // (12 bites felbontás fele 2048)
  97.         offset1= 2048-offset1;
  98.        
  99.         HAL_TIM_Base_Start(&htim1);
  100.        
  101.         HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2);
  102.         HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_3);
  103.        
  104.        
  105.   while (1)
  106.   {...}
(#) Balázs válasza cimopata hozzászólására (») Aug 24, 2016 /
 
A mainben is van egy adc_store nevű lokális változó, és van egy globális is. Az ISR-ből a globális látszik, a mainben pedig a lokális. Tehát a DMA vezérlőnek te a mainben definiált tömb címét adod át, de az ISR-ben a globálisan deklarált tömböt olvasod.
(#) aticska válasza cimopata hozzászólására (») Aug 24, 2016 /
 
adc_store kétszer szerepel. Mainben és azon kívül is. Csak a külső legyen.
(#) cimopata válasza aticska hozzászólására (») Aug 24, 2016 /
 
adc_store benn maradt nem szándégos, de vágülis az működik nem azzal van a baj. A speed nem működik a megszkításban amit feljebb osztottam meg.
(#) szilva válasza cimopata hozzászólására (») Aug 24, 2016 /
 
Szertintem csak casting gondod van, mivel a speed short, a spped_x128buff meg long. Az a 128-cal osztás így lehet, hogy nem úgy fog viselkedni, ahogy gondolod. Érdemes lenne kierőszakolt castinggal minden tényezőnek megmondani, hogy miként kezelje a fordító. Sőt, a "7" konstans is lehet, hogy kevés, én inkább "7L"-t írnék.
(#) cimopata válasza szilva hozzászólására (») Aug 24, 2016 /
 
Mint írtam a main-ben tökéletesen megy. Ez egy meredekség korlátozó lenne. A mainben tökéletesen fut le csak gyorsabban mert a main 2-3us alatt lefut nekem pedig az túl gyors. De lehet az lesz hogy átírom hogy tovább számoljon és hagyom a main-ben. Csak arra lettem volna kíváncsi hogy miért nem működik a megszakításban mert később lehet olyan feladat lenne amit nem tudok berakni a main-be.
(#) szilva válasza cimopata hozzászólására (») Aug 24, 2016 /
 
Értem, akkor már csak egy hülye kérdésem lenne: biztos, hogy eljut ide a vezérlés, biztos, hogy működik az interrupt?
(#) cimopata válasza szilva hozzászólására (») Aug 24, 2016 /
 
Működik beleraktam egy port billegtetését fut 80us-os periódussal.
(#) szilva válasza cimopata hozzászólására (») Aug 24, 2016 /
 
Lépésenként nyomkövetni nincs mód? Talán csak kiderülne, hogy mit hova pakol és mit számol egyáltalán. A globális volatile változót kellene tudni így írni, annak jónak kellene lennie, én csak arra tudok gondolni, hogy valamilyen oknál fogva rossz adat kerül bele, és emiatt gondolod azt, hogy nem írja. Első körben a 14. sorba tennék töréspontot, ha van erre mód, és onnan vizsgálnám meg a memóriát és a hivatkozásokat, amiket használ.
(#) ha1drp válasza szilva hozzászólására (») Aug 24, 2016 /
 
Más is belefutott a problémába.
(#) szilva válasza ha1drp hozzászólására (») Aug 24, 2016 /
 
Hát, pedig ennek így működnie kellene. Az biztos, hogy több programomban használtam ilyen jellegű értékátadást interruptból. Persze volt, ahol szemaforozni kellett (pl. PIC-nél a nagyobb szóhosszúságú értékek módosításánál), de alapvetően a főprogram és a megszakítási rutin is tudta mindig, hogy hol van a változó, amivel dolgoznia kell.

Ki kell debugolni, hogy itt mi történik, mert még az is lehet, hogy fordítóhiba. Annak idején pl. SDCC-ben találtam címzéshibát, amit a fordító rontott el bizonyos esetekben.

Apropó, milyen fordítóról beszélünk? Én ARM-ekre Eclipse környezetet és GNU GCC-t használok.

# arm-none-eabi-gcc --version
arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.9.3 20150529 (release) [ARM/embedded-4_9-branch revision 227977]
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
(#) cimopata válasza szilva hozzászólására (») Aug 24, 2016 /
 
Na úgy néz ki meglett a baj. Egyrészről mindegyik változót ami a megszakításon belül előfordul lecseréltem volatile-ra valamint van az a sor az If-en belül hogy "speed_x128=(adc_store[4] <<7);" itt az nem tetszhetett neki hogy a longos adatba ami a speed_x128 bele akarom írni az adc_store[4] adatot felszorozva 128-al ami pedig uint32_t adatot volt. Az unit32_t t átírtam short-ra. Így most szépen meg csinálja a meredekségszabályozást amilyet épp szeretnék.

Sok még a csiszolni való a programon de egyenlőre lekopogom jól megy


  1. void TIM1_BRK_UP_TRG_COM_IRQHandler(void)
  2. {
  3. if(TIM1->SR & TIM_SR_UIF) // if UIF flag is set
  4.   {
  5.   TIM1->SR &= ~TIM_SR_UIF; // clear UIF flag
  6.         //GPIOB->BRR = (1 << 6); //reset PC8   
  7.         //GPIOB->BSRR = (1 << 6); //set PC8    
  8.                
  9.         speed_x128=speed_x128 + 1;
  10.         speed_x128buff=speed_x128 & 0xFFF80;
  11.         speed=speed_x128buff >> 7; // osztás 128-al
  12.         if(speed>adc_store[4])
  13.                 {
  14.                         speed=adc_store[4];
  15.                         speed_x128=(adc_store[4] <<7);
  16.                 }
  17.        
  18.        
  19.  
  20.   }
  21. }
(#) rolandgw hozzászólása Szept 10, 2016 /
 
Üdv! Pár bosszantó LPC tapasztalat. Hozzáteszem nekem szimpatikusabb mint az ST. Szerintem könnyebb konfigurálni, 256K-ig teljes értékű, ingyenes fejlesztőkörnyezet, jó stdlib stb. Kinéztem az M0+ -t kisebb feladatokhoz ( 11U/E6X sorozat) és ezt a fejlesztő panelt LPCopen támagtással. Kb. sehol nem kapni. Cortex M3 belépő szint (13XX) ,board még csak-csak, de például DMA nincs a prociban.Szóval ezen a téren meg sem közelíti az ST-t.
(#) killbill válasza rolandgw hozzászólására (») Szept 10, 2016 /
 
Az osszes ARM ingyenesen fejlesztheto, csak egy Linux kell hozza, ami szinten ingyenes. Mind az ST, mind az LPC-k sima mezei sorosvonalon programozhatok, nem kell draga csilli-villi programozokat venni. Persze nincs ingyenes grafikus felulet, ami helyetted megirja a start kodot, meg a periferiak felprogramozasat, mint a vindozos IDE-kben, viszont igy tudni fogod, hogy mit csinal a program, amit a FLASH-be beegetsz. Teny, hogy erteni kell hozza, el kell olvasni az adatlapot. A kisebb LPC-kben tenyleg nincs DMA, de ezt leszamitva jobbak, mint az ST-k. Nezd csak meg az ST UART-jat, TIMER-eit, es nezd meg az LPC-ben ugyanezeket. 32 bites timer nelkul egy ilyen uC eleg szegyenletes, marpedig az ST-kben nem igen vannak. A legkisebb LPC-ben is van legalabb ket 32 bites es 2 16 bites timer. A UART-janak 16 byte FIFO-ja van ki is, be is. Az SPI-je szinten rendelkezik 8 melysegu FIFO-val, akar 16 bit szeles szavakhoz is. Nem olyan rosszak azok az LPC-k.
Következő: »»   74 / 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