This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

PWM using CAPCOM

Hi

Does anyone know where to find any example of implementing PWM using CAPCOM especially in XC161 (16 bit microcontroller)?

MJ

  • In my opinion, there is more than enough information in the Infineon peripheral user's manual to configure a CAPCOM channel for a simple autonomous PWM.

    What are the criteria for the PWM? Again, in my opinion this discussion would drive the solution (implementation).

    What are the issues that you don't understand about the CAPCOM?

    Here a very simplistic example. It is for CAPCOM1, T0, CC0 and runs in staggered mode. The CAPCOM clock frequency is assumed 20MHz.

    T0 is configured for a period of 100msec and CC0 set the P6.0 (to 1) at 50% DC and the overflow clears the P6.0 (to 0).

    #include "xc161.h"
    #include <intrins.h>
    
    void main(void)
    {
      CC1_T01CON = 0x0003u;
      CC1_M0 = 0x0007u;
    
      CC1_T0    = 0x85EEu;
      CC1_T0REL = 0x85EEu;
      CC1_CC0   = 0xC2F7u;
    
      /* P6.0 is used for CAPCOM1 Output (CC0IO) */
      ALTSEL0P6 |= 0x0001u;
      _bfld_(DP6,0x01u,0x01u);
    
      CC1_T01CON_T0R = 1;
    
      while(1) {
        _nop_();
       }
    }
    
    

  • Would you mind to tell me how you did calculate the value of CC1_TOREL?

    MJ

  • No problem, the timer T0 is running at a clock frequency of 20MHz/64 = 3.2usec per tick. The CAPCOM timers can ONLY count up. The example uses the CAPCOM channel 0 in Compare Mode 3 and is associated to T0.

    I arbitrarily selected a period of 100mseconds. So 100msec/3.2usec = 31250 or 0x7A12 counts. Since the CAPCOM can only count up you need to subtract this from 0x10000 which gives you 0x10000 – 0x7A12 = 0x85EE.

    Does this answer your question?

    -Chris

  • Hi

    I understand that part but I don't understand some of the codes such as

    CC1_CC0 = 0xC2F7u;
    ALTSEL0P6 |= 0x0001u;
    _bfld_(DP6,0x01u,0x01u);

    Can you please kindly explain that to me?

    MJ

  • Ok, I arbitrarily selected a duty cycle of 50%. A 50% DC is simply half of the period which I calculated before to be 0x7A12. So take 0x7A12/2 = 0x3D09, but remember that the timer only counts up so again you need to subtract this from 0x10000. Then the compare value for CC0 would be 0x10000 – 0x3D09 = 0xC2F7. I said that the channel is running in compare mode 3 so when the timer (T0) matches the value in the CC0 register the port pin associated with CC0 (P6.0) is set high (to 1). When the timer overflows the port associated with CC0 (P6.0) is cleared (to 0).

    You can achieve a 0% DC by programming the CC0 value less than period value. You can not achieve 100% DC without directly controlling the pin since the timer overflow will always reset (clear) the output.

    Some examples to write to the CC0 register for different DC values would be:
    0x85EF = 99.9968%
    0xC2F7 = 50.0000%
    0xFFFF = 0.0032%
    0x0 thru 0x85EE = 0.0000%

    The ports can be used for general purpose I/O or for different functions. To internally map the port pin (P6.0) to the CAPCOM then you need to have a 1 in the zero bit of the ALTSELOP6 register (It Assumes that NO external Bus is enabled, thus no chip selects). Since I only need to make sure that I have a one in the register a simple OR to the register can be made.

    ALTSEL0P6 |= 0x0001u;
    
    For the setting the port I used the intrinsic instruction _bfld_ (more from habit) since I usually need to modify more than one bit setting and clearing at the same time for a port configuration. The Keil compiler will generate the proper instruction based on the mask and data. Have a look to the instruction set for more definition. Since I am using the CAPCOM to generate an outbound signal you need to make the port pin an output. Have a look to the Infineon Systems User's Manual under parallel ports.

    The instruction could have been this since I only need to set one bit.
    DP6 |= 0x0001u;
    

    I would also suggest you try using DAVE to see how it handles setting up the ports.

    Let me know if you have more questions.