ADC to PWM Demonstration

Coding and general discussion relating to the compiler

Moderators: David Barker, Jerry Messina

Post Reply
xor
Posts: 286
Joined: Sun Nov 05, 2006 1:15 pm
Location: NYC
Contact:

ADC to PWM Demonstration

Post by xor » Sat Nov 18, 2006 11:24 pm

This is a simple PWM demonstration to dim LED's connected to PORTB. It reads a pot connected to RA2 which varies the voltage to the AN2 ADC on an 18F452.

The program uses Timer2 as a counter and timer set up to increment every 8us (prescaler = 16) and will provide a Period of 2048us (256 x 8us). We can create an ON-OFF cycle within that period by using the ADC reading in its 8-bit form. You can create an accurate 8-bit reading by shifting the 10-bit result left into the ADRESH register. This is easily done by setting ADCON1.7 = 0. Comparing the Timer2 value to the ADC value and we can effectively control the ON and OFF duty cycle within the 2048us (488 Hz).

Enjoy.

Code: Select all

{
****************************************************************
*  Name    : ADC2PWM.BAS                                       *
*  Author  : Warren Schroeder alias "xor"                      *
*  Notice  : Copyright (c) 2006 Warren Schroeder               *
*          : All Rights Reserved                               *
*  Date    : 11/18/2006                                        *
*  Version : 1.0                                               *
*          ;                                                   *
*  Notes   : Simple demonstration using an 8-bit ADC reading   *
*          : to do LED dimming using PWM techniques            *
*          ; Tested using a 18F452 @ 8MHz on an EasyPIC3       *
*          : Development Board connected to 8 LED's on PortB   *
****************************************************************
}
Device = 18F452
Clock = 8

Include "ADC.bas"

TRISA = 4                       ' RA2/AN2 as input
LATB = 0                        ' initialize PortB output register
TRISB = 0                       ' PortB is all outputs
T2CON = 7                       ' Timer2 is ON and Prescaler=16; Timer2 increments every 8us 
ADCON1 = 66                     ' left justify; TOSC=16; AN0 to AN5 enabled 

Repeat                          ' start routine
  If ADC.Read(AN2) <> 0 Then    ' read ADC2 and store 8 bit result in ADRESH 
    TMR2 = 0                    ' initialize Timer2 
    Repeat                        
        LATB = 255              ' turn on PortB 
    Until TMR2 = ADRESH         ' keep ON until Timer2 is ADC value
    Repeat                                                           
        LATB = 0                ' turn off PortB
    Until TMR2 = 0              ' keep OFF until Timer2 increments to rollover 
  End If   
Until 0=1                       ' do all again 

User avatar
Darrel Taylor
Posts: 29
Joined: Wed Oct 04, 2006 4:44 pm
Location: California

Post by Darrel Taylor » Sun Nov 19, 2006 1:06 am

Hi Warren,

Just curious if there's some advantage to using LATB, instead of PORTB in your program?

Is it to overcome the Read/Modify/Write problem of the port?

Why the PWM output on all 8 pins of PORTB?

And, why not use the CCP module, since the PIC is now stuck doing a single task.
Best regards,
DT

xor
Posts: 286
Joined: Sun Nov 05, 2006 1:15 pm
Location: NYC
Contact:

Post by xor » Sun Nov 19, 2006 5:41 am

Hi DT,

Interesting question about LATB and PORTB. Swordfish was intelligent enough to make the correct conversions in assembler from some of my preliminary tests....a noteworthy accomplishment for the programmer(s). LATB is the output register and it is, from my limited knowledge of these sort of things, a method to overcome some of the problems encountered with Read-Modify-Write issues, especially when changing single bits on a PORT with the BSF and BCF instructions. I personally use LATx for all output operations with P18's, and use PORTx for input readings.

The program I posted is not meant to be a practical application as much as a learning tool to cover different aspects of using Swordfish with a PIC. In the above example the ADC library is utilized in a particularly useful way, and then we can see how software PWM techniques might be used to dim an LED. Lest we forget, a PIC timer can be a useful tool without implementing interrupts or flags. There is also the demonstration of how to use an analog input to create a proportional analog-like output with a digital device.

There is much managed here in a concise way that doesn't require much study by the reader...and you never know when the most mundane routines provide ideas for a bigger project.... :D

User avatar
Darrel Taylor
Posts: 29
Joined: Wed Oct 04, 2006 4:44 pm
Location: California

Post by Darrel Taylor » Sun Nov 19, 2006 7:25 pm

Thanks for the info Warren,

I've always known LATB was there, but never saw anyone use it before, and never really thought much about what it was there for.

And, "roger that" on the "learning tool".
Best regards,
DT

Post Reply