PWM Library

The CCP module is available with a number of dsPIC30/33 and PIC24 MCUs. mikroBasic PRO for dsPIC30/33 and PIC24 provides a library which simplifies using of the PWM HW Module.

  Important : PWM module uses either Timer2 or Timer3 module.

Library Routines

PWM_Init

Prototype

sub function PWM_Init(dim freq_hz as longint, dim enable_channel_x, timer_prescale, use_timer_x as word) as word

' 30F1010 and dsPIC33FJ06GS101/102/202 prototype

sub function PWM_Init(dim freq_hz as longint, dim enable_channel_x, timer_prescale) as word

Description

Initializes the PWM module with duty ratio 0.

Parameters
  • freq_hz: PWM frequency in Hz (refer to device datasheet for correct values in respect with Fosc)
  • enable_channel_x: number of PWM channel to be initialized. Refer to MCU's datasheet for available PWM channels
  • timer_prescale: timer prescaler parameter. Valid values: 1, 8, 64, and 256
  • use_timer_x: timer to be used with the PWM module. Valid values: 2 (Timer2) and 3 (Timer3)
Returns
  • 0xFFFF - if timer settings are not valid
  • otherwise returns calculated timer period
Requires

MCU must have the HW PWM Module.

Example
' Initializes the PWM module at 5KHz, channel 1, no clock prescale, timer2 :
dim pwm_period1 as word
...
pwm_period1 = PWM_Init(5000, 1, 0, 2)
Notes

Number of available PWM channels depends on MCU. Refer to MCU datasheet for details.

PWM_Set_Duty

Prototype

sub procedure PWM_Set_Duty(dim duty, channel as word)

Description

The function changes PWM duty ratio.

Parameters
  • duty: PWM duty ratio. Valid values: 0 to timer period returned by the PWM_Init function.
  • channel: number of PWM channel to change duty to.
Returns

Nothing.

Requires

MCU must have the HW PWM Module.

PWM channel must be properly initialized. See PWM_Init routine.

Example
' Set channel 1 duty ratio to 50%:
dim pwm_period1 as word
...
PWM_Set_Duty(pwm_period1 div 2, 1)
Notes

Number of available PWM channels depends on MCU. Refer to MCU datasheet for details.

PWM_Start

Prototype

sub procedure PWM_Start(dim enable_channel_x as byte)

Description

Starts PWM at requested channel.

Parameters
  • enable_channel_x: number of PWM channel
Returns

Nothing.

Requires

MCU must have the HW PWM Module.

PWM channel must be properly configured. See the PWM_Init and PWM_Set_Duty routines.

Example
' start PWM at channel 1
PWM_Start(1)
Notes

Number of available PWM channels depends on MCU. Refer to MCU datasheet for details.

PWM_Stop

Prototype

sub procedure PWM_Stop(dim disable_channel_x as byte)

Description

Stops PWM at requested channel.

Parameters
  • disable_channel_x: number of PWM channel
Returns

Nothing.

Requires

MCU must have the HW PWM Module.

Example
' stop PWM at channel 1
PWM_Stop(1)
Notes

Number of available PWM channels depends on MCU. Refer to MCU datasheet for details.

Library Example

The example changes PWM duty ratio on channels 1 and 2 continuously. If LEDs are connected to channels 1 and 2, a gradual change of emitted light will be noticeable.

Copy Code To ClipboardCopy Code To Clipboard
program Pwm_Demo
dim current_duty, old_duty, current_duty1, old_duty1 as word
    pwm_period1, pwm_period2 as word

sub procedure InitMain()
  ADPCFG = 0xFFFF                            ' initialize AN pins as digital
  TRISB = 0xFFFF                             ' configure PORTB pins as input
  PORTD = 0                                  ' set PORTD to 0
  TRISD = 0                                  ' designate PORTD pins as output
end sub

main:
  InitMain()
  current_duty  = 16                         ' initial value for current_duty
  current_duty1 = 16                         ' initial value for current_duty1

  pwm_period1 = PWM_Init(5000 , 1, 1, 2)
  pwm_period2 = PWM_Init(10000, 2, 1, 3)

  PWM_Start(1)
  PWM_Start(2)

  PWM_Set_Duty(current_duty,  1)             ' Set current duty for PWM1
  PWM_Set_Duty(current_duty1, 2)             ' Set current duty for PWM2

  while (TRUE)                               ' endless loop
    if RB0_bit = 1 then                      ' button on RB0 pressed
      Delay_ms(20)
      Inc(current_duty)                      ' increment current_duty
      if (current_duty > pwm_period1) then   ' if we increase current_duty greater then possible pwm_period1 value
        current_duty = 0                     ' reset current_duty value to zero
      end if
      PWM_Set_Duty(current_duty,  1)         ' set newly acquired duty ratio
    end if

    if RB1_bit = 1 then                      ' button on RB1 pressed
      Delay_ms(20)
      Dec(current_duty)                      ' decrement current_duty
      if (current_duty > pwm_period1) then   ' if we decrease current_duty greater then possible pwm_period1 value (overflow)
        current_duty = pwm_period1           ' set current_duty to max possible value
      end if
      PWM_Set_Duty(current_duty,  1)         ' set newly acquired duty ratio
    end if

    if RB2_bit = 1 then                      ' button on RB2 pressed
      Delay_ms(20)
      Inc(current_duty1)                     ' increment current_duty1
      if (current_duty1 > pwm_period2) then  ' if we increase current_duty1 greater then possible pwm_period2 value
        current_duty1 = 0                    ' reset current_duty1 value to zero
      end if
      PWM_Set_Duty(current_duty1,  2)        ' set newly acquired duty ratio
    end if

    if RB3_bit = 1 then                      ' button on RB3 pressed
      Delay_ms(20)
      Dec(current_duty1)                     ' decrement current_duty1
      if (current_duty1 > pwm_period2) then  ' if we decrease current_duty1 greater then possible pwm_period1 value (overflow)
        current_duty1 = pwm_period2          ' set current_duty to max possible value
      end if
      PWM_Set_Duty(current_duty1,  2)
    end if

    Delay_ms(5)                              ' slow down change pace a little
  wend
end.

HW Connection

PWM demonstration

PWM demonstration

Copyright (c) 2002-2012 mikroElektronika. All rights reserved.
What do you think about this topic ? Send us feedback!
Want more examples and libraries? 
Find them on LibStock - A place for the code