Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

arm sam7s + regulator modelarski + silnik bezszczotkowy

szumlakn2o 12 Nov 2010 23:31 2865 5
Computer Controls
  • #1
    szumlakn2o
    Level 10  
    Witam posiadam mikrokontroler ARM at91sam7s256. Potrzebuje programu ktory będzie sterował mocą silnika bezszczotkowego sygnalem pwm. Znalazlem kod do generowania sygnału i pozmienialem troche zeby sterowac wartością wypełnienia za pomocą przycisków. Po podaniu sygnały na diodę wszystko działa ładnie jednak po podpięciu regulatora i silnika pojawiają się problemy. Silnik się nie obraca, a jedynie mniej wiecej w połowie zakresu pwm (ok 50% wypełnienia) czasami lekko drgnie i piszczy:
    ( - - - - - - - - - - - -) 

    Regulator to: ACS-25A Alturn 25A Brushless Motor Control
    Dokumentacja regulatora którą udało mi się znaleźć na internecie:

    Dokumentacja1
    Dane techniczne regulatora

    Wiem że regulator trzeba zaprogramować ale nie bardzo wiem jak. Z tego co czytalem po podaniu mu maksymalnego wypełnienia przy starcie powinien przejsć w tryb programowania i wydać sygnał dźwiękowy ale nic takiego sie nie dzieje. Poniżej zamieszczam kod programu:

    Code:


    // Simple program that runs PWM channel 0
    // connect the output (PA11) to an LED

    #define  TRUE                   1
    #define  FALSE                  0
    typedef  unsigned char       BOOL;
    typedef  unsigned char       BYTE;

    #define  PORT_PWM              24

    #define  PORT_MASK(nBit) (1<<nBit)

    #include "AT91SAM7S64.h"
    #include "gpio.c"

    // ------------------------------------------------------------
    // Init() initializes the Flash, the watchdog timer, the Power
    // Management Controller (PMC), and the PIO port.
    // See the steps outlined in the section titled "Programming
    // Sequence" of the Atmel AT91SAM7S data sheet (Section 26.7 )
    // to program the PMC.
    // ------------------------------------------------------------

    void pwm_init(void)
    {
       AT91PS_PMC pPMC;
       AT91PS_PIO pPIO;

          // --- set flash memory parameters ---
          // MCK will be set to 47.92 MHz (approximately 48MHz) below
          // so set FMCN=48.  Add minimal wait states since we are above 40 MHz.
       AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN)&(48 <<16)) | AT91C_MC_FWS_1FWS ;

          // --- disable the watchdog timer ---
       AT91C_BASE_WDTC->WDTC_WDMR=AT91C_WDTC_WDDIS;

          // --- program the Power Management Controller (PMC) ---
          // steps are as given in Section 26.7 "Programming Sequence"

       pPMC=AT91C_BASE_PMC;

          // 1. start the "main oscillator" (Section 25.3.3)
          // slow clock frequency = 32.768 KHz
          // slow clock period = 30.5176 microseconds
          // Start up time = 8*7*30.5176 = 1708.984375 microseconds or 1.709 milliseconds
       pPMC->PMC_MOR = (AT91C_CKGR_OSCOUNT & (0x03 <<8)) | AT91C_CKGR_MOSCEN;

          // 2. check the main oscillator frequency (optional)
          // skipped

          // wait the master clock to settle
       while(!(pPMC->PMC_SR & AT91C_PMC_MOSCS));

          // 3. set the PLL and the divider
          // main clock or (crystal) frequency = 18.432MHz)
          // use: USBDIV=1, DIV=5, MUL=25, and OUT=0, which yields,
          // (18.432/5)*(25+1)=95,8464MHz
          // for a LOCK time of 1000 microseconds (1 milliseconds),
          // set PLLCOUNT to 1000/30.5176=33
          pPMC->PMC_PLLR = ((AT91C_CKGR_DIV & 5) | (AT91C_CKGR_PLLCOUNT & (33<<8)) | (AT91C_CKGR_MUL & (25<<16)) | (AT91C_CKGR_USBDIV & (1<<28)) );
          // wait for the PLL to stabalize
       while(!(pPMC->PMC_SR&AT91C_PMC_LOCK));
       
       while(!(pPMC->PMC_SR&AT91C_PMC_MCKRDY));
     
          // 4. select the master clock source and the prescalar
          // source    = the PLL clock
          // prescalar = 2
       pPMC->PMC_MCKR=AT91C_PMC_CSS_PLL_CLK|AT91C_PMC_PRES_CLK_2;//bylo2
       while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY));

          // 5. select programmable clocks
          // (programmable clocks are not used in this application)
       
          // 6. enable the peripheral clock used by PIOA and PWMC
       pPMC->PMC_PCER=(1<<AT91C_ID_PIOA)|(1<<AT91C_ID_PWMC);

          // initializ the port defined as PORT_LED as an output port.

       pPIO=AT91C_BASE_PIOA;
          //configure the PIO register used by the PWM channel 0
       pPIO->PIO_PDR  = PORT_MASK(PORT_PWM);   // PWM port is controlled by the peripheral
       pPIO->PIO_BSR  = PORT_MASK(PORT_PWM);   // PWM port is peripheral B (multiplexed with PA11)
    }

    // ------------------------------------------------------------

    // ------------------------------------------------------------


    //------------------------------------------------

    int main(void)
    {
       AT91PS_PWMC      pPwmc;
       AT91PS_PWMC_CH   pPwmCh0;
       volatile int     n, nDC;

       // inicjalizacja pwm
       pwm_init();

       // enable pwm channel 1 (0,1,2,3) -- no interrupts
       pPwmc=AT91C_BASE_PWMC;
       pPwmc->PWMC_ENA=2;           // enable pwm channel,

       pPwmCh0=AT91C_BASE_PWMC_CH1; //bylo 0
       pPwmCh0->PWMC_CMR=0x020A;    // polarity 1 (start high), PWM_CLK = MCK/1024
       pPwmCh0->PWMC_CPRDR=0x100;   // period
       //nDC=0x80;
       //pPwmCh0->PWMC_CDTYR=nDC;     // duty cycle


       //konfiguracja gpio
       AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA ) ;

       nDC=255;    //wypelnienie pwm      

       
       AT91F_PIO_CfgOutput( AT91C_BASE_PIOA, AT91C_PIO_PA25) ;
       AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, AT91C_PIO_PA25) ;   

    //petla glowna programu
     while(TRUE)
      {
       for(n=0; n<0x10000; n++);
       if ( (AT91F_PIO_GetInput(AT91C_BASE_PIOA) & SW2_MASK) == 0 )
        {
            nDC--;
          if(nDC==0){nDC=1;AT91F_PIO_SetOutput( AT91C_BASE_PIOA, AT91C_PIO_PA25) ;}
        }
        if ( (AT91F_PIO_GetInput(AT91C_BASE_PIOA) & SW3_MASK) == 0 )
        {
            nDC++;
          if(nDC==256)nDC=255;
        }
            //tak dla sprawdzenia
       if(nDC==1)AT91F_PIO_SetOutput( AT91C_BASE_PIOA, AT91C_PIO_PA25) ;
       else AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, AT91C_PIO_PA25) ;

       nDC&=0xFF;
       pPwmCh0->PWMC_CUPDR=nDC;     // duty cycle
     }
     
    }


    Może częstotliwość generowanego sygnału jest nieodpowiednia? To są moje początki z programowanie arm'ów i nie bardzo sie mogą połapać jak ją zmienić. Gdyby ktoś mógł jakoś pomóc byłbym wdzięczny.
  • Computer Controls
  • #2
    szumlakn2o
    Level 10  
    gdyby mógł ktoś podpowiedzieć w jaki sposób mogę zmienić częstotliwość generowanego sygnału pwm byłbym bardzo wdzięczny. nie moge sie w tym kodzie za bardzo połapać
  • Computer Controls
  • #3
    adambombel
    Level 12  
    Generalnie wszystko masz w PDFie od SAM7S, ale żeby nie było że pisze bezużyteczne posty, to:

    Zmienić częstotliwość możesz na kilka sposobów.

    1. Wybierając odpowiednie źródło sygnału taktowania (patrz PDF i rejestr PWMC_CMRx i PWMC_MR) i ustawiając jego częstotliwość

    2. Ustawiając odpowiednio "period" (patrz rejestr PWMC_CPRDx)

    Generalnie, jeżeli wybierzesz sobie jakąś częstotliwość taktowania dla kanału PWM (f), to częstotliwość wyjściowa (fwy) będzie równa fwy = f/period

    "period" w uproszczeniu jest właściwie rozdzielczością PWMa, którą chcesz uzyskać.

    Przykład:
    wybierasz częstotliwość sygnału taktującego PWM f=1MHz
    Interesuje cię 8-bitowa rozdzielczość, więc ustawiasz period = 256
    Uzyskasz tym sposobem f na wyjsciu rózną 1MHz/256 = ~3.9KHz

    Jezeli chcesz mieć np. rodzielczość PWMa co 1%, czyli 100 kroków, ustawiasz period na 100 i dostajesz na wyjściu przebieg o f = 1MHz / 100 = 10kHz.
  • #4
    arrevalk
    Level 25  
    A próbowałeś zamienić miejscami dwa dowolne przewody silnika?
  • #5
    Mat_91
    Level 25  
    Regulator modelarski musisz sterować tak samo jak serwo. To nie PWM.

    Link
  • #6
    szumlakn2o
    Level 10  
    dziękuje za odpowiedzi. już wszystko działa. okazało się ze regulator modelarski wymaga sygnału sterującego o częstotliwości 50Hz. Ponadto użyteczny zakres mieści się w zakresie od ok 6% do 9,5% wypełnienia. gdzie 6,5% to inicjacja pracy regulatora a 9% to moc maksymalna. Powyżej tej wartości regulator nie działa prawidłowo. Przeprowadzilismy test polegający na zbadaniu na oscyloskopie sygnały z standardowego odbiornika RC wykożystywanego w modelarstwie i taki wlasnie sygnał on generuje. Dodatkowo naszym błędem było podanie zbyt słabego prądu. Regulator ma zabezpieczenie przed rozładowaniem akumulatora. Przy spadku napięcia odcina zasilanie.
    i jeszcze jedno. servo modelarskie steruje się takim samym sygnałem PWM.