-
        

Ergebnis 1 bis 2 von 2

Thema: Xmega & Bascom: PWM und Servounterstützung

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    26.12.2009
    Beiträge
    6

    Xmega & Bascom: PWM und Servounterstützung

    Anzeige

    Hallo Bascom-Fans,

    Mit den im Dezember 2009 erschienenen Bascom-Versionen (aktuell 1.11.9. hat Mark Alberts deutliche Fortschritte bei der Unterstützung der Xmegas erzielt. Leider fehlt für die Modellbau/Robotik/UAV-Szene noch etwas Elementares - nämlich der Bascom-support von PWM und Servos. Das kann man aber selbst mit kleinen Veränderungen an der XM128def.dat hinbekommen. Wie, ist in nachstehendem Source snippet erläutert.

    Wünsche noch einen guten Rutsch,
    Natalius

    Code:
    '----------------------------------------------------------------
    '  (C) MCS 2009 & N.Kiedro
    '  Xmega2Servo.bas
    '  This snippet demonstrates PWM on the Xmega128A1
    '  Platform: Xmega A1 USB module from http://shop.avr-praxis.de
    '
    '  USE port D to create six RC servo signals in 4000 steps/ms
    '  resolution via interrupt-free single slope PWM.
    '  Servo signals are pulses between 1 and 2 ms,
    '  corresponding to 4000 to 8000 here - center at 6000.
    '  In my own kixm128a1def.dat file I have done these extensions for
    '  all Timer/Counters which allows to control 20 Servos (=24-4 because
    '  of USART F0 in use) via the Xmega-A1-USB module. Of course, jitter-free
    '  and with best achievable resolution @ 32 MHz.
    '-----------------------------------------------------------------
    
    $regfile = "kixm128a1def.dat"
    
    'For Bascom 1.11.9.8: This snippet needs an extended definition dat with the following
    'changes:
    ''(1) Load xm128def.dat into the editor and save it under a different name, e.g. kixm128a1def.dat
    ''(2) Find the following definitions for TCD0, TCD1
    ''     _CNT
    ''     _PER
    ''     _CCA
    ''     _CCB
    ''     _CCC
    ''     _CCD
    ''     _PERBUF
    ''     _CCABUF
    ''     _CCBBUF
    ''
    ''(3) Replace the corresponding sections as follows:
    ''     TCD0_CNTL = 2336  ; Count
    ''     TCD0_CNTH = 2337  ; Count
    ''     TCD0_PERL = 2342  ; Period
    ''     TCD0_PERH = 2343  ; Period
    ''     TCD0_CCAL = 2344  ; Compare or Capture A
    ''     TCD0_CCAH = 2345  ; Compare or Capture A
    ''     TCD0_CCBL = 2346  ; Compare or Capture B
    ''     TCD0_CCBH = 2347  ; Compare or Capture B
    ''     TCD0_CCCL = 2348  ; Compare or Capture C
    ''     TCD0_CCCH = 2349  ; Compare or Capture C
    ''     TCD0_CCDL = 2350  ; Compare or Capture D
    ''     TCD0_CCDH = 2351  ; Compare or Capture D
    ''     TCD0_PERBUFL = 2358  ; Period Buffer
    ''     TCD0_PERBUFH = 2359  ; Period Buffer
    ''     TCD0_CCABUFL = 2360  ; Compare Or Capture A Buffer
    ''     TCD0_CCABUFH = 2361  ; Compare Or Capture A Buffer
    ''     TCD0_CCBBUFL = 2362  ; Compare Or Capture B Buffer
    ''     TCD0_CCBBUFH = 2363  ; Compare Or Capture B Buffer
    ''     TCD0_CCCBUFL = 2364  ; Compare Or Capture C Buffer
    ''     TCD0_CCCBUFH = 2365  ; Compare Or Capture C Buffer
    ''     TCD0_CCDBUFL = 2366  ; Compare Or Capture D Buffer
    ''     TCD0_CCDBUFH = 2367  ; Compare Or Capture D Buffer
    ''
    ''     TCD1_CNTL = 2400  ; Count
    ''     TCD1_CNTH = 2401  ; Count
    ''     TCD1_PERL = 2406  ; Period
    ''     TCD1_PERH = 2407  ; Period
    ''     TCD1_CCAL = 2408  ; Compare or Capture A
    ''     TCD1_CCAH = 2409  ; Compare or Capture A
    ''     TCD1_CCBL = 2410  ; Compare or Capture B
    ''     TCD1_CCBH = 2411  ; Compare or Capture B
    ''     TCD1_PERBUFL = 2422  ; Period Buffer
    ''     TCD1_PERBUFH = 2423  ; Period Buffer
    ''     TCD1_CCABUFL = 2424  ; Compare Or Capture A Buffer
    ''     TCD1_CCABUFH = 2425  ; Compare Or Capture A Buffer
    ''     TCD1_CCBBUFL = 2426  ; Compare Or Capture B Buffer
    ''     TCD1_CCBBUFH = 2427  ; Compare Or Capture B Buffer
    ''(4) Dont forget to save the changes
    
    
    $crystal = 32000000
    $hwstack = 512
    $swstack = 256
    $framesize = 256
    
    'include the following lib and code, the routines will be replaced since they are a workaround
    $lib "xmega.lib"
    $external _xmegafix_clear
    $external _xmegafix_rol_r1014
    
    '$timeout = 8000000     TIMEOUT WILL WORK FOR ALL UARTS
    
    'first enable the osc of your choice
    Config Osc = Enabled , 32mhzosc = Enabled                   'remarkably accurate given the fact that no xtal is employed
    'Config Osc = Enabled , Extosc = Enabled , Range = 12mhz_16mhz , Startup = Xtal_16kclk (so far doesn't work)
    
    'configure the systemclock
    Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1
    
    Dim N As String * 16 , B As Byte
    Dim Tel As Byte , Channum As Byte , Jst As String * 1 , Chanval As Word , Chanpwm(6) As Word , Iby As Byte
    
    Config Com7 = 38400 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
    Config Input7 = Cr , Echo = Crlf                            ' CR is used for input, we echo back CR and LF
    
    Open "COM7:" For Binary As #7
    '       ^^^^ change from COM1-COM8
    
    Config Portf = Output
    Config Portf.3 = Output                                     ' TX pin must be output
    Config Portf.2 = Input
    Config Portq = Output
    
    'Waitms 500
    Print #7 , "Press <CR> to start";
    
    'pwm initialisation here
    'RC cycle period should be ideally at 20ms, viz. 50 Hz.
    'With fpwm = fosc/per/clkdiv = 32MHz/(2^16)/8 = 1MHz/2^14 = 61.0352 Hz we have a
    'cycle period of 16.384 ms most Servos should be able to live with.
    
    ' From the Xmega 128A1 manual:
    ' 6.4 Using a Timer/Counter for PWM Generation
    '     Task: Configure TCC0 for pulse width modulation output with varying duty cycle on channel A.
    '        1. Configure PC0 for output by setting bit 0 in PORTC.DIR.
    '        2. Select the timer period by setting the PER[H:L] register.
    '        3. Select a waveform generation mode by setting the WGMODE[2:0] bits in CTRLB
    '        4. Enable Compare Channel A by setting the CCAEN bit in CTRLB.
    '        5. Start the TC by selecting a clock source (CLKSEL[3:0] in CTRLA).
    '        6. Calculate the desired compare value.
    '        7. Write the new compare value to CCA[H:L].
    '        8. Wait for the TC Overflow Flag to be set. (OVFIF in INTFLAGS).
    '        9. Clear the TC Overflow flag.
    '       10. Go to step 6.
    'Using this sequence, the compare value will be updated once every PWM period.
    
    'Modification: free running pwm - no interrupt, but ASAP update instead:
    '        1. Configure PD0 and PD1 for output --> PORTD.DIR.
    '        2. Select the timer period by setting the PER[H:L] register.
    '        3. Select a waveform generation mode by setting the WGMODE[2:0] bits in CTRLB
    '        4. Enable Compare Channel A-D by setting the CCAEN bits in CTRLB.
    '        5. Start the TC by selecting a clock source (CLKSEL[3:0] in CTRLA).
    '        6. Calculate the desired compare value.
    '        7. Write the new compare value to CCxBUF[H:L].
    '        8. Go to step 6
    
    'ad 1.
    Portd_dir = &HFF
    
    'ad2.
    Tcd0_perl = &HFF
    Tcd0_perh = &HFF
    Tcd1_perl = &HFF
    Tcd1_perh = &HFF
    
    'ad 3 & 4
    Tcd0_ctrlb = &HF3                                           'define WGMODE 011 = single slope and set OCA-D active
    Tcd1_ctrlb = &HC3
    
    'ad 5
    Tcd0_ctrla = &H04                                           'Divide Clock By 8 , Enable Timers (Bits 3..0 define clckdiv)
    Tcd1_ctrla = &H04
    
    'ad 6
    For Iby = 1 To 6
        Chanpwm(iby) = 6000
    Next Iby
    
    'ad 7
    Gosub Update
    
    'configure the priority
    'config priority=static|roundrobin,vector=application|boot,HI=enabled|disabled, LO=enabled|disabled,ME=enabled|disabled
    Config Priority = Static , Vector = Application , Lo = Enabled
    
    'test an interrupts
    On Usartf0_rxc Rxc_isr
    Enable Usartf0_rxc , Lo
    Enable Interrupts
    
    
    Tel = 65
    Do
      Print #7 , "Channel(1-6)?";
      Tel = Waitkey(#7)
      Jst = Chr(tel)
      Channum = Val(jst)
      Print #7 , Channum
      Input #7 , "value?" , N                                   'enter values between 4000 (1ms) and 8000 (2ms)
      Chanval = Val(n)
      Print #7 , N
      Chanpwm(channum) = Chanval
      'ad 7
      Gosub Update
    Loop
    
    
    
    
    Rxc_isr:
     Toggle Portq.3
     'Incr Teller
    Return
    
    
    
    Update:
    
      Tcd0_ccabufL = Low(chanpwm(1))
      Tcd0_ccabufH = High(chanpwm(1))
    
      Tcd0_ccbbufL = Low(chanpwm(2))
      Tcd0_ccbbufH = High(chanpwm(2))
    
      Tcd0_cccbufL = Low(chanpwm(3))
      Tcd0_cccbufH = High(chanpwm(3))
    
      Tcd0_ccdbufL = Low(chanpwm(4))
      Tcd0_ccdbufH = High(chanpwm(4))
    
      Tcd1_ccabufL = Low(chanpwm(5))
      Tcd1_ccabufH = High(chanpwm(5))
    
      Tcd1_ccbbufL = Low(chanpwm(6))
      Tcd1_ccbbufH = High(chanpwm(6))
    
    Return

  2. #2
    Neuer Benutzer Öfters hier
    Registriert seit
    26.12.2009
    Beiträge
    6
    Was man für einen Kickstart sonst noch braucht:
    (1) Registrierte Bascom user gehen von der MCSELEC homepage nach registration und support, um das LIC File für 1.11.9.8 runterzuladen. Abspeichern im /BASCOM-AVR.
    (2) Sobald das neue LIC abgespeichert ist, ruft man Autoupdate Wiz auf.
    (3) Man installiert die letzte Version von AVR Studio (aktuell Dezember 09) von der Atmel Seite.
    (4) Als Programmer ist der AVRISPmk2 geeignet (ca. 35Euro). Dieser wird nach FW-update im AVR-Studio in einen PDI-Programmer umkonfiguriert.
    (5) Will keine Reklame machen, aber im AVR-Praxis shop gibt es für wenig Geld das Xmega-A1-USB Modul, z.B.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •