Menu

Interrupt based PWM example for 12F683

2009-04-28
2013-05-30
  • Nobody/Anonymous

    'You must define IOPWM, and set the bytPWM value in you main loop

    'Use PIC12F683
    #chip 12F683, 8    'Internal Ocs, 8Mhz
    #config INTOSCIO, BOD_ON, MCLRE_ON, PWRTE_ON    'Enable Brown Out, Power on timer
    'Note GCBasic does not handle interrupts properly on the 12F683
    'you must manually edit the asm file to move the SysW variable to the upper addresses, like 127
    'Also, you must manually change the code to the following in the handler:
    ';Interrupt vector
    '    ORG    4
    ';Save Context
    '    movwf    SysW
    '    swapf    STATUS,W
    '    clrf    STATUS

    Main:

    'Handle timer manually to save code
      Set TMR1ON Off
      T1CON = 0    'Set configuration, including prescale to 1:1
      TMR1H = 0
      TMR1L = 0
      On Interrupt Timer1Overflow Call TimerOver
      Set TMR1ON On

    'Insert main loop code here

    Sub TimerOver

      'Timer1 interrupt
      'Used for Low Frequency PWM, since the hardware PWM can't operate < 1KHz
      'The PWM duty cycle is set by changing timer1 on each interrupt
      'On each interrupt the next PWM value is calculated and set
      'Not recommended to write TMR1L, and since it just overflowed it should a small value (usually)
      'Be careful with math operations in an interrupt, as they can insert interrupt enables disables from GCBasic
      Select Case bytPwm
        Case 0
          Set IOPWM Off
        Case 255
          Set IOPWM On
        Case Else
          If IOPWM On Then
            TMR1H = bytPwm    'Timer low byte not critical enough to reset, should be close to 0 anyways
            Set IOPWM Off
            Exit Sub
          End If
          Set IOPWM On
          TMR1H = ! bytPwm
      End Select

    End Sub

    End

     
    • smartroad

      smartroad - 2009-05-11

      Thanks for this, having a little problem. Using a 16F627 with a 4mhz crystal and I seem to have a PWM frequency of about 3-5Hz (don't have a frequency meter so can't be 100%). When I set at 128 (50% duty I hope) it is obviously flashing. Any ideas how I can up the frequency?

      Cheers!

       
    • Nobody/Anonymous

      You need to set the timer0 period.  In the above example:
      Timer1 is used at 0 preset.
      '  Which gives 256 x 256 counts @ 2MHz = 32.77 mS or 30.52 Hz interrupt timing.

      Look over the configuration of the timer for your chip, including the value for T1CON.  If you have the code space, you can just let GCBasic setup the timer using InitTimer0, in my case I did not.

       
    • Nobody/Anonymous

      Oops.  Change the above comment to timer1 and not timer0

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.