PDA

View Full Version : 16F684 adcin and hpwm



astouffer
- 17th November 2008, 16:21
I'm having a bit of trouble trying to get an adjustable pwm signal out of a 16F684. My version of MPLAB is 8.0 and MPASM is 5.14. The code was pieced together from posts on this forum and a few other sites as well. What I'm hoping to do is get an adjustable 6khz pwm signal with a 0-80% duty cycle. Pin 12 is connected to the wiper of a 10k pot. Looking at the output it seems the duty cycle is changing very slightly (1-2%) over the entire travel. Anything look out of place?


INCLUDE "modedefs.bas" 'Includes supoprt for PicBasic language

OSCCON = %01110001
PAUSE 100 ' start-up delay

'/////////////////////////
'// PIN configuration //
'/////////////////////////

'DEFINE CCP1_REG PORTC 'Define output port of pulses out
'DEFINE CCP1_BIT 3 'Define output port of pulses out

Define ADC_BITS 8 ' Set number of bits in result
Define ADC_CLOCK 3 ' Set clock source (3=rc)
Define ADC_SAMPLEUS 100 ' Set sampling time in uSec

CMCON0 = 7 ' Disable analog comparator
ANSEL = %00000010 ' set AN1 (RA1) as analog, others to digital
ADCON1 = %00000000 ' Left justified results in 8 bits
ADCON0 = %10000001 ' Configure and turn on A/D Module

TRISC = %00000000 ' Set PORTB to all output
TRISA = %11111111 ' Set PORTA to all input

'///////////////////////////////////////////////
'// Variable Declaration and initialization //
'///////////////////////////////////////////////

DutyCycle var byte 'Create adval to store result
LastDutyCycle var byte 'hold last time around

'//////////////////////////
'// Program starts here //
'//////////////////////////

Mainloop:
ADCON0.2 = 1 'Start Conversion

ADCIN 1, DutyCycle 'analog pin 1 (RA1) get the 8 bit result
pause 50

If dutycycle <> lastdutycycle then
lastdutycycle = dutycycle
HPWM 1,DutyCycle,6000
Endif

GOTO Mainloop
end

mister_e
- 17th November 2008, 17:01
You don't need to start the conversion, ADCIN handle it for you.

Usually you want to use Right Justified results.

Make sure you set your config fuses to use the internal OSC.

Not sure if HPWM work as expected on this PIC as it has this ECCP module... might worth a try here if you still have some problem using it.

astouffer
- 17th November 2008, 19:01
What I'm trying to do is rewrite this ASM code into Basic

http://hades.mech.northwestern.edu/wiki/index.php/PIC_PWM_Motor_Driver

It works as described but I need to add more options and conditions. The hardest part is getting this pwm part working.

mister_e
- 17th November 2008, 21:11
NO NEED FOR HPWM then


INIT_PWM
BANK0
MOVLW B'10001100' ;Dual-Output, Half-Bridge Mode
MOVWF CCP1CON ;P1A,P1C active-high, P1B,P1D active-high
MOVLW B'00000100' ;Timer2 enabled with prescale 1
MOVWF T2CON
BANK1
MOVLW 0xFF
MOVWF PR2 ;Set frequency to 19.53 kHz
BANK0
MOVLW B'01111111' ;50% duty cycle
MOVWF CCPR1L
RETURN


UPDATE_PWM
BANK0
MOVFW ADRESH ; copy the 8 MSbs to the CCPR1L register
MOVWF CCPR1L
BTFSC ADRESL,7 ; is ADC bit 1 set?
BCF CCP1CON,5 ; if not, clear the PWM bit 1
BSF CCP1CON,5 ; if so, set the PWM bit 1
BTFSC ADRESL,6 ; same thing, for bit 0
BCF CCP1CON,4
BSF CCP1CON,4

RETURN

Think about it a little bit ;)

astouffer
- 19th November 2008, 14:35
Got it working. Heres the code:

DEFINE FOSC 100
DEFINE ADC_BITS 10 ' Set number of bits in result
DEFINE ADC_CLOCK 3 ' Set clock source (3=rc)
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in uS
OSCCON = %01100001 '4 Mhz

TRISA = %11111111 ' Set PORTA to all input
ADCON1 = %10000010 ' Set PORTA analog and right justify
output portc.5

adcVar VAR word
dutyCycle var byte


main:
ADCIN 0, adcVar
dutyCycle = adcVar/256
hpwm 1,dutyCycle,6000
goto main

anonymouse
- 21st November 2008, 02:58
Got it working. Heres the code:

DEFINE FOSC 100
DEFINE ADC_BITS 10 ' Set number of bits in result
DEFINE ADC_CLOCK 3 ' Set clock source (3=rc)
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in uS
OSCCON = %01100001 '4 Mhz

TRISA = %11111111 ' Set PORTA to all input
ADCON1 = %10000010 ' Set PORTA analog and right justify
output portc.5

adcVar VAR word
dutyCycle var byte


main:
ADCIN 0, adcVar
dutyCycle = adcVar/256
hpwm 1,dutyCycle,6000
goto main

word filled by 10bit, result divided by 256?

astouffer
- 21st November 2008, 15:01
word filled by 10bit, result divided by 256?

Would it make more sense to sample 8 bits? Without dividing by 256 one full turn of the pot repeats 0-100% duty cycle many times. I admit being new to the world of programming and working with the internals of microprocessors.

mister_e
- 21st November 2008, 17:29
Well yes and no. Yes if you're using HPWM, no if you set the CCP register yourself as in the ASM code.

One thing is sure, 10 bits/256, will not give you a 8 bit results... if you divide it by 4... yes.