Jump to content
 
  • entries
    31
  • comments
    47
  • views
    24,542

Contributors to this blog

Getting Started in Embedded Programming Pt 4


N9WXU

579 views

 Share

Today I am going to introduce a peripheral.  So far we have interacted with the I/O pins on the micro controller.  This can get you pretty far and if you can manipulate the pins quickly enough you can produce nearly any signal.  However, there are times when the signal must be generated continuously and your MCU must perform other tasks.

Today we will be generating a PWM signal.  PWM stands for Pulse Width Modulation.  The purpose of PWM is to produce a fixed frequency square wave but the width of the high and low pulses can be adjusted.  By adjusting the percentage of the time the signal is high versus low, you can change the amount of energy in a system.  In a motor control application, changing the energy will change the speed.  In an LED application, changing the energy will change the brightness.  We will use the PWM to change the brightness of the LED on our demo board.

Here is a sample of a PWM signal.  The PWM frequency is 467.3hz and the duty cycle is 35%.

image.png

One way to produce such a signal is to execute a bit of code such as this one.

do_pwm macro
    banksel pwm_counter
    movlw   pwm_reload
    decfsz  pwm_counter,f
    movf    pwm_counter,w
    movwf   pwm_counter
    banksel pwm
    subwf   pwm,w
    banksel LATA
    movf    LATA,w
    andlw   0xFB
    btfss   STATUS,C
    iorlw   0x04
    movwf   LATA   
    endm

This code does not help you if you are writing in C but it will serve to show the challenges of this technique.  This is a simple macro that must be executed numerous times to produce the entire PWM cycle.  The PWM frequency is determined by how often this macro can be called.  So one option is quite simply this:

loop
	do_pwm
	goto	loop

But if you do this the MCU will not be able to perform any other functions.  

loop
    do_pwm

    banksel reload
    incfsz  reload
    goto    loop
    
    banksel pwm
    incf pwm,f

    goto    loop

Here is one that updates the PWM duty cycle every time the reload variable overflows.  This is not a lot of additional work but the MCU is still 100% consumed toggling a pin and deciding when to update the duty cycle.  Surely there is a better way.

Enter a Peripheral

MCU Peripherals are special hardware functions that can be controlled by the software but do some tasks automatically.  One common peripheral is the PWM peripheral.  Different MCU have different peripherals that can produce a PWM signal.  For instance, older PICmicrocontrollers have the CCP (Capture, Compare, PWM) peripheral and newer PICmicrocontrollers have dedicated PWM's.  To demonstrate the use of this simple peripheral I will switch to C and give some code.

The good side to using a peripheral is the work it takes on.  The down side is the additional effort required to setup the additional hardware.  Microchip provides a tool call MCC to do this work but in this example, we will do the work ourselves.  Fortunately, Microchip provided a section in the data sheet that provides an 8 step checklist for configuring the PWM.image.png

Time for doing the steps

    // Steps from Chapter 30.9 of the datasheet
    // Step 1
    TRISAbits.TRISA2 = 1;
    // Step 2
    PWM6CON = 0;
    // Step 3
    T2PR = 0xFF;
    // Step 4
    PWM6DC = 358 << 6;
    // Step 5
    T2CLKCONbits.CS = 1;
    T2CONbits.CKPS = 0;
    T2CONbits.ON = 1;
    // Step 6
    // Step 7
    TRISAbits.TRISA2 = 0;
    RA2PPS = 0x0D;
    // Step 8
    PWM6CONbits.EN = 1;
    

And here is 35% just like before, except last time the period of the entire wave was 2.14ms and now it is 0.254ms.  That is about 10x faster than before.

image.png

This time the main loop is doing absolutely nothing making it possible to do all kinds of neat things like implement a flicker to make the LED look like a candle.

    while(1)
    {
        __delay_ms(5);
        PWM6DC = rand() % 1024 << 6;
    }

So here is a candle.  Through honestly it is not the best looking candle.  Perhaps you can do a better job.

Peripherals can be a huge time saver and can certainly provide more CPU in your application for the real "secret sauce".   Most of the data sheet covers peripherals so we will go through a few of them in the next few weeks.

 

Good Luck

 

Step_4.zip

step_4_asm.zip

  • Helpful 1
 Share

0 Comments


Recommended Comments

There are no comments to display.

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...