In previous post I putted some examples of using the dsPIC30F2010 prototype board. However it's too long. So I need to write some remaining posts here.
Creating a PWM Output Using Code Generation Wizard
Generating a PWM output signal could be done from scratch with a few line of code using CCS PICC. We can use its code generation wizard or even manually.
![]() |
PWM Output Pin of OC1 |
After clicking on Create Project it will generate source code. Then pressing F9 to compile this project.
The main.c C source code is just like below.
- #include <main.h>
- void main()
- {
- while(TRUE)
- {
- //TODO: User Code
- }
- }
Then double click on the main.h header file we will see its source code.
- #include <30F2010.h>
- #device ICSP=1
- #use delay(crystal=20000000)
- #FUSES NOWDT //No Watch Dog Timer
- #FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
- #use pwm(OC1,TIMER=2,FREQUENCY=10000,DUTY=0)
It will generate a PWM signal output at pin OC1 (RC13) with a frequency of 10kHz and 0% duty cycle. If we want a 50% duty cycle we need to change the DUTY parameter to 50, and rebuilt it.
PWM Duty Cycle Adjusting with ADC
After using the code generation wizard I got some idea of using PWM in CCS PICC. So I modify and write more codes to adjust PWM signal. I use the on-board ADC input from a potentiometer. Then it will convert to PWM duty cycle ranging from 0% to 100%.
- #include "board.h"
- #use pwm(OC1,TIMER=2,FREQUENCY=10000,STREAM=_1,DUTY=50)
- void main()
- {
- long adc_value = 0;
- float duty_cycle = 0;
- setup_adc_ports(sAN4);
- setup_adc(ADC_CLOCK_INTERNAL | ADC_TAD_MUL_31);
- while(TRUE)
- {
- //TODO: User Code
- set_adc_channel(4);
- delay_us(10);
- adc_value = read_adc();
- duty_cycle = (1000.0*adc_value)/1023;
- pwm_set_duty(_1,(int)duty_cycle);
- //pwm_set_duty_percent(_1,(int)duty_cycle);
- delay_ms(100);
- }
- }
And its "board.h" file:
- #include <30F2010.h>
- #device ADC=10
- #device ICSP=1
- #fuses HS,NODEBUG,NOWDT,PR,CKSFSM
- #use delay(crystal=20000000)
- #use FIXED_IO( D_outputs=PIN_D1,PIN_D0 )
- #use rs232(UART1, baud=9600, stream=UART_PORT1)
- #define LED0 PIN_D0
- #define LED1 PIN_D1
- #define SW0 PIN_C13
- #define SW1 PIN_C14
- #define DELAY 500
It work fine without wiring additional components. However we can connect the OC1(RC13) PWM pin to a larger LED ( for instance a 5VDC 10mm LED).
![]() |
Low Duty Cycle |
![]() |
High Duty Cycle |
ADC with On-board Tactile Switches and PWM
Fortunately there are two on-board tactile switches that could be used to adjust PWM duty cycle. So I will use ADC channel 4, SW4 (RC13) and SW5(RC14) to adjust PWM duty cycle of OC1 and OC2 respectively.
The PWM OC1 is generated by Timer 2 while the PWM OC2 is generated by Timer 3.