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.

Working with Shift Registers and a PIC help

Status
Not open for further replies.
srry for the double post but like this ? Im still not sure how to access the carry flag im not sure the location of it ? and would I be able to do the same thing with a 12 output shift register using 12 digits instead of 8 ? like so '000000000000' then do the same thing with RLF to move it into the carry flag like the same thing with the 8 output shift

Code:
                    C 76543210
                    0 00000001
            RLF     0 00000010
            RLF     0 00000100
            RLF     0 00001000
            RLF     0 00010000
            RLF     0 00100000
            RLF     0 01000000
            RLF     0 10000000
            RLF     1 00000000
            RLF     0 00000001
 
Last edited:
We have the whole thing figured out other then the engine now. Looking at one that was made before by someone else who was helping me, but we were not using shift registers at the time.
I was thinking about it today. You're right - it probably can be done without interrupts. It'll be tight for code space, but you can probably squeeze it in.

Also since I'm going to be using all the I/0 pins on the PIC what do I need to do in circuit programming?
What I do is just put in SPDT switches for the PGD, PGC and MCLR lines, like in **broken link removed**. You could do it with jumpers too, but they're not nearly so convenient.

I'm not sure what pins the 509 uses to program and what I need to do to separate the PIC from the rest of the curcuit as well. When I am programming the PIC I know it needs to be seperated from everything so that it doesn't fail in programming.
Look at the datasheet in section 7.12. GP0 is PGD, GP1 is PGC and GP3 is MCLR. Isolate them as noted above when programming.

Now how do I write the carry flag im not sure what location its in?
Here's another thing you must learn. The STATUS register is covered in section 4.4 of the datasheet (page 20). You must know this register by heart. It gets used constantly.

Use a BTFSC or BTFSS to test the carry bit and either write one value if no branch or if there is a branch to write the other value to the data pin.

Basically your telling me to first set what LED's I want on by something like this b'10100100'. Then I would use RLF to move the first bit into the carry flag and write that to the data pin.
Don't write that exact bit, but say if that bit is 1, the test takes execution to a line that puts a 1 on the data pin. If that bit is 0 it goes to another line that puts a 0 on the data pin. Then it goes to code that blips the clock and repeats the whole thing.

Then I would then use RLF again and that would take the bit in the carry flag and move it to the end so it would then be '01001001' right? and put the new bit in then I would write that to the shift etc etc?
Sort of, ya. :p
 
Im still not sure how to access the carry flag im not sure the location of it?
See previous post regarding status register.

Would I be able to do the same thing with a 12 output shift register using 12 digits instead of 8 ? like so '000000000000' then do the same thing with RLF to move it into the carry flag like the same thing with the 8 output shift
Not exactly like that because the PIC you're using is an 8-bit model. You would have to use one byte and half of another and write code to use them both in the proper order.

like this?
Code:
                    C 76543210
                    0 00000001
            RLF     0 00000010
            RLF     0 00000100
            RLF     0 00001000
            RLF     0 00010000
            RLF     0 00100000
            RLF     0 01000000
            RLF     0 10000000
            RLF     1 00000000
            RLF     0 00000001
Yes. You would stop before that last line. Do a loop count of 8, for 8 bits.
 
Last edited:
Basically the whole thing would look something like this right ? but im having some build errors all post them under the code

Code:
;******** Main Code

start
		movlw   b'001000'       ; Configure only GP3 as a input
        tris    GPIO
        
loop

		movlw	b'00100001'
		movwf	Display
		call	Engine
		
		goto	loop


;******** Subroutines

Engine
		RLF		Display
		call	test_clock
		RLF		Display
		call	test_clock
		RLF		Display
		call	test_clock
		RLF		Display
		call	test_clock
		RLF		Display
		call	test_clock
		RLF		Display
		call	test_clock
		RLF		Display
		call	test_clock
		RLF		Display
		call	test_clock
		movlw	b'000100'
		movwf	GPIO
		retlw	0
		
test_clock
		BTFSC 03h,b
		movlw	b'000000'		; Moves 0 on Data pin
		movwf	GPIO
		movlw	b'000010'		; Clocks it
		movwf	GPIO
		movlw	b'000000'
		movwf	GPIO
		BTFSC 03h,b
		movlw	b'000001'		; Moves 1 on Data pin
		movwf	GPIO
		movlw	b'000010'		; Clocks it
		movwf	GPIO
		movlw	b'000000'
		movwf	GPIO
		retlw	0		
	END					; End of Program !

Code:
----------------------------------------------------------------------
Debug build of project `C:\PIC12F509\Programs\LED_Matrix.disposable_mcp' started.
Preprocessor symbol `__DEBUG' is defined.
Sat Sep 06 13:45:30 2008
----------------------------------------------------------------------
Clean: Deleting intermediary and output files.
Clean: Done.
Executing: "C:\Program Files\Microchip\MPASM Suite\MPASMWIN.exe" /q /p12F509 "LED_Matrix.ASM" /l"LED_Matrix.lst" /e"LED_Matrix.err" /d__DEBUG=1
Error[149]   C:\PIC12F509\PROGRAMS\LED_MATRIX.ASM 57 : Directive only allowed when generating an object file
Error[149]   C:\PIC12F509\PROGRAMS\LED_MATRIX.ASM 62 : Directive only allowed when generating an object file
Message[305] C:\PIC12F509\PROGRAMS\LED_MATRIX.ASM 85 : Using default destination of 1 (file).
Message[305] C:\PIC12F509\PROGRAMS\LED_MATRIX.ASM 87 : Using default destination of 1 (file).
Message[305] C:\PIC12F509\PROGRAMS\LED_MATRIX.ASM 89 : Using default destination of 1 (file).
Message[305] C:\PIC12F509\PROGRAMS\LED_MATRIX.ASM 91 : Using default destination of 1 (file).
Message[305] C:\PIC12F509\PROGRAMS\LED_MATRIX.ASM 93 : Using default destination of 1 (file).
Message[305] C:\PIC12F509\PROGRAMS\LED_MATRIX.ASM 95 : Using default destination of 1 (file).
Message[305] C:\PIC12F509\PROGRAMS\LED_MATRIX.ASM 97 : Using default destination of 1 (file).
Message[305] C:\PIC12F509\PROGRAMS\LED_MATRIX.ASM 99 : Using default destination of 1 (file).
Error[113]   C:\PIC12F509\PROGRAMS\LED_MATRIX.ASM 106 : Symbol not previously defined (b)
Error[113]   C:\PIC12F509\PROGRAMS\LED_MATRIX.ASM 113 : Symbol not previously defined (b)
Halting build on first failure as requested.
----------------------------------------------------------------------
Debug build of project `C:\PIC12F509\Programs\LED_Matrix.disposable_mcp' failed.
Preprocessor symbol `__DEBUG' is defined.
Sat Sep 06 13:45:31 2008
----------------------------------------------------------------------
 
One issue that I have not seen mentioned is the memory addressing limitations of baseline PICs of which the 12F509 is a member. These PICs have the instruction space divided into 512 word pages. Only the first 256 words of a page can be used as the destination of a subroutine call or instruction that modifies PCL. In addition, care must be taken that the page select bits in the STATUS register are set for a GOTO, CALL, or instruction that modifies the PCL. These characteristics can severely limit table lookups used for pattern generation.

An inexpensive mid-range chip such as a 16F627A/628A is much better suited for this project and is probably cheaper in the long run, i.e. one PIC vs One PIC and two shift registers.
 
Yes many have said such things about getting a new PIC but as for now im sticking too the 509 untill I understand assembly much more. As of right now im just going back looking how I did things in the past following tut's etc... So at the moment I just need help on what ive written and if its correct or not and why its not building right ?
 
Some of your errors I can't help with as you haven't included all your code.

The Message[305]s are caused by not having a destination on your RLFs. You need either F for file or W for W tagged on the end of the instructions.
I.E.
Code:
		RLF	Display,F
or
		RLF	Display,W

The Error[113]s are caused by the BTFSC 03h,b instructions.
I assume you are trying to test the Carry flag and if so it should be BTFSC STATUS,C.
You should also note that this instruction only skips the following instruction, you appear to expect it to jump over several.

Can I suggest you change your subroutine to,
Code:
test_clock
		movlw	b'000001'	;value to send 1 bit
		BTFSS	STATUS,C	;carry set
		movlw	b'000000'	;no so use value to send zero bit
		movwf	GPIO		;put it on port
		nop			;avoid RMW problem
		bsf	GPIO,1		; Clocks it
		nop			;short delay
		bcf	GPIO,1		;finish clocking
		retlw	0

HTH

Mike.
 
Thanks Mike all errors are fixed now so now all I have to do is just make my pattern and call the engine and it should understand what im giving it and write what I need to the Data Pin and clock it then go to the next pattern right since I now have the engine figured out ? And thanks again for helping my teacher is going to be happy haha
 
Last edited:
Yes many have said such things about getting a new PIC but as for now im sticking too the 509 untill I understand assembly much more. As of right now im just going back looking how I did things in the past following tut's etc... So at the moment I just need help on what ive written and if its correct or not and why its not building right ?

But most of my post was a warning about addressing quirks of baseline PICs. If your program gets longer than 256 words there are issues with regard to where you place your subroutines. If you should choose to implement your patterns using table lookups this can become important if the tables occupy a large portion of memory.

I also remind you that the return stack is two levels deep so there is a servere restriction on the nesting of subroutines, at lest on those invoked with a CALL instruction.

Perhaps it is best just to let you discover these thing for yourself!
 
Hi skyhawk,

I agree totally that switching to a better chip would be the best solution.

However, you are not completely correct on your description of the 12 bit chips. On the 509 you can make calls to addresses in the 0x200-0x2ff region by setting the PA0 bit in status. You can also use the two pages that are not accessible to calls for tables as computed gotos will still work.

Darkstar,
What skyhawk states is so true. You are making your life so much harder by staying with the 12 bit chips. Switching to a 14 bit chip (12F683 - still 8 pins) will give you so much more flexibility.


Mike.
 
However, you are not completely correct on your description of the 12 bit chips. On the 509 you can make calls to addresses in the 0x200-0x2ff region by setting the PA0 bit in status. You can also use the two pages that are not accessible to calls for tables as computed gotos will still work.

I thought I covered the bases with:

These PICs have the instruction space divided into 512 word pages. Only the first 256 words of a page can be used as the destination of a subroutine call or instruction that modifies PCL. In addition, care must be taken that the page select bits in the STATUS register are set for a GOTO, CALL, or instruction that modifies the PCL.

Total memory space 1024 words, 512 word pages, so need to set page select bit (PA0) in STATUS register to access all of memory.

I'm not sure how you do a computed GOTO, but I do it by doing arithmetic on PCL to select the GOTO in a table of GOTOs, since that modifies PCL then the table of GOTOs must be in the first 256 words of each page. In that case I have used space in that area for GOTO's rather than data tables. I don't see the gain. Using GOTO's will allow one to move the body of a subroutine out of the top half of the page as long as the entry point is there.

My point was/is that one can do tricks to get around the limitations of baseline PICs, but that is something that is probably beyond the skills/understanding of a beginner.

Mike you are most geneous with the help you give beginners here on the forum.
 
Last edited:
Sorry Skyhawk, I didn't see your earlier post and was responding to your post immediately above mine. You are also correct on the computed gotos, I didn't realise the call bug also effected writes to PCL.

Mike.
 
Well Mr. Darkstar, I got myself a couple 12F509's and some HEF4894B 12-stage shift registers in my Digikey order today. We shall see how well this crappy little chip can drive a 3x3x3 LED cube. :p

The 12F509 took me some time to get used to. Took me an hour or two to figure out the chip's strange quirks and get an LED flashing on GPIO2. Now that I have the chip's oddities figured out I can move on. What a bare-bones chip!

My blinky prog:
Code:
	include	"P12F509.INC"
	__config _IntRC_OSC & _WDT_OFF & _MCLRE_ON

	cblock	0x07
	d1,d2
	endc

	org	0x000
init	movlw	b'11001000'	;clear T0CS for output on GPIO2
	option
	movlw	b'001000'	;set pins to all outs
	tris	GPIO
	clrf	GPIO		;zero all pins
main	bsf	GPIO,2
	call	delay
	bcf	GPIO,2
	call	delay
	goto	main

delay	movlw	0x3e		;0.2 second delay
	movwf	d1
	movlw	0x50
	movwf	d2
delay_0	decfsz	d1, f
	goto	del1
	decfsz	d2, f
del1	goto	delay_0
	retlw	0

	end
 
Last edited:
and some HEF4894B 12-stage shift registers in my Digikey order today. We shall see how well this crappy little chip can drive a 3x3x3 LED cube. :p
Aaarrrggghhh! My LED cube is common cathode, but my new shift registers are open drain, so I need a common anode cube! Oh well, I guess I'm building a new cube. Think I'll go 4x4x4 (for other MCUs) and red LEDs this time.

I can only use 3x3x3 of it with the 12F509 due to too few pins (509 has 5 outs). Need 2 pins to control the shift register and 3 for the anodes. Hmm... I guess I could add another shift register to control the anodes and would only need 4 output pins that way... And I could go to a 8x8x8 cube! :p (I'd probably run out of memory on this tiny chip though.)

**broken link removed**
 
Last edited:
Yes, you could drive the anodes via high side PNPs. So 4*4 is 16 cathodes plus 4 anodes can fit on two 12 bit shift registers.

Mike.
 
Yes, you could drive the anodes via high side PNPs. So 4*4 is 16 cathodes plus 4 anodes can fit on two 12 bit shift registers.
Groovy! :D It shall be done! Might have to solder together a control board. It gets very hectic wiring that much stuff on a breadboard. I'll just socket the PIC so I can replace it with a 12F683 later when I run out of space (and patience) with the 12F509. No interrupts! Ridiculous! :p
 
I think you'll find the 2 level deep stack to be very constricting. And you'll miss things like addlw.:eek:

Mike.
 
I think you'll find the 2 level deep stack to be very constricting. And you'll miss things like addlw.:eek:

Yes, it's ludicrous bodging lot's of extra hardware on because you're using too small a device, plus the 12 bit PIC's are very limited compared with the 14 bit ones, never mind the 16 bit ones.

In the distant past you had no choice if you wanted a tiny PIC, but for many years now you have been able to get 14 bit PIC's in 8 pin packages, even including A2D.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top