Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

yet another PIC12F683 ADC problem

Status
Not open for further replies.

madderscience

New Member
Hi all-

I'm relatively new to PIC processors, and like some previous posters I am building what is essentially a voltmeter (eventually to become part of a data acquisition system for my electric car).

However the problem I seem to be having doesn't match what is described anywhere else I can find on this forum, so I'll post this and let you guys tell me what presumably dumb thing I am doing.

My problem is that after finishing an ADC sample cycle, I cannot get ADRESL to read back anything other than Zero. However I am getting sane values from ADRESH. If I left justify the adc results, I get 8 bits of good data from ADRESH, but always zero from ADRESL. If I right justify the results, I get two bits of good data from ADRESH, but ADRESL still reads zero. Yes, I am using bank bits. I am transmitting my results off of the PIC via rs232 on an unused pin, so I can see what I am getting on a remote computer terminal.

Here are the (relevant) portions of my code: (comments may be truncated)

one-time-setup:

InitIO BANKSEL GPIO ; select bank containing GPIO (bank 0)
clrf GPIO ; clear contents of GPIO
clrf CMCON0 ; CMCON0 set GP0, GP1 to analog input, GP2 to I/O and
BANKSEL ANSEL ; select bank containing ANSEL register (bank 1)
movlw 0x33 ; set up ADC for dedicated clock and input on AN0
movwf ANSEL ; and write to ANSEL register.
movlw 0x03 ; set up tristate control buffer for input on GP0 and GP1
movwf TRISIO ; GP5,4,2 all outputs. GP3 is always a
BANKSEL GPIO ; go back to bank 0
return

sample routine, called periodically:

(ADCON0 is set to 0x0 before calling (Vdd reference, left justify, channel zero), the "Delay" routine sets up a variable duration watchdog timer wake-from-sleep based on the contents of W, and is known working)

Sample bsf ADCON0, 0 ; turn on adc.
movlw 0x0
call Delay ; wait 1/8s (way longer) than acquisition tim

bsf ADCON0, 1 ; GO!

btfsc ADCON0, 1 ; are we really done???
goto $-1

; store the result in program memory.
movfw ADRESH
movwf sampleH ; <<<< WORKS FINE, GETTING SANE DATA
BANKSEL ADRESL
movfw ADRESL
movwf sampleL ; <<<< ALWAYS ZERO!! GRRR!!!!!!

BANKSEL PIR1

bcf ADCON0, 0 ; turn off adc. isr should have done this, but
return ; and done,

I can do without the two least significant bits, but I'd like to have them if possible.

Thanks to all.

Brian
 
If you read the 'sticky' at the top of this forum, it refers you to my tutorials, one of which explains simply and clearly how to use the analogue inputs.
 
I suspect Pommie has found the problem unless sampleL and sampleH are in the 'shared' 70..7Fh area.
 
Last edited:
problem identified

Pommie said:
What bank is sampleL in?

Mike.

Thats it!

I knew I was doing /something/ stupid. SampleL is in the low bank random acess area, so I am writing what comes out of ADRESL into a wrong and/or unimplemented register.

Thanks to all!

Brian
 
Hi, Everybody!

I read this forum and rejoiced at it - I would like to make a circuit, wich can control ny modell engine's direction and speed. Before I made a same circuit, with 16F716, but it has no internal oscillator, and DIP18, 12F683 has INTOSC? and DIP8 -> smaller.

I can not start ADC. With Brian's routines neither.... Please help me. After message I fitted int he asm, which I wrote - PWM works, but ADC not. When I program PIC and switch on power, the GP2 output works for 1 minute, and off...

fejesg HU

;************************************************************
; Processor: PIC12F683 at 4 MHz using intosc
;************************************************************
LIST P=12F683, R=DEC
#include "P12F683.INC"
;
__config _FCMEN_OFF & _IESO_OFF & _PWRTE_OFF & _BOD_OFF & _MCLRE_OFF & _WDT_OFF & _CP_OFF & _CPD_OFF & _INTOSCIO
;
CBLOCK 0x20
Loop1, Loop2, adfelso, adalso
ENDC
;
ORG 0x00
goto main

InitIO
BANKSEL GPIO ; select bank containing GPIO (bank 0)
clrf GPIO ; clear contents of GPIO
clrf CMCON0 ; CMCON0 set GP0, GP1 to analog input, GP2 to I/O and
CLRF TMR2 ;
CLRF T2CON ;
CLRF CCPR1L ;
movlw b'00001100' ; PWM on
movwf CCP1CON
BANKSEL ANSEL ; select bank containing ANSEL register (bank 1)
movlw 0x33 ; set up ADC for dedicated clock and input on AN0
movwf ANSEL ; and write to ANSEL register.
movlw 0x03 ; set up tristate control buffer for input on GP0 and GP1
movwf TRISIO ; GP5,4,2 all outputs. GP3 is always a
BANKSEL GPIO ; go back to bank 0
return

delay ; ez 250-250-nél kb 0,5 sec idő, 1/8 sec-hez negyede kell, kb. 60-250
MOVLW 60
MOVWF Loop1
Outer MOVLW 250
MOVWF Loop2
Inner NOP
NOP
DECFSZ Loop2,F
GOTO Inner ; Inner loop = 5 usec.
DECFSZ Loop1,F
GOTO Outer
RETURN

;sample routine, called periodically:
;(ADCON0 is set to 0x0 before calling (Vdd reference, left justify, channel zero), the "Delay" routine
;sets up a variable duration watchdog timer wake*from*sleep based on the contents of W, and is
;known working)

Sample
bsf ADCON0, 0 ; turn on adc.
movlw 0x0
call delay ; wait 1/8s (way longer) than acquisition tim
bsf ADCON0, 1 ; GO!
btfsc ADCON0, 1 ; are we really done???
goto $-1
; store the result in program memory.
movfw ADRESH
movwf adfelso ; <<<< WORKS FINE, GETTING SANE DATA
BANKSEL ADRESL
movfw ADRESL
BCF STATUS,RP0 ; Bank0
movwf adalso ; <<<< ALWAYS ZERO!! GRRR!!!!!!
BANKSEL PIR1
bcf ADCON0, 0 ; turn off adc. isr should have done this, but
return

pwm_init
;
bsf STATUS, RP0 ; bank1
movlw b'11111111'
movwf PR2 ; berakja a periódusidő értékét
clrf INTCON ; minden megszakítást tilt
clrf PIE1 ; minden megszakítást tilt
bcf STATUS, RP0 ; bank0
movlw b'00000101' ; 1:4 előosztó, T2ON=1.
movwf T2CON
clrf CCPR1L
movlw b'10001100' ; PWM bekapcsolva, aktív L kitöltési felső 2 bitje 00
movwf CCP1CON ; beírni
movlw b'00001111' ; alapértékek: 11000111, 10000001, 00001111, 11111111
movwf CCPR1L ; berak egy alapértéket
;
return

main

call InitIO

call pwm_init

here

nop
nop
nop
call Sample

BCF STATUS,RP0 ; Bank0

movfw adalso
movwf CCP1CON
nop
nop

goto here

end
 
Are you using macro?

What is "movfw" in your code? You should use "movf XXX,w" instead.
 
Hi, Chung (Lao?).

In the starting of experimentation I used movf REGISTER and movwf THERE. I don't know, why not works routine???

Inside the PDF documentation I read, that necessary delay time (TAD) 3..5 mikrosec (with 4 MHz internal clock 3..5 pcs nop-s...). If I use longer delay, it is not works too..

Please help me; my question:
- are my register settings good? I read in PDF that CMCON0 & TRISIO & ANSEL & ADCON0 work together...

If You can, please send me a short WORKABLE asm program, with wich I can start my ADC; after it, I can modify program, to handle PWM.

fejesg
 
You don't appear to be setting ADCON0 (except bits 0 and 1) and so it may be reading the wrong pin and GP2 should be set to input for the PWM module to work correctly. You may also have to turn off the comparators (CMCON0=7).

Mike.
 
hi,
I have used a Code tidy to reformat your code. [Pommie's]
When you post code, select all the code and then click the '#' sign in the menu bar, it keeps the formatting.:) also others can read it more easily.
I'll look thru your program.

Code:
;************************************************* ***********  
; Processor: PIC12F683 at 4 MHz using intosc  
;************************************************* ***********  
	list	P=12F683, R=DEC
#include "P12F683.INC" 
;
	__config _FCMEN_OFF & _IESO_OFF & _PWRTE_OFF & _BOD_OFF & _MCLRE_OFF & _WDT_OFF & _CP_OFF & _CPD_OFF & _INTOSCIO
;
	cblock	0x20
Loop1,	Loop2,	adfelso, adalso
	endc
;
	org	0x00
	goto	main

InitIO
	banksel	GPIO		; select bank containing GPIO (bank 0)
	clrf	GPIO		; clear contents of GPIO
	clrf	CMCON0		; CMCON0 set GP0, GP1 to analog input, GP2 to I/O and
	clrf	TMR2		;
	clrf	T2CON		;
	clrf	CCPR1L		;
	movlw	b'00001100'	; PWM on
	movwf	CCP1CON
	banksel	ANSEL		; select bank containing ANSEL register (bank 1)
	movlw	0x33		; set up ADC for dedicated clock and input on AN0
	movwf	ANSEL		; and write to ANSEL register.
	movlw	0x03		; set up tristate control buffer for input on GP0 and GP1
	movwf	TRISIO		; GP5,4,2 all outputs. GP3 is always a
	banksel	GPIO		; go back to bank 0
	return

delay				; ez 250-250-nél kb 0,5 sec ido", 1/8 sec-hez negyede kell, kb. 60-250 
	movlw	60
	movwf	Loop1
Outer	movlw	250
	movwf	Loop2
Inner	nop
	nop
	decfsz	Loop2,F
	goto	Inner		; Inner loop = 5 usec.
	decfsz	Loop1,F
	goto	Outer
	return

;sample routine, called periodically:  
;(ADCON0 is set to 0x0 before calling (Vdd reference, left justify, channel zero), the "Delay" routine  
;sets up a variable duration watchdog timer wake*from*sleep based on the contents of W, and is  
;known working)  

Sample
	bsf	ADCON0,0	; turn on adc.
	movlw	0x0
	call	delay		; wait 1/8s (way longer) than acquisition tim
	bsf	ADCON0,1	; GO!
	btfsc	ADCON0,1	; are we really done???
	goto	$-1
; store the result in program memory.  
	movfw	ADRESH
	movwf	adfelso		; <<<< WORKS FINE, GETTING SANE DATA
	banksel	ADRESL
	movfw	ADRESL
	bcf	STATUS,RP0	; Bank0
	movwf	adalso		; <<<< ALWAYS ZERO!! GRRR!!!!!!
	banksel	PIR1
	bcf	ADCON0,0	; turn off adc. isr should have done this, but
	return

pwm_init 
;
	bsf	STATUS,RP0	; bank1
	movlw	b'11111111'
	movwf	PR2		; berakja a periódusido" értékét
	clrf	INTCON		; minden megszakítást tilt
	clrf	PIE1		; minden megszakítást tilt
	bcf	STATUS,RP0	; bank0
	movlw	b'00000101'	; 1:4 elo"osztó, T2ON=1.
	movwf	T2CON
	clrf	CCPR1L
	movlw	b'10001100'	; PWM bekapcsolva, aktív L kitöltési felso" 2 bitje 00
	movwf	CCP1CON		; beírni
	movlw	b'00001111'	; alapértékek: 11000111, 10000001, 00001111, 11111111
	movwf	CCPR1L		; berak egy alapértéket
;
	return

main

	call	InitIO

	call	pwm_init

here

	nop
	nop
	nop
	call	Sample

	bcf	STATUS,RP0	; Bank0

	movfw	adalso
	movwf	CCP1CON
	nop
	nop

	goto	here

	end
 
Hi, Mike.

At first, I setted up CMCON0 b'00000111', how You wrote; but the program not worked... I changed settings, after I read message of Chung.

fejesg
 
Hi, Eric.

Thank You the repair of my message; at the next time I shall do in this way. I wait the result of Your checking of my program.

fejesg
 
Hi, Eric.

Thank You the repair of my message; at the next time I shall do in this way. I wait the result of Your checking of my program.

fejesg

hi,
Your original code reads the ADC OK and loads the two registers OK [adfelso, adalso], this is using my Oshonsoft simulator.
Why do think its not loading these two registers.?
Your program comments call the locations 'program memory' its not.

BTW: the movfw is recognised by the assembler OK.

I'll look at the program later today.
 
Hi, Eric.

I use Mplab 8.15; it is errorous, because the base setting inside are 20 MHz IntOsc (but values of osccon are right...); I can not try program with the assembler correctly.

I made (on the last weekend) a test circuit;
at first:I connected a LED (& a speaker, with BC301) to GP2, switched on PWM, setted up a "basement" CCPR1L value (speaker beeped!), and I wrote in program that the end of conversion value of ADRESL shall write in CCPR1L. IT NOT WORKED.

at second:I connected 4 LED-s to GP1-GP2-GP4-GP5, conncted a potmeter (+5v-out-gnd) to GP0 (as analog input), and wrote in program, that the result of conversion (ADRESL) shall copy to GPIO, and let appear result in I/O-s, light LED-s. IT NOT WORKED.

Huuu. I dont't know why not works AD of 12F683; when I made a test circuit with 16F716, that's ADC has worked well.

fejesg
 
BTW: the movfw is recognised by the assembler OK.

Eric thanks for pointing that out. I have never used it before and it is not one from the standard 14-bit instruction set.

I then looked it up in Assembler Help file and yes it is defined as an "Pseudo-Instruction" which is accepted by the assembler.

However, Microchip also stated "Use of these pseudo-instructions is not recommended for new designs. These are documented mainly for historical purposes.".
 
So. Dear Everybody.

Does know anybody well MPLAB 8.15? Can I use some procedures, to simulate analog input of PIC? I have no Oshorn Simulator (because it is not free software).

fejesg
 
So. Dear Everybody.

Does know anybody well MPLAB 8.15? Can I use some procedures, to simulate analog input of PIC? I have no Oshorn Simulator (because it is not free software).

fejesg

hi,
You can get Oshonsoft on a 30 day free trial.
 
Hi, Eric.

I use Mplab 8.15; it is errorous, because the base setting inside are 20 MHz IntOsc (but values of osccon are right...); I can not try program with the assembler correctly.

fejesg

To set the MPLAB sim clock do this: Click 'debugger' on the menu bar, click 'settings' on the drop down menu, set the sim clock to 4MHz.

Your ADC reading code works OK on the Oshonsoft sim at 4MHZ.
 
ThanX Eric!

I modified clock frequency! But the Output (Mplab SIM writes "ADC-W0008: No stimulus file attached to ADRESL for A/D.". How can I simulate analogue input?

fejesg
 
Status
Not open for further replies.

Latest threads

Back
Top