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.

Led Brightness Control with 4 buttons

Status
Not open for further replies.

Zegsy

New Member
I am trying to control the brightness of a single LED using 4 push button on the Velleman K8048 kit using PWM and TMR2 of a PIC16F627. Instead of controlling a single LED with the buttons the LED keep blinking at fast rate.
As I am new to PIC and ASM programming I am stuck and I need some help in making my code work.
Thanks.
 
I am trying to control the brightness of a single LED using 4 push button on the Velleman K8048 kit using PWM and TMR2 of a PIC16F627. Instead of controlling a single LED with the buttons the LED keep blinking at fast rate.
As I am new to PIC and ASM programming I am stuck and I need some help in making my code work.
Thanks.

hi,
Please post ALL your code.
To keep the code formatted, select it and then click the '#' symbol on the menu bar.
 
Hi,

Thanks for your reply. I have spend the all day on this forum jumping from one tutorial to the other and wow! I have learnt quite a lot.
I have modified my code and I was able to control the brightness of the led connected to RB3 on PORTB. However I need to also use TMR2 to generate an interrupt and output a high to RB5 on PORTB. Now I am a bit confuse wether to put the switch button scanning of my code in the ISR along with outputting a high to RB5 on PORTB.
My code so far is given below.
Thanks







Code:
		include 	P16F628.INC

		__CONFIG	_CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BODEN_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _XT_OSC

	cblock       0x20            ; Block of variables starts at address 20h
      w_temp                       
      status_temp                 
      d1,d2,d3
	endc


;	symbolic name for port connected to LEDs (PORTB)
LEDs	EQU		6
;	symbolic names for LEDs for bitwise operations
LD1		EQU		0
LD2		EQU		1
LD3		EQU		2
LD4		EQU		3
LD5		EQU		4
LD6		EQU		5
;	symbolic name for port connected to switches (PORTA)
SWs		EQU		5
;	symbolic names for Switches for bitwise operations
SW1		EQU		0
SW2		EQU		1
SW3		EQU		2
SW4		EQU		3


			org 0x0000
			goto Main

			org 0x0004 
			goto ISR





;************************************************************************************

	ISR		

; save STATUS and W register before processing interrupt
	movwf	w_temp
	swapf	STATUS,w
	movwf	status_temp

	
; restore the working and status register
	movf	status_temp,w
	movwf	STATUS
	swapf	w_temp,f
	swapf	w_temp,w

	retfie


; subroutines
;************************************************************************************
delay	movlw	0x2d			;around 0.1 second or a bit less
	movwf	d1
	movlw	0xe7
	movwf	d2
	movlw	0x01
	movwf	d3
delay_0	decfsz	d1, f
	goto	dd2
	decfsz	d2, f
dd2	goto	dd3
	decfsz	d3, f
dd3	goto	delay_0
	return

SW1_Pressed	movlw	D'4'
			movwf	CCPR1L
			call	delay
			return

SW2_Pressed	movlw	D'16'
			movwf	CCPR1L
			call	delay
			return

SW3_Pressed	movlw	D'64'
			movwf	CCPR1L
			call	delay
			return

SW4_Pressed	movlw	D'255'
			movwf	CCPR1L
			call	delay
			return

;******************************************************
; end of subroutines


Main	nop
		

	movlw	0x07			;turn comparators off
	movwf	CMCON
	bsf 	STATUS,RP0		;bank 1
	movlw	0x00			;all pins outputs
	movwf	TRISA
	movwf	TRISB
	movlw	0xff			;set period
	movwf	PR2
	bcf 	STATUS,RP0		;bank 0

	movlw	0x80			;set duty cycle
	movwf	CCPR1L
	movlw	0x04			;set timer2 prescale and enable it
	movwf	T2CON
	movlw	0x0c			;set bottom 2 pwm bits and enable pwm
	movwf	CCP1CON
	BSF 	T2CON, TMR2ON 		;Timer2 starts to increment
	call	delay



MLoop	nop	

	clrf	PORTB
	btfsc	SWs,SW1
	call	SW1_Pressed
	btfsc	SWs,SW2
	call	SW2_Pressed
	btfsc	SWs,SW3
	call	SW3_Pressed
	btfsc	SWs,SW4
	call	SW4_Pressed
	
	goto	MLoop

;******************************************************		
		
end
 
Last edited by a moderator:
Hello,

Can anyone please help me out. I dont seem to be able to generate an interrupt with TMR2. I have posted my code in the forum, its use to control the brightness of LED, but I need to be able to generate a high to RB5 when TMR2 interrupt occurs.
The PWM is working but the interrupt seems not to be.
Please your help is great appreciated... anyone!
 
Hello,

Can anyone please help me out. I dont seem to be able to generate an interrupt with TMR2. I have posted my code in the forum, its use to control the brightness of LED, but I need to be able to generate a high to RB5 when TMR2 interrupt occurs.
The PWM is working but the interrupt seems not to be.
Please your help is great appreciated... anyone!

hi,
In your program TIMER2 is allocated to the PWM function, IIUC only the Timer2 postscaler is free.
Why not use Timer0 or Timer1 for the ISR.???
 
TMR2 Interrupt

hi,
In your program TIMER2 is allocated to the PWM function, IIUC only the Timer2 postscaler is free.
Why not use Timer0 or Timer1 for the ISR.???

Yeah! I thought as much that since I was using TMR2 for the PWM it might not be able to generate interrupt to control an output.

I tried writing another code for the TMR2 alone to generate an output at the TMR2 interrupt, but I am not getting an interrupt. Please help look at my code, What am I getting wrong?

Code:
;*************************************************************************************
ISR	
	 movwf       w_temp          ; Save register W
       
       movf        STATUS          ; Save register STATUS
       movwf       status_temp
       
       movf        PCLATH          ; Save register PCLATH
       movwf       pclath_temp
       
       banksel     PORTB           ; Selects bank containing PORTB
       clrf	PORTB		; or LEDs instead of PORTB
		movlw	B'00100000'
		movwf	PORTB		; or LEDs instead of PORTB
		movlw	D'5'		
		call	DelWds		; hold for 0.5 s
	incf        PORTB           ; Increments PORTB register by 1
       banksel     PR2             ; Selects bank containing PR2
       decf        PR2             ; PR2 is decremented by 1
       movf        pclath_temp,w   ; PCLATH is given its original state
       movwf       PCLATH
       movf        status_temp,w   ; STATUS is given its original state
       movwf       STATUS
       swapf       w_temp,f        ; W is given its original state
       swapf       w_temp,w
       
       banksel     PIR1            ; Selects bank containing PIR1
       bcf         PIR1,TMR2IF     ; Clears interrupt flag TMR2IF
       
       bsf         INTCON,GIE      ; Global interrupt enabled
      
       retfie                      ; Return from interrupt routine
	


retfie
;************************************************************************************


;******************************************************



Main	
         nop
		

	banksel     TRISB           ; Selects bank containing register TRISB
       clrf        TRISB           ; All port B pins are configured as outputs
       	movlw	B'00100000'
	movwf	PORTB		; or LEDs instead of PORTB
	movlw	D'5'		
	call	DelWds		; hold for 0.5 s
	clrf        PR2                            
       
       banksel     T2CON           ; Selects bank containing register T2CON
       movlw       H'FF'           ; Sets all control register bits
       movwf       T2CON           ; prescaler=1:16, postscaler=1:16 TMR2=ON
       clrf        PORTB
       
       banksel     PIE1            ; Selects bank containing register PIE1
       bsf         PIE1,TMR2IE     ; TMR2 interrupt enabled
       bsf         INTCON,PEIE      ; Peripheral modules interrupt enabled
                                   ; Timer TMR2 belongs to peripheral modules
       bsf         INTCON,GIE      ; Global interrupt enabled
loop
       goto        loop            ; Remain here
 
Last edited by a moderator:
hi Zegsy,
I'll look at your latest code in my sim, I assume the program header is the same as the first program.?

As you can see Nigel has again reposted your code in order restore the formatting.

When you post code; after you have pasted the code into the reply window, select the whole code [turns blue] and then click the '#' [hash] symbol located in the top menu bar.

EDIT:
Looked at your program, lots of missing items.! please post the full program.
 
Last edited:
With the values you are using your PWM period will be 1220Hz and your interrupt should happen at 1/16th of this rate (about 75Hz). In your interrupt routine you call a 0.5 second delay which is not advisable, interrupt code should be as short as practicable.

Apart from that I can't see any reason it shouldn't work. Somethings you may want to change so they don't cause problems later are,
Move your temp variables into the common area at 0x70.
Move the bcf PIR,TMR2IF before the context restore code.
Remove the goto ISR and put your ISR code at location 4.

Mike.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top