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.

16F676 programming problem

Status
Not open for further replies.

swapan

Member
Hello friends,
I have taken up a project using 16F676 which will switch on a gadget to battery position when there is no AC Main supply. On resumption of AC Main supply the microcontroller will take some delay for stabilization of main supply then switch over to AC Main position. Also before switching over to ‘main’ position the microcontroller will check if the main supply is within permissible limit. When checking the stages one by one I face a problem in delay loop. Please see the code. When no delay is used the program works well. But on insertion of delay loop the BTFSC instruction has no effect and the relay operated from RA2 remains on even the RC5 bit is made ground. Please help.

Code:
config. bits. MCLR-OFF, PWRTE-OFF, CP-OFF, WDT-OFF, INTOSC

cblock 0x20
count1
count2
count3
endc

BSF STATUS, RP0
MOVLW 0X38
MOVWF TRISA
MOVLW 0X2C
MOVWF TRISC
MOVLW 0XC0
MOVWF ANSEL
MOVLW 0X87
MOVWF OPTION_REG
BCF STATUS, RP0
MOVLW 0X7
MOVWF CMCON
MOVLW 0X19
MOVWF ADCON0
MOVLW b'00100000'
MOVWF INTCON

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
BTFSS PORTC, 5 ; See if AC Main is present
GOTO AC_ON
INV_ON: MOVLW 0X4 ; If not, turn on Change Over Relay
MOVWF PORTA ; to inverter position.
CONT1: BTFSC PORTC,5
GOTO CONT1

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

AC_ON:
MOVLW D’10’ ; D
MOVWF COUNT3 ;
CT_2: MOVLW D’255’ ; E
MOVWF COUNT2 ;
CT_1: MOVLW D’255’ ; L
MOVWF COUNT1 ;
WAIT_1: BCF INTCON,2 ; A
DLY_1: BTFSC PORTC, 5 ;
GOTO INV_ON ; Y
BTFSS INTCON,2 ;
GOTO DLY_1 ;
DECFSZ COUNT1,1 ;
GOTO WAIT_1 ;
DECFSZ COUNT2,1 ;
GOTO CT_1 ;
DECFSZ COUNT3,1 ;
GOTO CT_2 ;
MOVLW b'00000000'
MOVWF PORTC ; Turn off change over relay to switch
over to Main position.
CONT2: BTFSC PORTC, 5 ; Check if AC Main is present or not.
GOTO INV_ON ; If present continue here otherwise
GOTO CONT2 turn on relay .

END
 
hi,:)
You are also using PORTC,5 in the Delay subr.!


Code:
config.	bits.	MCLR-OFF, PWRTE-OFF, CP-OFF, WDT-OFF, INTOSC

	cblock	0x20
count1
count2
count3
	endc

	bsf	STATUS, RP0
	movlw	0X38
	movwf	TRISA
	movlw	0X2C
	movwf	TRISC
	movlw	0XC0
	movwf	ANSEL
	movlw	0X87
	movwf	OPTION_REG
	bcf	STATUS, RP0
	movlw	0X7
	movwf	CMCON
	movlw	0X19
	movwf	ADCON0
	movlw	b'00100000'
	movwf	INTCON

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;  
	btfss	PORTC,5		; See if AC Main is present
	goto	AC_ON
INV_ON:	movlw	0X4		; If not, turn on Change Over Relay
	movwf	PORTA		; to inverter position.
CONT1:	btfsc	PORTC,5
	goto	CONT1

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;  

AC_ON:
	movlw	D’10’		; D
	movwf	COUNT3		;
CT_2:	movlw	D’255’		; E
	movwf	COUNT2		;
CT_1:	movlw	D’255’		; L
	movwf	COUNT1		;
WAIT_1:	bcf	INTCON,2	; A
DLY_1:	[COLOR="Blue"]btfsc	PORTC,5[/COLOR]		;
	goto	INV_ON		; Y
	btfss	INTCON,2	;
	goto	DLY_1		;
	decfsz	COUNT1,1	;
	goto	WAIT_1		;
	decfsz	COUNT2,1	;
	goto	CT_1		;
	decfsz	COUNT3,1	;
	goto	CT_2		;
	movlw	b'00000000'
	movwf	PORTC		; Turn off change over relay to switch
;over	to	Main position.
CONT2:	btfsc	PORTC,5		; Check if AC Main is present or not.
	goto	INV_ON		; If present continue here otherwise
	goto	CONT2 turn on relay .

	end
 
Last edited:
There's a few bugs...

First, after the delay, when you "turn off change over relay to switch over to Main position" near the bottom of the code, you're setting PORTC to all zeros. When you switched the relay on in INV_ON, you're setting PORTA. So, in the changed code below I changed the relay-off to PORTA.

Second of all, your delay routine is very long. The changes below give me a 3-4 second delay with a 20MHz clock (if you're using the internal oscillator it won't be more than 8 MHz). With your delay values the delay would be many hours or days!

When you post code on here, enclose it in [ CODE ] ... [ /CODE ] tags so the formatting isn't lost.

Code:
;config. bits. MCLR-OFF, PWRTE-OFF, CP-OFF, WDT-OFF, INTOSC
	list      p=16F676            ; list directive to define processor
	#include <p16F676.inc>        ; processor specific variable definitions

	__CONFIG   _MCLRE_OFF & _PWRTE_OFF & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT

	cblock 0x20
	COUNT1
	COUNT2
	COUNT3
	endc

	BSF STATUS, RP0
	MOVLW 0X38
	MOVWF TRISA
	MOVLW 0X2C
	MOVWF TRISC
	MOVLW 0XC0
	MOVWF ANSEL
	MOVLW 0X87
	MOVWF OPTION_REG
	BCF STATUS, RP0
	MOVLW 0X7
	MOVWF CMCON
	MOVLW 0X19
	MOVWF ADCON0
	MOVLW b'00100000'
	MOVWF INTCON

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;
	BTFSS PORTC, 5 ; See if AC Main is present
	GOTO AC_ON
INV_ON:
	MOVLW 0X4 ; If not, turn on Change Over Relay
	MOVWF PORTA ; to inverter position.
CONT1:
	BTFSC PORTC,5
	GOTO CONT1

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;

AC_ON:
	MOVLW D'1' ; D
	MOVWF COUNT3 ;
CT_2:
	MOVLW D'1' ; E
	MOVWF COUNT2 ;
CT_1:
	MOVLW D'255' ; L
	MOVWF COUNT1 ;
WAIT_1:
	BCF INTCON,2 ; A
DLY_1:
	BTFSC PORTC, 5 ;
	GOTO INV_ON ; Y
	BTFSS INTCON,2 ;
	GOTO DLY_1 ;
	DECFSZ COUNT1,1 ;
	GOTO WAIT_1 ;
	DECFSZ COUNT2,1 ;
	GOTO CT_1 ;
	DECFSZ COUNT3,1 ;
	GOTO CT_2 ;
	MOVLW b'00000000'
	MOVWF PORTA ; Turn off change over relay to switch over to Main position.
CONT2:
	BTFSC PORTC, 5 ; Check if AC Main is present or not.
	GOTO INV_ON ; If present continue here otherwise
	GOTO CONT2  ;turn on relay .

	END
 
There's a few bugs...

First, after the delay, when you "turn off change over relay to switch over to Main position" near the bottom of the code, you're setting PORTC to all zeros. When you switched the relay on in INV_ON, you're setting PORTA. So, in the changed code below I changed the relay-off to PORTA.

Second of all, your delay routine is very long. The changes below give me a 3-4 second delay with a 20MHz clock (if you're using the internal oscillator it won't be more than 8 MHz). With your delay values the delay would be many hours or days!

When you post code on here, enclose it in [ CODE ] ... [ /CODE ] tags so the formatting isn't lost.

Code:
;config. bits. MCLR-OFF, PWRTE-OFF, CP-OFF, WDT-OFF, INTOSC
	list      p=16F676            ; list directive to define processor
	#include <p16F676.inc>        ; processor specific variable definitions

	__CONFIG   _MCLRE_OFF & _PWRTE_OFF & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT

	cblock 0x20
	COUNT1
	COUNT2
	COUNT3
	endc

	BSF STATUS, RP0
	MOVLW 0X38
	MOVWF TRISA
	MOVLW 0X2C
	MOVWF TRISC
	MOVLW 0XC0
	MOVWF ANSEL
	MOVLW 0X87
	MOVWF OPTION_REG
	BCF STATUS, RP0
	MOVLW 0X7
	MOVWF CMCON
	MOVLW 0X19
	MOVWF ADCON0
	MOVLW b'00100000'
	MOVWF INTCON

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;
	BTFSS PORTC, 5 ; See if AC Main is present
	GOTO AC_ON
INV_ON:
	MOVLW 0X4 ; If not, turn on Change Over Relay
	MOVWF PORTA ; to inverter position.
CONT1:
	BTFSC PORTC,5
	GOTO CONT1

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;

AC_ON:
	MOVLW D'1' ; D
	MOVWF COUNT3 ;
CT_2:
	MOVLW D'1' ; E
	MOVWF COUNT2 ;
CT_1:
	MOVLW D'255' ; L
	MOVWF COUNT1 ;
WAIT_1:
	BCF INTCON,2 ; A
DLY_1:
	BTFSC PORTC, 5 ;
	GOTO INV_ON ; Y
	BTFSS INTCON,2 ;
	GOTO DLY_1 ;
	DECFSZ COUNT1,1 ;
	GOTO WAIT_1 ;
	DECFSZ COUNT2,1 ;
	GOTO CT_1 ;
	DECFSZ COUNT3,1 ;
	GOTO CT_2 ;
	MOVLW b'00000000'
	MOVWF PORTA ; Turn off change over relay to switch over to Main position.
CONT2:
	BTFSC PORTC, 5 ; Check if AC Main is present or not.
	GOTO INV_ON ; If present continue here otherwise
	GOTO CONT2  ;turn on relay .

	END

Many thanks Mr. kpatz. The program is working fine. By mistake the PORTC was made clear instead of PORTA. Your pointing out the mistake in delay time helped me a lot. I think instead of using 2 counts loaded with D'1' each , if one count is loaded with D'2' the delay time will be the same. Please confirm.
 
hi,:)
You are also using PORTC,5 in the Delay subr.!


Code:
config.	bits.	MCLR-OFF, PWRTE-OFF, CP-OFF, WDT-OFF, INTOSC

	cblock	0x20
count1
count2
count3
	endc

	bsf	STATUS, RP0
	movlw	0X38
	movwf	TRISA
	movlw	0X2C
	movwf	TRISC
	movlw	0XC0
	movwf	ANSEL
	movlw	0X87
	movwf	OPTION_REG
	bcf	STATUS, RP0
	movlw	0X7
	movwf	CMCON
	movlw	0X19
	movwf	ADCON0
	movlw	b'00100000'
	movwf	INTCON

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;  
	btfss	PORTC,5		; See if AC Main is present
	goto	AC_ON
INV_ON:	movlw	0X4		; If not, turn on Change Over Relay
	movwf	PORTA		; to inverter position.
CONT1:	btfsc	PORTC,5
	goto	CONT1

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;  

AC_ON:
	movlw	D’10’		; D
	movwf	COUNT3		;
CT_2:	movlw	D’255’		; E
	movwf	COUNT2		;
CT_1:	movlw	D’255’		; L
	movwf	COUNT1		;
WAIT_1:	bcf	INTCON,2	; A
DLY_1:	[COLOR="Blue"]btfsc	PORTC,5[/COLOR]		;
	goto	INV_ON		; Y
	btfss	INTCON,2	;
	goto	DLY_1		;
	decfsz	COUNT1,1	;
	goto	WAIT_1		;
	decfsz	COUNT2,1	;
	goto	CT_1		;
	decfsz	COUNT3,1	;
	goto	CT_2		;
	movlw	b'00000000'
	movwf	PORTC		; Turn off change over relay to switch
;over	to	Main position.
CONT2:	btfsc	PORTC,5		; Check if AC Main is present or not.
	goto	INV_ON		; If present continue here otherwise
	goto	CONT2 turn on relay .

	end

Thanks Mr. ericgibbs for your reply. Actually I wanted to monitor the presence or absence of AC main supply frequently. Hence the instruction btfsc PORTC,5 has been used. Since TMR0 is used to count internal instruction cycle, I think it will make no difference if the said instruction is used. Your kind remark is solicited.
 
I think instead of using 2 counts loaded with D'1' each , if one count is loaded with D'2' the delay time will be the same. Please confirm.
That should work fine. I just changed both to D'1' as a quick fix. You only need 2 delay counts (instead of 3) for the delay you need. You can use the stopwatch in the simulator in MPLAB to see how long your delay will be and then you can tweak the counts to get it the way you want. An even better way is to use one of the timers.
 
Last edited:
A better method.

Get the transformer ratio & measure the output voltage of the transformer. This will indirectly measure the supply voltage.

A transformer rating of 230/12V has the following results. (The values may have slightly higher than the shown below after converting to DC)

230V it will show you 12.0V
240V it will show you 12.56V
220V it will show you 11.51V

Measure this voltage with AD ( after scaling to 5V) & check the line voltage is within the limits.
 
That should work fine. I just changed both to D'1' as a quick fix. You only need 2 delay counts (instead of 3) for the delay you need. You can use the stopwatch in the simulator in MPLAB to see how long your delay will be and then you can tweak the counts to get it the way you want. An even better way is to use one of the timers.


Actuallu TMR0 has been used in the program by clearing bit 5 (T0CS) of POTION_REG. I could not got the idea of using one of the timers. Would you please throw some light?
 
A better method.

Get the transformer ratio & measure the output voltage of the transformer. This will indirectly measure the supply voltage.

A transformer rating of 230/12V has the following results. (The values may have slightly higher than the shown below after converting to DC)

230V it will show you 12.0V
240V it will show you 12.56V
220V it will show you 11.51V

Measure this voltage with AD ( after scaling to 5V) & check the line voltage is within the limits.

I am thankful to you Mr. Gayan Soyza. Whenever I post any tag you have given your valuable comment. Actually, I shall employ the same idea as you have opined. Before proceeding further I have tested one part i.e. monitoring the presence or absence of AC Main. If there is no AC Main the circuit will immediately switch over to inverter position. On resumption of AC Main the circuit will switch over to AC Main position after some delay. During the delay period the circuit will continue checking the AC Main. Program for this has been tested successfully. Now I shall concentrate on checking the input AC Main voltage level. Certainly your idea will be employed.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top