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.

Very dull request - coding error... :-(

Status
Not open for further replies.

barkerben

New Member
Yesterday various people were extremely helpful in helping a begginer get his head round assembly programming of a PIC. I think I have now managed to put some code together, but it does not quite perform how it should.

I have been using a P1C6F627

It is supposed to output 2 50Hz square waves slightly out of phase with each other, which is achieved by counting down interrupts with two counters, one of which was initialized to a different value from the other, so that they reach zero at different times. When either eaches zero, the relevant counter is reset and pins are toggled.

It is also supposed to output a 25Khz square wave with 50% duty cycle from the PWM capabilities of the PIC

The interrups seem to be called as required, and looking at the simulator, I think the counter variables are working, but the 50Hz output doesn't behave right, and the 25Khz output doesn't behave at all (Pin RB3 - the pwm output pin - stays at zero constantly)

The code is posted at:

www.srcf.ucam.org/~dbrb2/oscillator

If someone can see anything obviously wrong, I would be very grateful for any advice.

I apologise for this double posting, but I'm getting very annoyed with this PIC, and have been staring at the code all day! It seemed a good idea at the time though ...
 
It is supposed to output 2 50Hz square waves slightly out of phase with each other, which is achieved by counting down interrupts with two counters, one of which was initialized to a different value from the other, so that they reach zero at different times. When either eaches zero, the relevant counter is reset and pins are toggled.

How much phase shift are you trying to achieve? Yesterday, I posted code to introduce a small amount of dead time for two transistors in a totem pole arraignment. This turns OFF one transistor before the other transistor is turned ON to prevent a situation known as "shoot through". Since transistor switching times are less than a few usec, a couple of NOPs should do the trick.

Obviously, you are after a different objective considering the size of the phase shift. I would need more info to help you.

It is also supposed to output a 25Khz square wave with 50% duty cycle from the PWM capabilities of the PIC

Try this initialization code:

Code:
init	
	bcf 	STATUS,RP0 ; select bank zero
	bcf 	STATUS,RP1 ; select bank zero

	movlw	_PR2
	movwf	PR2

	movlw	_T2CON	
	movwf	T2CON

	movlw	_CCPR1L		   ;set these + the bits 4 and 5 of CCP1CON 
				   ;to give a value of 80 for 50% duty 
	movwf	CCPR1L

	bsf 	 CCP1CON, 2
	bsf  	 CCP1CON, 3 
	
	bcf 	 CCP1CON, 4 
	bcf  	 CCP1CON, 5 

	bsf 	STATUS,RP0 ; select bank one	

	clrf	TRISA	; PORTA = all outputs
	clrf	TRISB	; PORTB = all outputs
	bsf	PIE1,TMR2IE   

	bcf 	STATUS,RP0

	bsf	INTCON,PEIE

	clrf	PORTA	; PORTA = 0
	clrf	PORTB	; PORTB = 0
	bsf	PORTB,1		;set pin 1 high initially so that we get 
				;inverse outputs on pins 1 and 2

	bsf	INTCON,GIE


I apologise for this double posting, but I'm getting very annoyed with this PIC, and have been staring at the code all day! It seemed a good idea at the time though ...

Hey, everyone has to pay the "tuition fee" to learn how to code. You're lucky to produce almost usable code in only a few hours of trying.
 
delay

Hi Motion,

Ideally I'm looking for about a 60 degree delay on a 50Hz signal, so I worked out that would be about 3000 nops - the high side gate drivers already have shoot-through protection of a few nanoseconds.

This was the reson I went for using 2 seperate timers, although to be honest a signle square wave with no shift at all would be better than nothing - at least it would give me an output! I tried removing the code for the phase shift though, and the code worked just as not well as with it!

Cheers,

Ben
 
Try this code. There is a bug in the earlier code I posted. PR2 was in the wrong bank.

Code:
 LIST P=16F627
 #INCLUDE P16F627.INC

 __CONFIG _CP_OFF&_WDT_OFF&_BODEN_OFF&_PWRTE_ON

_T2CON     EQU b'00001100'
_PR2       EQU d'39'
_CCPR1L    EQU b'00010100'

   org     0x70

interrupt_count  RES   1

;Reset vector
   org	   0x00

   goto    init

;Interupt vector
   org	   0x04

;Interupt service Routine

isr
   decfsz  interrupt_count,F
   goto    phase_shift 		 ;count, but initialised at startup to a different value

   movlw   d'125'            ;reset interrupt_count variable to 125
   movwf   interrupt_count

   movlw   B'00000001'
   xorwf   PORTB,F        	 ; Toggle the bit0 pin

   goto    end_isr
phase_shift:
   movlw   d'83'
   subwf   interrupt_count,W ; check if (interrupt_count==d'83')
   btfss   STATUS,Z
   goto    end_isr

   rrf     PORTB,W      ; move bit0 to carry flag to preserve its state.
   rlf     PORTB,F      ; shift all bits including bit0.

end_isr:
   bcf     PIR1,TMR2IF  ; end isr, resetting interrupts
   retfie		        ; return to main program

init:
   clrf    STATUS
   clrf    PCLATH

   movlw   _T2CON
   movwf   T2CON

   movlw   _CCPR1L      ;set these + the bits 4 and 5 of CCP1CON 
   movwf   CCPR1L       ;to give a value of 80 for 50% duty 

   bsf     CCP1CON, 2
   bsf     CCP1CON, 3 
    
   bcf     CCP1CON, 4
   bcf     CCP1CON, 5 

   bsf     STATUS,RP0 ; select bank one    

   movlw   _PR2       ;
   movwf   PR2        ; MOVED this to here! 

   clrf    TRISA      ; PORTA = all outputs 
   clrf    TRISB      ; PORTB = all outputs

   bsf     PIE1,TMR2IE    

   bcf     STATUS,RP0 ; select bank zero    

   bsf     INTCON,PEIE 

   clrf    PORTA   ; PORTA = 0 
   clrf    PORTB

   bsf     INTCON,GIE

main:
   goto    main

   end
 
RES?

Hi Motion.

One question. What is the :

interrupt_count RES 1

line for. It used to be:

interrupt_count EQU d'125'

and I can't find a reference for the REF command...

Thanks for being so much help,

Ben
 
As in your code as well as mine interrupt_count is general purpose register. It can take a value of D'125' and is decremented down to 0. It must also have a meaningful location in the PICs memory. In bank0, general purpose registers can be located between 0x20-0x7F. To define its location you may use

Code:
interrupt_count equ 0x20

or

Code:
   org 0x20
interrupt_count res 1     ; reserve 1 memory location

This can be found in the MPASM users' guide.

I purposely assigned interrupt_count to 0x70 because this is mapped to all banks. This is not important now but could be a source of bugs if you start adding more code.

I noticed you confuse value for location when using general purpose registers. However, you distinguish them when using SFRs by the use of the underscore.
 
code modification

Hum....

Now none of the portB pins ever go high. I was looking through the code you posted, and was a bit confused by the phase shift section - to toggle pin 0 we use XOR, but I can't see how pin 1 is being toggled. Surely another XOR ought to work (and still preserver the status of pin0) as long as the mask only has a high bit at bit number 1...). I'm off to fiddle with the code.

Thanks,

Ben
 
I ran it through the MPLAB simulator and it works there.

RRF PORTB,W ; shifts bit0 to the carry flag without affecting PORTB itself.
RLF PORTB,F ; shifts the carry flag back to bit0 and at the same time shifting bit0 to bit1 position.
 
wow

That suggests my simulator may be screwy. I'm in the department now, so will give it a go on MPLab

I'll kick myself if the sim. was the problem

Cheers,

Ben
 
Thanks

Yu, ran it through MPlab and the PWM output worked. The 50Hz outputs still seem to be dead, but according to the bloke in electronics lab MPLAB cant simulate software interrupts so it should work when I get it on a real PIC tommorow.

Thanks for all your help,

Ben
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top