PWM 16 bit Library
CMO module is available with a number of AVR MCUs. mikroBasic PRO for AVR provides library which simplifies using PWM HW Module.
Important :
-
For better understanding of PWM module it would be best to start with the example provided in Examples folder of our mikroBasic PRO for AVR compiler.
When you select a MCU, mikroBasic PRO for AVR automaticaly loads the correct PWM-16bit library, which can be verified by looking at the Library Manager.
PWM library handles and initializes the PWM module on the given AVR MCU, but it is up to user to set the correct pins as PWM output, this topic will be covered later in this section.
Library Routines
Predefined constants used in PWM-16bit library
| The following variables are used in PWM-16bit library functions: | Description : |
|---|---|
_PWM16_PHASE_CORRECT_MODE_8BIT |
Selects Phase Correct, 8-bit mode. |
_PWM16_PHASE_CORRECT_MODE_9BIT |
Selects Phase Correct, 9-bit mode. |
_PWM16_PHASE_CORRECT_MODE_10BIT |
Selects Phase Correct, 10-bit mode. |
_PWM16_FAST_MODE_8BIT |
Selects Fast, 8-bit mode. |
_PWM16_FAST_MODE_9BIT |
Selects Fast, 9-bit mode. |
_PWM16_FAST_MODE_10BIT |
Selects Fast, 10-bit mode. |
_PWM16_PRESCALER_16bit_1 |
Sets prescaler value to 1 (No prescaling). |
_PWM16_PRESCALER_16bit_8 |
Sets prescaler value to 8. |
_PWM16_PRESCALER_16bit_64 |
Sets prescaler value to 64. |
_PWM16_PRESCALER_16bit_256 |
Sets prescaler value to 256. |
_PWM16_PRESCALER_16bit_1024 |
Sets prescaler value to 1024. |
_PWM16_INVERTED |
Selects the inverted PWM-16bit mode. |
_PWM16__NON_INVERTED |
Selects the normal (non inverted) PWM-16bit mode. |
_TIMER1 |
Selects the Timer/Counter1 (used with PWM16bit_Start and PWM16bit_Stop. |
_TIMER3 |
Selects the Timer/Counter3 (used with PWM16bit_Start and PWM16bit_Stop. |
_TIMER1_CH_A |
Selects the channel A on Timer/Counter1 (used with PWM16bit_Change_Duty). |
_TIMER1_CH_B |
Selects the channel B on Timer/Counter1 (used with PWM16bit_Change_Duty). |
_TIMER1_CH_C |
Selects the channel C on Timer/Counter1 (used with PWM16bit_Change_Duty). |
_TIMER3_CH_A |
Selects the channel A on Timer/Counter3 (used with PWM16bit_Change_Duty). |
_TIMER3_CH_B |
Selects the channel B on Timer/Counter3 (used with PWM16bit_Change_Duty). |
_TIMER3_CH_C |
Selects the channel C on Timer/Counter3 (used with PWM16bit_Change_Duty). |
Note :
-
Not all of the MCUs have 16bit PWM, and not all of the MCUs have both Timer/Counter1 and Timer/Counter3. Sometimes, like its the case with ATmega168, MCU has only Timer/Counter1 and channels A and B. Therefore constants that have in their name
Timer3 or channel C are invalid (for ATmega168) and will not be visible from Code Assistant. It is highly advisable to use this feature, since it handles all the constants (available) and eliminates any chance of typing error.
PWM16bit_Init
| Prototype |
sub procedure PWM16bit_Init(dim wave_mode as byte, dim prescaler as byte, dim inverted as byte, dim duty as word, dim timer as byte) |
|---|---|
| Returns |
Nothing. |
| Description |
Initializes the PWM module. Parameter
Parameter
The N variable represents the
The N variable represents the PWM16bit_Init must be called before using other functions from PWM Library. |
| Requires |
You need a CMO on the given MCU (that supports PWM-16bit). Before calling this routine you must set the output pin for the PWM (according to the datasheet):
DDB1_bit = 1 ' set PORTB pin 1 as output for the PWM-16bit
This code example is for ATmega168, for different MCU please consult datasheet for the correct pinout of the PWM module or modules. |
| Example |
Initialize PWM-16bit module: PWM16bit_Init(_PWM16_PHASE_CORRECT_MODE_8BIT, _PWM16_PRESCALER_16bit_8, _PWM16_NON_INVERTED, 255, _TIMER1) |
PWM16bit_Change_Duty
| Prototype |
sub procedure PWM16bit_Change_Duty(dim duty as word, dim channel as byte) |
||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Returns |
Nothing. |
||||||||||||||||||||||||||||
| Description |
Changes PWM duty ratio. Parameter
|
||||||||||||||||||||||||||||
| Requires |
PWM module must to be initialised (PWM16bit_Init) before using PWM_Set_Duty function. |
||||||||||||||||||||||||||||
| Example |
Example lets set duty ratio to : PWM16bit_Change_Duty( 300, _TIMER1_CH_A ) |
PWM16bit_Start
| Prototype |
sub procedure PWM16bit_Start(dim timer as byte) |
|---|---|
| Returns |
Nothing. |
| Description |
Starts PWM-16bit module with alredy preset values (wave mode, prescaler, inverted and duty) given in the PWM16bit_Init. |
| Requires |
MCU must have CMO module to use this library.
PWM16bit_Init must be called before |
| Example |
PWM16bit_Start( _TIMER1 ) ' Starts the PWM-16bit module on Timer/Counter1 or PWM16bit_Start( _TIMER3 ) ' Starts the PWM-16bit module on Timer/Counter3 |
PWM16bit_Stop
| Prototype |
sub procedure PWM16_Stop(dim timer as byte) |
|---|---|
| Returns |
Nothing. |
| Description |
Stops the PWM-16bit module, connected to Timer/Counter set in this stop function. |
| Requires |
MCU must have CMO module to use this library. Like in
PWM16bit_Start before, PWM16bit_Init must be called before |
| Example |
PWM16bit_Stop( _TIMER1 ) ' Stops the PWM-16bit module on Timer/Counter1 or PWM16bit_Stop( _TIMER3 ) ' Stops the PWM-16bit module on Timer/Counter3 |
Library Example
The example changes PWM duty ratio continually by pressing buttons on PORTC (0-3). If LED is connected to PORTB.B1 or PORTB.B2 ,you can observe the gradual change of emitted light. This example is written for ATmega168. This AVR MCU has only Timer/Counter1 split over two channels A and B. In this example we are changing the duty ratio on both of these channels.
program PWM_Test
dim current_duty as byte
current_duty1 as byte
main:
DDC0_bit = 0 ' Set PORTC pin 0 as input
DDC1_bit = 0 ' Set PORTC pin 1 as input
DDC2_bit = 0 ' Set PORTC pin 2 as input
DDC3_bit = 0 ' Set PORTC pin 3 as input
current_duty = 127 ' initial value for current_duty
current_duty1 = 127 ' initial value for current_duty
DDB1_bit = 1 ' Set PORTB pin 1 as output pin for the PWM (according to datasheet)
DDB2_bit = 1 ' Set PORTB pin 2 as output pin for the PWM (according to datasheet)
PWM16bit_Init(_PWM16_FAST_MODE_9BIT, _PWM16_PRESCALER_16bit_1, _PWM16_INVERTED, 255, 1)
while TRUE ' Endless loop
if (PINC.B0 <> 0) then ' Detect if PORTC pin 0 is pressed
Delay_ms(40) ' Small delay to avoid deboucing effect
Inc(current_duty) ' Increment duty ratio
PWM_Set_Duty(current_duty) ' Set incremented duty
end if
if (PINC.B1 <> 0) then ' Detect if PORTC pin 1 is pressed
Delay_ms(40) ' Small delay to avoid deboucing effect
Dec(current_duty) ' Decrement duty ratio
PWM_Set_Duty(current_duty) ' Set decremented duty ratio
end if
if (PINC.B2 <> 0) then ' Detect if PORTC pin 2 is pressed
Delay_ms(40) ' Small delay to avoid deboucing effect
Inc(current_duty1) ' Increment duty ratio
PWM1_Set_Duty(current_duty1) ' Set incremented duty
end if
if (PINC.B3 <> 0) then ' Detect if PORTC pin 3 is pressed
Delay_ms(40) ' Small delay to avoid deboucing effect
Dec(current_duty1) ' Decrement duty ratio
PWM1_Set_Duty(current_duty1) ' Set decremented duty ratio
end if
wend
end.
HW Connection

PWM demonstration
What do you think about this topic ? Send us feedback!




