10-Bit PWM using PIC16F1509


Closed Thread
Results 1 to 20 of 20
  1. #1
    Join Date
    Jan 2011
    Location
    Sydney, Australia
    Posts
    166

    Default 10-Bit PWM using PIC16F1509

    Hi All,

    I am working my way through the process of setting up a 10-Bit PWM channel using a PIC16F1509 and have hit a major hurdle - I am stumped and don't know what to do.
    My project is for an RGB LED Controller using slider pots to control the PWM signal being fed to the RGB LEDs.
    I have the basic principle operating using HPWM commands but this limits the control to 8-bits and I want to take advantage of the device's 10-bit PWM capability.
    Using the calculation in the datasheet, I can achieve 10-bit PWM resolution for my desired 250Hz PWM frequency with a 4MHz internal oscillator, PR2 = 255 and TMR2 Prescale = 16
    My problem is when I try to set the PWM1CON register or load the high and low PWM duty cycle registers.
    My code is as follows:

    Code:
    '****************************************************************
    '*  Name    : RGB_LED_Controller_16F1509.pbp                    *
    '*  Author  : Barry Phillips                                    *
    '*  Notice  : Copyright (c) 2015 Baztronics                     *
    '*          : All Rights Reserved                               *
    '*  Date    : 27/02/2015                                        *
    '*  Version : 1.0                                               *
    '*  Notes   : RGB LED Controller using PIC16F1509               *
    '*          :                                                   *
    '****************************************************************
    #CONFIG
        __config _CONFIG1,     _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
        __config _CONFIG2,     _WRT_OFF & _STVREN_OFF & _LPBOR_OFF & _LVP_OFF
      #ENDCONFIG
     
    OSCCON= %01101000                   'Internal 4MHz Oscillator
    DEFINE OSC 4                       'Internal RC Oscillator 8MHz
    
    ' Connect LCD D4 to RB4 (Pin 13)
    ' Connect LCD D5 to RB5 (Pin 12)
    ' Connect LCD D6 to RB6 (Pin 11) 
    ' Connect LCD D7 to RB7 (Pin 10)
    ' Connect LCD R/S to RC3 (Pin 7)
    ' Connect LCD E   to RC6 (Pin 8)
    ' Connect POT1 to RA0 (Pin 19)
    ' Connect POT2 to RA1 (Pin 18)
    ' Connect POT3 to RC0 (Pin 16)
    ' Connect POT4 to RC2 (Pin 14)
    ' Connect PWM1 to RC5 (Pin 5)
    ' Connect PWM2 to RC7 (Pin 9)
    ' Connect PWM3 to RA2 (Pin 17)
    ' Connect PWM4 to RC1 (Pin 15)
    ' Connect SW1 to RA5 (Pin 2)
    ' Connect SW2 to RA1 (Pin 3)
    ' Connect SW3 to RA3 (Pin 4)
    
    @ ERRORLEVEL -306            ' Turn off "Crossing page boundary" error message
    
    
    ' Define LCD registers and bits
    Define	LCD_DREG	PORTB
    Define	LCD_DBIT	4
    Define	LCD_RSREG	PORTC
    Define	LCD_RSBIT	3
    Define	LCD_EREG	PORTC
    Define	LCD_EBIT	6
    Define	LCD_BITS	4
    Define	LCD_LINES	4
    Pause 500
    
    DEFINE ADC_BITS 10                  'Set number of bits in result (8, 10 or 12)
    DEFINE ADC_CLOCK 3                  'Set clock source (rc = 3)
    DEFINE ADC_SAMPLEUS 50              'Set sampling time in microseconds
    
    TRISA = %00111011                   'Set PORTA.0, 1, 3, 4 & 5 as digital inputs               
    TRISB = %00000000                   'Set PORTB as all digital outputs
    TRISC = %00000101                   'Set PORTC.0 & 2 as digital inputs                  
    ANSELA = %00000011                  'Set PORTA.0 & 2 as analog inputs
    ANSELB = %00000000                  'Disable PORTB analog inputs
    ANSELC = %00000101                  'Set PORTC.0 & 2 as analog inputs
    
    ADCON0 = %00000001                  'Enable ADC
    ADCON1 = %11010000                  'Right Justify
                                        'Fosc/16
                                        'Vref connected to Vdd                                  
    FVRCON.7 = 0                        'Disable Fixed Voltage Reference
    CM1CON0.7 = 0						'Disable Comparitor 1
    CM2CON0.7 = 0						'Disable Comparitor 2
    INTCON.7 = 0						'Disable Interrupts
    
    T2CON = %00000110					'Enable TMR2 and set PreScale to 16
    
    ' Set up PWM Registers
    PWM1CON = %11000000
    PR2 = %11111111
    
    POT1	VAR		WORD
    POT2	VAR		WORD
    POT3	VAR		WORD
    POT4	VAR		WORD
    ScaledPot1	VAR	WORD
    Dummy	VAR		WORD
    
    
    	LCDOUT $FE, $1
    	LCDOUT $FE, $80, " ** BAZTRONICS **  "
    	LCDOUT $FE, $C0, "RGB LED Controller "
    	LCDOUT $FE, $94, "   Version 1.1     "
    	LCDOUT $FE, $D4, "                   "
    	Pause 2000
    	LCDOUT $FE, $1
    
    Start:
    	ADCIN 0, POT1
    	LCDOUT $FE, $80, "POT1 = ", DEC POT1, "    ", DEC ScaledPot1, " "
    	ADCIN 1, POT2
    	LCDOUT $FE, $C0, "POT2 = ", DEC POT2, " "
    	ADCIN 4, POT3
    	LCDOUT $FE, $94, "POT3 = ", DEC POT3, " "
    	ADCIN 6, POT4
    	LCDOUT $FE, $D4, "POT4 = ", DEC POT4, " "
    	Pause 100
    	PWM1DCH = POT1.HIGHBYTE
    	PWM1DCL = POT1.LOWBYTE
    GOTO Start
    
    End
    When I try to compile this code I get syntax error messages for the following lines:
    PWM1CON = %11000000
    PWM1DCH = POT1.HIGHBYTE
    PWM1DCL = POT1.LOWBYTE

    I cannot see anything wrong with the syntax in these three lines of code. Can anyone shed some light on what it is wrong?

    I am using PBP3 (Version 3.0.5.4)) and MCS (Version 5.0.0.0)

    Cheers
    Barry
    VK2XBP

  2. #2
    Join Date
    May 2013
    Location
    australia
    Posts
    2,381


    Did you find this post helpful? Yes | No

    Default Re: 10-Bit PWM using PIC16F1509

    your code complies ok for me
    chk pic16f15009 microcontroller selected and mpasm assembler selected


    for 10 bit pwm you need to
    pot1<<6 before you load the regs

    Code:
    pot1=pot1<<6
     PWM1DCH = POT1.HIGHBYTE
     PWM1DCL = POT1.LOWBYTE
    ps
    I'm assuming pot1 is 0-1023 value of course


    you could be clever here an not right justify adc reading and save a step
    Last edited by richard; - 27th February 2015 at 04:51. Reason: ps and my 'd' key is dodgy

  3. #3
    Join Date
    May 2013
    Location
    australia
    Posts
    2,381


    Did you find this post helpful? Yes | No

    Default Re: 10-Bit PWM using PIC16F1509

    I am using PBP3 (Version 3.0.7.4)) and MCS (Version 5.0.0.5)

  4. #4
    Join Date
    Jan 2011
    Location
    Sydney, Australia
    Posts
    166


    Did you find this post helpful? Yes | No

    Default Re: 10-Bit PWM using PIC16F1509

    Thanks Richard.

    I updated the versions of PBP3 and MCS and everything now compiles...

    Cheers
    Barry
    VK2XBP

  5. #5
    Join Date
    Feb 2013
    Posts
    1,078


    Did you find this post helpful? Yes | No

    Default Re: 10-Bit PWM using PIC16F1509

    Having same idea, to control RGB led using PWM, but how you did it with 1 hardware channel PWM?

  6. #6
    Join Date
    Apr 2014
    Location
    OK
    Posts
    557


    Did you find this post helpful? Yes | No

    Default Re: 10-Bit PWM using PIC16F1509

    Great question! I don't know. I would suggest if you have 3 different targets (R + B + G) each requiring a different PWM DC%, you will need a PIC with 3 separate PWM channels.

  7. #7
    Join Date
    Feb 2013
    Posts
    1,078


    Did you find this post helpful? Yes | No

    Default Re: 10-Bit PWM using PIC16F1509

    And that appears to be a hard task - most MCUs as I've checked from datasheet, have "synchronised" PWM outputs, which mostly mirror each other, and also they all run same frequency....

  8. #8
    Join Date
    Sep 2009
    Posts
    737


    Did you find this post helpful? Yes | No

    Default Re: 10-Bit PWM using PIC16F1509

    Take look at SPWM from DT. Or better MIBAM.

  9. #9
    Join Date
    Apr 2014
    Location
    OK
    Posts
    557


    Did you find this post helpful? Yes | No

    Default Re: 10-Bit PWM using PIC16F1509

    Quote Originally Posted by CuriousOne View Post
    And that appears to be a hard task - most MCUs as I've checked from datasheet, have "synchronised" PWM outputs, which mostly mirror each other, and also they all run same frequency....
    All that means is that the Period for each starts at the same time, and they operate at the same frequency. Each is capable of independent Duty Cycle. That will work for an RGB LED.

  10. #10
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,795


    Did you find this post helpful? Yes | No

    Default Re: 10-Bit PWM using PIC16F1509

    Mike, that means a PIC should have different CCPxCON registers. As many as the different channels, so the user can define the duty of each independently.

    For example, the 16F887 has two and 16F1939 has four CCPxCON registers.

    Ioannis
    Last edited by Ioannis; - 21st January 2020 at 16:04. Reason: typo

  11. #11
    Join Date
    May 2013
    Location
    australia
    Posts
    2,381


    Did you find this post helpful? Yes | No

    Default Re: 10-Bit PWM using PIC16F1509

    its fairly easy to get 3 different pwm streams from one ccpm module , you just to need to
    1. set pulse width for channel
    2. set pin steering to channel pin
    in a sequentially multiplexed routine
    eg
    Code:
    /**
      Generated Main Source File
    
    
            Device            :  PIC16F1825
            Driver Version    :  2.00
     */
    
    
    int pwmv[3];
    char cnt = 0;
    void ticker(void);
    
    
    
    
    #include "mcc_generated_files/mcc.h"
    
    
    /*
                             Main application
     */
    void main(void) {
        // initialize the device
        SYSTEM_Initialize();
        TMR1_SetInterruptHandler(ticker);
        // When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
        // Use the following macros to:
        PSTR1CON = 0x10;
        // Enable the Global Interrupts
        INTERRUPT_GlobalInterruptEnable();
    
    
        // Enable the Peripheral Interrupts
        INTERRUPT_PeripheralInterruptEnable();
    
    
        // Disable the Global Interrupts
        //INTERRUPT_GlobalInterruptDisable();
    
    
        // Disable the Peripheral Interrupts
        //INTERRUPT_PeripheralInterruptDisable();
    
    
        while (1) {
            pwmv[cnt] = ADC_GetConversion(cnt);
            __delay_ms(300);
            cnt++;
            cnt &= 3;
            // Add your application code
        }
    }
    
    
    void ticker(void) {
        static char inx = 0;
        CCPR1L = pwmv[inx] >>8;
        CCP1CON = ((pwmv[inx]&0xc0)>>2) | 0xC;
        PSTR1CON = 0x10 | (2 << inx);
        inx++;
        inx &= 3;
    }
    this sort of led modulation is exactly how those p10 led modules work
    Attached Images Attached Images  
    Last edited by richard; - 22nd January 2020 at 02:04.
    Warning I'm not a teacher

  12. #12
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,795


    Did you find this post helpful? Yes | No

    Default Re: 10-Bit PWM using PIC16F1509

    Hi Richard. Thanks for posting this. I was not aware this was possible.

    But, doesn't this have glitches in the signal when steering is changing channel?

    Have to try this in real hardware.

    Ioannis

  13. #13
    Join Date
    May 2013
    Location
    australia
    Posts
    2,381


    Did you find this post helpful? Yes | No

    Default Re: 10-Bit PWM using PIC16F1509

    24.4.6.1 Steering Synchronization
    The STRxSYNC bit of the PSTRxCON register gives
    the user two selections of when the steering event will
    happen. When the STRxSYNC bit is ‘0’, the steering
    event will happen at the end of the instruction that
    writes to the PSTRxCON register. In this case, the
    output signal at the Px<D:A> pins may be an
    incomplete PWM waveform. This operation is useful
    when the user firmware needs to immediately remove
    a PWM signal from the pin.
    When the STRxSYNC bit is ‘1’, the effective steering
    update will happen at the beginning of the next PWM
    period. In this case, steering on/off the PWM output will
    always produce a complete PWM waveform.

    in the isr you could add a PSTR1CON = 0 before setting new pwm value
    or maybe even read the data sheet re glitch free pwm updates

    i didn't go to too much effort for this.
    Warning I'm not a teacher

  14. #14
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,795


    Did you find this post helpful? Yes | No

    Default Re: 10-Bit PWM using PIC16F1509

    Well, after reading the Steering on 16F887 I think it is not possible to have 4 different PWM signals at the same time on a chip that lacks more channels.

    The 887 has 2 channels, so 2 different PWM signals can be produced by hardware. I really do not have fully understood what steering is there for but I am sure not for more free channels.

    The datasheet says that the SAME PWM signal can be simultaneously available on multiple pins. Not different PWM signals.

    I hope I am wrong but that is what data sheet says as I understand it.

    Ioannis

  15. #15
    Join Date
    Aug 2011
    Posts
    408


    Did you find this post helpful? Yes | No

    Default Re: 10-Bit PWM using PIC16F1509

    its fairly easy to get 3 different pwm streams from one ccpm module , you just to need to...
    Maybe I'm missing something here.

    What does LED1 do while the signal goes out to LED2 and then LED3?

  16. #16
    Join Date
    May 2013
    Location
    australia
    Posts
    2,381


    Did you find this post helpful? Yes | No

    Default Re: 10-Bit PWM using PIC16F1509

    What does LED1 do while the signal goes out to LED2 and then LED3?
    its unlit for 4mS of a 6mS drive signal period . pov makes the gap invisible at that rate


    the pwm freq is 2kHz the isr switches the pwm drive @ 2mS intervals . for a pov objective its quite effective
    its basically the same as how a 1/4 scan or a 1/8 scan led panel works, except its 1/3 scan

    try it .
    Warning I'm not a teacher

  17. #17
    Join Date
    Feb 2013
    Posts
    1,078


    Did you find this post helpful? Yes | No

    Default Re: 10-Bit PWM using PIC16F1509

    POV might make it invisible to eye, but cameras see all that flickering very well, and giving very poor recording. So unfortunately, that is not the way to go...

  18. #18
    Join Date
    Aug 2011
    Posts
    408


    Did you find this post helpful? Yes | No

    Default Re: 10-Bit PWM using PIC16F1509

    Plus, I would think having the led off 2/3 of the time would decrease the brightness quite a bit.

  19. #19
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,795


    Did you find this post helpful? Yes | No

    Default Re: 10-Bit PWM using PIC16F1509

    It is kinda multiplexed PWM signal I think.

    Ioannis

  20. #20
    Join Date
    May 2013
    Location
    australia
    Posts
    2,381


    Did you find this post helpful? Yes | No

    Default Re: 10-Bit PWM using PIC16F1509

    Plus, I would think having the led off 2/3 of the time would decrease the brightness quite a bit.
    it won't do for room lighting, it's still useful though

    mp4 attached
    Attached Files Attached Files
    Warning I'm not a teacher

Similar Threads

  1. DMX512 Reception + 3 * 8-Bit PWM Outputs
    By JEC in forum Code Examples
    Replies: 5
    Last Post: - 16th February 2015, 16:21
  2. 16 bit PWM using CCP1
    By Normnet in forum mel PIC BASIC Pro
    Replies: 60
    Last Post: - 27th August 2014, 09:13
  3. Replies: 17
    Last Post: - 22nd May 2014, 20:58
  4. Replies: 1
    Last Post: - 13th March 2012, 00:34
  5. 10 bit pwm as dac
    By yasser hassani in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 30th June 2004, 16:12

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts