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.

Program issues

Status
Not open for further replies.

Ambient

New Member
First of all, thanks for the previous help with this program to all who took the time. I would not bother you again with the same program, but I am stumped.

The program runs fine, outputs work. Not sure about the A/D working though. I had originally set up AN3 to get the delay value that is decremented. It was not working apparently, so I just put in a value in the code for "Delay".

The problem is that no matter what I set the value at, the delay I actually see on the LEDs is always the same, and only changes with the prescalar on Timer0. I tried changing the RAM address of "Delay" to 0x0022 from 0x0020, did not help. I am at a loss here. The program runs exactly as it should otherwise. The thing that puzzles me is that Delay is being decremented somewhere, as the program will not continue to the next LED until is is 0. Unless it never had a value to begin with and is always 0?

https://h1.ripway.com/AmbientSix/Strobe.txt

EDIT: I am not sure how to make the text file open in the post, when I just copied it the format was awful.
 
Last edited:
List p=12f683
include P12F683.INC
__CONFIG _FCMEN_ON & _IESO_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_OFF & _INTOSCIO &_INTRC_OSC_NOCLKOUT
errorlevel -302 ; suppress message 302 from list file

w_temp EQU 0x7E ; variable used for context saving
status_temp EQU 0x7F ; variable used for context saving
Delay EQU 0x0022
Done EQU 0x0021
red EQU b'00000001'
wht EQU b'00000010'
blue EQU b'00000100'

;*****************
Code:
***********************************
	org 0x0000
	goto	INIT
	NOP
	NOP
	NOP
	
	org	0x0004
	GOTO	ISR

	org 0x0005	
INIT

	BSF	STATUS,RP0	;selects memory Bank 1
	
	MOVLW	b'01000001'
	MOVWF	OSCCON		;sets oscillator to 1MHz
	
	MOVLW	b'00000000'
	MOVWF	OPTION_REG	;enables Timer0, 1:4 PS (1.024ms/overflow)
	
	MOVLW	b'10100000'
	MOVWF	INTCON		;enable GIE, Timer0 interrupt
	
	MOVLW	b'00000111' 
	MOVWF	CMCON0		;disables comparator

	BCF	STATUS,RP0	;selects memory Bank 0
	CLRF	GPIO
	BSF	STATUS,RP0	;Bank 1 selected

	MOVLW	b'00011000'	;GP0,1,2,5 as outputs, GP3,4 as inputs.  
	MOVWF	TRISIO		;GP3,5 are for future add-ons.
	MOVLW	b'00010000'	;GP4 analog input enable, FOSC/2
	MOVWF	ANSEL
	
	MOVLW	b'10001101'	;right justify, VDD ref, AN0, ADON
	MOVWF	ADCON0
	BCF	STATUS,RP0	;Bank 0 selected
	
	MOVLW	h'0009'
	MOVWF	Delay

START
	CLRF	TMR0
;	BSF	ADCON0,ADON
;	BSF	ADCON0,GO	;get A/D data for "Delay" variable
;	BTFSC	ADCON0,GO
;	GOTO	$-1
;	MOVF	ADRESL,W
;	MOVWF	Delay
;	BCF	ADCON0,ADON	;disables A/D till next use.
	

;==================RED=========================
RedON
	BCF		Done,h'0000'
	MOVLW	red
	MOVWF	GPIO		;turns red LED on.
	BTFSC	Done,h'0000'	;tests for decrementing complete
	GOTO	WhtON		;executed when complete
	GOTO	$-2		  ;executed when not complete

;==================WHITE========================
WhtON
	BCF		Done,h'0000'
	MOVLW	wht
	MOVWF	GPIO		;turns white LED on.
	BTFSC	Done,h'0000'
	GOTO	BlueON
	GOTO	$-2

;==================BLUE=========================
BlueON
	BCF		Done,h'0000'
	MOVLW	blue
	MOVWF	GPIO		;turns blue LED on.
	BTFSC	Done,h'0000'
	GOTO	START
	GOTO	$-2
	
;*********************ISR************************
ISR
	movwf   w_temp      ; save off current W register contents
	movf	STATUS,w    ; move status register into W register
	movwf	status_temp	; save off contents of STATUS register
	BCF	  INTCON,T0IF
	DECFSZ	Delay,F
	GOTO	 CONTEXT      ;If not done decrementing, returns to current loop
	MOVLW	h'0001'
	MOVWF	Done		;done decrementing, places h'1' in "Done" register
	GOTO	CONTEXT
CONTEXT
	movf    status_temp,w   ;retrieve copy of STATUS register
	movwf	STATUS		; restore pre-isr STATUS register contents
	swapf   w_temp,f
	swapf   w_temp,w      ; restore pre-isr W register contents
	retfie                        ; return from interrupt
	END
 
Hi,
You have initially set the delay value to be '9'. In the ISR, you have:
Code:
DECFSZ Delay,F
GOTO CONTEXT ;If not done decrementing, returns to current loop
MOVLW h'0001'
MOVWF Done ;done decrementing, places h'1' in "Done" register
GOTO CONTEXT
When the content of 'delay' is decreased until 0, bit 0 of Done is set, at the same time, the delay time should be restored. Otherwise, the next round the program entering the ISR, it will decrement the delay from 0, but not from 9.
Code:
DECFSZ Delay,F
GOTO CONTEXT ;If not done decrementing, returns to current loop
MOVLW h'0001'
MOVWF Done ;done decrementing, places h'1' in "Done" register
[b]movlw 0x09    ;add these 2 lines
movwf Delay[/b]
GOTO CONTEXT
Besides, I suggest you to use rotate to switch the LED since you're turning on only one LED each time.
Good luck :)
 
Last edited:
Dumb mistake, again. It seems to work now. I will see if the A/D works for getting the value. Since the value will be changing I will just make two variables, Delay and DelayTemp, with the latter being the only decremented one.

Rotate is an great idea that I did not think about, but I may change the pattern in the future. I have to leave it as is if I decide on another pattern. There are other ways that I can reduce the code as well, but I do not need to, as the PIC has only the job of turning LED's on and off.

Thanks for your help.

Sean
 
A couple of comments on the ADC configuration:

Code:
MOVLW    b'00010000' ;all analog channels are disabled, try b'00011000' instead
MOVWF    ANSEL

;...

;switch to bank 1
MOVF    ADRESL,W ;the ADRESL register is in bank 1

But I think that you want to left-justify the result and read the eight most significant bits in the ADRESH resgiter (that is in bank 0).


Hope you'll have it working.
 
Last edited:
I corrected the a/d mistake of not enabling AN3. But my reasoning of using the lower result with a right justify was that I would get bits 0-7. I only need the value to go up to a max of 256, so 8 bits is enough. Do you recommend left justify and upper address because the value will not be zero in several pot positions?
 
Ambient said:
I corrected the a/d mistake of not enabling AN3. But my reasoning of using the lower result with a right justify was that I would get bits 0-7. I only need the value to go up to a max of 256, so 8 bits is enough. Do you recommend left justify and upper address because the value will not be zero in several pot positions?
Yes, you only need 8 bit-resolution, but you want to get the eight most significant bits of the result.

If you right-justify the result and read the least significant bits, what happens if the value is...
ADRESH = xxxxxx00 ADRESL = 00110011
or
ADRESH = xxxxxx01 ADRESL = 00110011

You wouldn't get unique results.


Left-justify the result and read the ADRESH register. You'll be still using 8 bits.
 
I tried the left justify and using the high bits, still didn't work. The problem was I was trying to write to ADCON0 and was still in Bank 1. Now it works!

Thanks everyone. I just hope I can learn quick enough to return the favor sometime.

Sean
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top