PDA

View Full Version : HPWM the old fashioned way



Srigopal007
- 19th November 2004, 19:09
hello everyone: I am working with the PWM using the old fashion way. Only to learn the hardware architecture of the PIC, and to learn the names of the registers being used for the PWM process.
But I am stuck. How do I make the leds fade up and fade down.. I have the following that I cut and pasted from the melabs website and was wondering if someone can help me extract some data.
I have set the PR2 register myself since I wanted a frequency of 4khz. the PR2 = 155
and then I set the CCPR1L registers and stuffed the CCP1CON <5:4> pins with the 2 bits. to make it a 10bit PWM.
here is what I have so far. But one thing that I am having is how do I incorporate another CCP2 for PWM support. what timer to use.
I am using the 18F6520 as the PIC of choice. only becasue it has 5 PWM channels. and plan to use most of them very quickly.

here is the code that I have so far:

==============================================
include "modedefs.bas"

' PicBasic Pro Program to demonstrate hardware PWM.
' Output is a 1Khz signal with duty cycle sweeping
' from 0% to 80% once per second

' Note: PWM output will be on the CCP1 pin. Register
' names are for the PIC16F87x devices.

' PR2 = Timer2 period register, controls PWM period.
' CCPR1L and CCP1CON<5:4>bits control the duty cycle,
' and should be treated as a 10-bit word.

' Fosc = Clock Frequency (4MHz)
' PS = Timer2 Prescale Value (T2CON<1:0>)
' Freq = PWM output frequency
' Duty% = Duty cycle (80% = 0.8)

' formulas:
' PR2=(Fosc/(4*PS*Freq))-1
' CCPR1L:CCP1CON<5:4>=(PR2+1)*4*Duty%

duty VAR WORD ' Duty cycle value (CCPR1L:CCP1CON<5:4>)
START:

TRISC.2 = 0 ' Set PORTC.2 (CCP1) to output
CCP1CON = %00001100 ' Set CCP1 to PWM
CCP2CON = %00001100 ' Set CCP2 to PWM
T2CON = %00000110 ' Turn on Timer2, Prescale=16

' Use formula to determine PR2 value for a 1KHz signal,
' 4MHz clock, and prescale=4. (4E6/(4*4*1E3))-1=249

PR2 = 155 ' Set PR2 to get 4KHz out
'PR2 = 1001 1100

' Use formula to determine CCPR1L:CCP1CON<5:4> value for
' ends of range 0% to 100%. (156+1)*4*0.0=0 (0% value)
' (155+1)*4*1.00=624 (80% value)


duty = 0 ' Set duty cycle to 20%
'Go from ALL LEDS OFF TO BLUE LED ON
Loop1: CCP1CON.4 = duty.0 ' Store duty to registers as
CCP1CON.5 = duty.1 ' a 10-bit word
CCPR1L = duty >> 2

duty = duty + 1 ' Increase duty cycle

' Since the total sweep of duty is 624 (624 - 0) and
' we are adding 1 for each loop, that results in 624
' steps min to max. 1 second divided by 624 = 1.67mS

Pause 2 ' Pause 1/60 of second

IF (duty < 624) Then Goto Loop1' Do it again unless 80% duty cycle

duty = 0 ' Reset to 20% duty cycle


GoTo Loop2

Loop2:

CCP2CON.4 = duty1 .0
CCP2CON.5 = duty1.1
CCPR2L = duty1 >> 2

duty = duty + 1 'increase duty cycle

' Since the total sweep of duty is 624 (624 - 0) and
' we are adding 1 for each loop, that results in 624
' steps min to max. 1 second divided by 624 = 1.67mS
Pause 2

if(duty < 624) then Loop2
if(duty >= 624) then Loop3
duty = 0

GoTo Loop2
==============================================

again note that I want to ramp up and down the intensity of the LEDs slowly. I can easily use the PBP's library and have easily done it the easy way by have multiple HPWM statements.. but please I want to do it the long and old fashioned way. Thanksss


srigopal