Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

PIC18F1220 A/D Converter not working

Status
Not open for further replies.

Bob Edge

Junior Member level 2
Joined
Apr 5, 2011
Messages
23
Helped
3
Reputation
6
Reaction score
2
Trophy points
1,283
Location
Holmfirth UK
Activity points
1,441
Hi,

I am trying to use the A/D converter on the PIC18F1220, but I just can't get it to work. I know the answer to this is RTFDS, but I have, & I just don't know what I'm doing wrong. I am using pic basic pro by the way.
I am setting the chip up in the following way:

define OSC 20
'channel 0 analog all others digital
TRISA = 255
ADCON0 = %00000001
ADCON1 = %11111110
ADCON2 = %10000010
define adc_bits 10
define adc_sampleus 50

There must be something I am doing wrong, or not doing at all.

Regards
Bob...
 

this is sample program for reading ADC using PBP, using 16F877, but you can adapt the program to fit to your microcontroller

Code:
' PICBASIC PRO program to display result of 
' 10-bit A/D conversion on LCD
'
' Connect analog input to channel-0 (RA0)

' Define LCD registers and bits
Define	LCD_DREG	PORTD
Define	LCD_DBIT	4
Define	LCD_RSREG	PORTE
Define	LCD_RSBIT	0
Define	LCD_EREG	PORTE
Define	LCD_EBIT	1

adval	var	word		' Create adval to store result


	TRISA = %11111111  	' Set PORTA to all input
	ADCON1 = %10000010 	' Set PORTA analog and RIGHT justify result
	ADCON0 = %11000001	' Configure and turn on A/D Module
	Pause 500       	' Wait .5 second


mainloop: ADCON0.2 = 1		' Start Conversion

notdone: Pause 5
	If ADCON0.2 = 1 Then notdone	' Wait for low on bit-2 of ADCON0, conversion finished

	adval.highbyte = ADRESH	' Move HIGH byte of result to adval
	adval.lowbyte = ADRESL	' Move LOW byte of result to adval

	Lcdout $fe, 1		' Clear screen
	Lcdout "Value: ", DEC adval	' Display the decimal value  

	Pause 100		' Wait .1 second

	Goto mainloop		' Do it forever
	End

anyway, post your complete code to trace the bug(s)

regards


erio
 

Hi,

Here is the code;
Code:
define OSC 20
  'channel 0 analog all others digital
TRISA = 255  
ADCON0 = %00000001
ADCON1 = %11111110
ADCON2 = %10000010
define adc_bits 10
define adc_sampleus 50

INCLUDE "DT_INTS-18.bas"     ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas"     ' Include if using PBP interrupts

badweld     var portb.3
prim        var portb.0
prim1       var portb.1
bren        var portb.2
thy3        var portb.6
thy2        var portb.5
thy1        var portb.4

input badweld
input prim
input bren
high thy3
high thy2
high thy1
input prim1

angletime   var word
temp        var word
period      var word
sixdeg      var word
multiplier  var word
decimal1    var word
decimal2    var word
adresult    var word
x           var byte 'for next loop variable
rot         var bit 'rotation 1 = forward 0 = reverse
zeroflag    var bit  'flag set to 1 at zero crossing


pause 1000    'give time for supply to settle
gosub rotation

'set up timer 
T0CON = %00000000 '1/2 prescale fosc/4 not running
TMR0H = 0  ;Clear registers
TMR0L = 0


ASM
INT_LIST  macro    ;  IntSource,  Label,   Type, ResetFlag?
        INT_Handler    INT0_INT,  _ZERO,   PBP,  yes
    endm
    INT_CREATE               ; Creates the interrupt processor
ENDASM

@   INT_ENABLE   INT0_INT     ; enable external (INT) interrupts

goto cycle
'-------Interrupt Service Routine------------------
ZERO:
@ bcf T0CON,TMR0ON ; Switch off timer
period.lowbyte = TMR0L  'Record Result
period.highbyte = TMR0H
@ clrf TMR0H  ; Reset registers to zero
@ clrf TMR0L
@ bsf T0CON,TMR0ON  ;Start timer
period = (period / 5) * 2  'scale period value in micro seconds
sixdeg = period / 6  'delay time for 60 degrees
multiplier = (period / 4) / 859
decimal1 = (period / 4) // 859 DIg 0
decimal2 = (period / 4) // 859 dig 1
zeroflag = 1    'Set zero crossing flag
@ INT_RETURN

weldingfwd:   'welding routine for forward phase rotation
if badweld = 1 then noweld
if prim = 0 then goto weldingfwd ' Make sure phase is really high
pauseus angletime       'pause for required delay time
low thy1            'fire first pair of thyristors
low thy2
pauseus 200
high thy1
high thy2
pauseus 200
low thy1
low thy2
pauseus 200
high thy1
high thy2
pauseus 200
low thy1
low thy2
pauseus 200
high thy1
high thy2
pauseus 200
low thy1
low thy2
pauseus 200
high thy1
high thy2
pauseus 200
low thy1
low thy2
pauseus 200
high thy1
high thy2
temp = sixdeg - 1800 ' take time firing thyristors from sixdeg time
pauseus temp      ' and pause for required time
low thy1        'then fire second pair
low thy3
pauseus 200
high thy1
high thy3
pauseus 200
low thy1
low thy3
pauseus 200
high thy1
high thy3
pauseus 200
low thy1
low thy3
pauseus 200
high thy1
high thy3
pauseus 200
low thy1
low thy3
pauseus 200
high thy1
high thy3
pauseus 200
low thy1
low thy3
pauseus 200
high thy1
high thy3
return

weldingrev:   'welding routine for reverse phase rotation   
if badweld = 1 then noweld
if prim = 0 then goto weldingfwd 'Make sure phase is really high
pauseus sixdeg  ' pause for 60 degrees
pauseus angletime       'pause for required delay time
low thy1            'fire first pair of thyristors
low thy3
pauseus 200
high thy1
high thy3
pauseus 200
low thy1
low thy3
pauseus 200
high thy1
high thy3
pauseus 200
low thy1
low thy3
pauseus 200
high thy1
high thy3
pauseus 200
low thy1
low thy3
pauseus 200
high thy1
high thy3
pauseus 200
low thy1
low thy3
pauseus 200
high thy1
high thy3
temp = sixdeg - 1800 'take time firing thyristors from 60 degree time
pauseus temp    'then pause to take to 60 degrees
low thy1        'then fire second pair
low thy2
pauseus 200
high thy1
high thy2
pauseus 200
low thy1
low thy2
pauseus 200
high thy1
high thy2
pauseus 200
low thy1
low thy2
pauseus 200
high thy1
high thy2
pauseus 200
low thy1
low thy2
pauseus 200
high thy1
high thy2
pauseus 200
low thy1
low thy2
pauseus 200
high thy1
high thy2
return

rotation:
let temp = 0
for x = 1 to 5 
jmp:               'Test phase rotation  5 times
    if prim = 1 then jmp   'wait for phase to go low
jmp5:    
    if prim = 0 then jmp5  'wait for phase to go high
jmp6:
    if prim = 1 then jmp6  'wait for phase to go low
    if prim1 = 1 then temp = temp + 1 'if phase 1 high then rotation is forward
                           'otherwise phases reversed
next x
if temp = 5 then fwd     'answer 5 = fwd rotation
if temp = 0 then reve    'answer 0 = rev rotation
goto rotation               'any other answer is incorrect, do it again                
reve:
let rot = 0
return
fwd:
let rot = 1
return



noweld:
if badweld = 1 then noweld
return

cycle:
    if zeroflag = 0 then cycle ' Wait for zero crossing flag
    zeroflag = 0               'Clear zero crossing flag
    adcin 0, adresult          'Do A/D conversion
    adcin 0, temp
    adresult = (adresult + temp) / 2
    angletime = adresult * multiplier
    temp = (adresult * decimal1) / 10
    angletime = angletime + temp
    temp = (adresult * decimal2) / 100
    angletime = angletime + temp ' We now have phase angle delay
    
    If (rot = 1) and (bren = 1) then gosub weldingfwd
    if (rot = 0) and (bren = 1) then gosub weldingrev
    
    goto cycle 
    
end

It is used to run a 3 phase welder, there are 3 chips the same one for each phase. The A/D is used to adjust the phase angle.

My problem is with setting up the various registers to get the A/D working.

Regards
Bob...
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top