Maker Pro
Maker Pro

Help with using shift register to expand uC output

max_torch

Feb 9, 2014
111
Joined
Feb 9, 2014
Messages
111
I am just practicing how to use shift registers to expand a microcontroller's output. So far I'm only practicing using assembler language, I haven't yet dabbled in using C or BASIC with microcontrollers.
Here is a schematic I made:
shiftreg.png
The shift registers im using is the 4094 and the microcontroller is PIC16F84A, with oscillator set to 4MHz.
I wrote a program that will count from 0 to 29, wherein the ones place is at the bottom, and then display 1 in all the segments after that for a brief duration, then loop back to the start.
It sort of works..
My problem is that in some frames, the output doesn't come out right, but when the program loops back to the start and reaches that same frame it then comes out okay but then other frames don't come out right.
Basically, everytime it runs it seems like on some frames the output randomly don't display the numbers properly and there is no way to predict on which frames the error will occur.

Please help me find what is wrong with my program, or circuit.
Here is the source code:
include <p16f84a.inc>

__CONFIG _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_ON

cblock 0x20
d1
d2
d3
temp
digit
placer
endc


CONFIG bsf STATUS, RP0
clrf PORTB
bcf STATUS, RP0
clrf PORTB

movlw d'200'
movwf temp
Flush bsf PORTB, 1
bcf PORTB, 1
decfsz temp, f
goto Flush


START bsf PORTB, 3 ;Set OE

movlw d'7'
movwf placer ;placer starts at 7

movfw placer
movwf digit

call ZERO
decfsz digit, f
goto $-2
bsf PORTB, 2
bcf PORTB, 2
call DELAY

decf placer ;placer is now 6

movfw placer
movwf digit
call ONE
call ONES

movfw placer
movwf digit
call TWO
call ONES

movfw placer
movwf digit
call THREE
call ONES

movfw placer
movwf digit
call FOUR
call ONES

movfw placer
movwf digit
call FIVE
call ONES

movfw placer
movwf digit
call SIX
call ONES

movfw placer
movwf digit
call SEVEN
call ONES

movfw placer
movwf digit
call EIGHT
call ONES

movfw placer
movwf digit
call NINE
call ONES

decf placer ;placer is now 5

movfw placer
movwf digit
call ZERO
call TENS

movfw placer
movwf digit
call ONE
call TENS

movfw placer
movwf digit
call TWO
call TENS

movfw placer
movwf digit
call THREE
call TENS

movfw placer
movwf digit
call FOUR
call TENS

movfw placer
movwf digit
call FIVE
call TENS

movfw placer
movwf digit
call SIX
call TENS

movfw placer
movwf digit
call SEVEN
call TENS

movfw placer
movwf digit
call EIGHT
call TENS

movfw placer
movwf digit
call NINE
call TENS

movfw placer
movwf digit
call ZERO
call TWENTY

movfw placer
movwf digit
call ONE
call TWENTY

movfw placer
movwf digit
call TWO
call TWENTY

movfw placer
movwf digit
call THREE
call TWENTY

movfw placer
movwf digit
call FOUR
call TWENTY

movfw placer
movwf digit
call FIVE
call TWENTY

movfw placer
movwf digit
call SIX
call TWENTY

movfw placer
movwf digit
call SEVEN
call TWENTY

movfw placer
movwf digit
call EIGHT
call TWENTY

movfw placer
movwf digit
call NINE
call TWENTY

call ENDER


goto START

ONES call ZERO
decfsz digit, f
goto $-2
bsf PORTB, 2
bcf PORTB, 2
call DELAY
return

TENS call ONE
call ZERO
decfsz digit, f
goto $-2
bsf PORTB, 2
bcf PORTB, 2
call DELAY
return

TWENTY call TWO
call ZERO
decfsz digit, f
goto $-2
bsf PORTB, 2
bcf PORTB, 2
call DELAY
return

ENDER call ONE
call ONE
call ONE
call ONE
call ONE
call ONE
call ONE
bsf PORTB, 2
bcf PORTB, 2
call DELAYLONG


goto START


;;;;;;Digits Subroutines;;;;;;;;;;;
ZERO bcf PORTB, 0

movlw d'2'
movwf temp
bsf PORTB, 1
bcf PORTB, 1
decfsz temp, f
goto $-3

bsf PORTB, 0

movlw d'6'
movwf temp
bsf PORTB, 1
bcf PORTB, 1
decfsz temp, f
goto $-3

return

ONE bcf PORTB, 0

movlw d'5'
movwf temp
bsf PORTB, 1
bcf PORTB, 1
decfsz temp, f
goto $-3

bsf PORTB, 0

movlw d'2'
movwf temp
bsf PORTB, 1
bcf PORTB, 1
decfsz temp, f
goto $-3

bcf PORTB, 0

bsf PORTB, 1
bcf PORTB, 1

return

TWO bcf PORTB, 0

bsf PORTB, 1
bcf PORTB, 1

bsf PORTB, 0

bsf PORTB, 1
bcf PORTB, 1

bcf PORTB, 0

bsf PORTB, 1
bcf PORTB, 1

bsf PORTB, 0

movlw d'2'
movwf temp
bsf PORTB, 1
bcf PORTB, 1
decfsz temp, f
goto $-3

bcf PORTB, 0

bsf PORTB, 1
bcf PORTB, 1

bsf PORTB, 0

movlw d'2'
movwf temp
bsf PORTB, 1
bcf PORTB, 1
decfsz temp, f
goto $-3

return

THREE bcf PORTB, 0

bsf PORTB, 1
bcf PORTB, 1

bsf PORTB, 0

bsf PORTB, 1
bcf PORTB, 1

bcf PORTB, 0

movlw d'2'
movwf temp
bsf PORTB, 1
bcf PORTB, 1
decfsz temp, f
goto $-3

bsf PORTB, 0

movlw d'4'
movwf temp
bsf PORTB, 1
bcf PORTB, 1
decfsz temp, f
goto $-3

return

FOUR bcf PORTB, 0

bsf PORTB, 1
bcf PORTB, 1

bsf PORTB, 0

movlw d'2'
movwf temp
bsf PORTB, 1
bcf PORTB, 1
decfsz temp, f
goto $-3

bcf PORTB, 0

movlw d'2'
movwf temp
bsf PORTB, 1
bcf PORTB, 1
decfsz temp, f
goto $-3

bsf PORTB, 0

movlw d'2'
movwf temp
bsf PORTB, 1
bcf PORTB, 1
decfsz temp, f
goto $-3

bcf PORTB, 0

bsf PORTB, 1
bcf PORTB, 1

return

FIVE bcf PORTB, 0

bsf PORTB, 1
bcf PORTB, 1

bsf PORTB, 0

movlw d'2'
movwf temp
bsf PORTB, 1
bcf PORTB, 1
decfsz temp, f
goto $-3

bcf PORTB, 0

bsf PORTB, 1
bcf PORTB, 1

bsf PORTB, 0

movlw d'2'
movwf temp
bsf PORTB, 1
bcf PORTB, 1
decfsz temp, f
goto $-3

bcf PORTB, 0

bsf PORTB, 1
bcf PORTB, 1

bsf PORTB, 0

bsf PORTB, 1
bcf PORTB, 1

return

SIX bcf PORTB, 0

bsf PORTB, 1
bcf PORTB, 1

bsf PORTB, 0

movlw d'5'
movwf temp
bsf PORTB, 1
bcf PORTB, 1
decfsz temp, f
goto $-3

bcf PORTB, 0

bsf PORTB, 1
bcf PORTB, 1

bsf PORTB, 0

bsf PORTB, 1
bcf PORTB, 1

return

SEVEN bcf PORTB, 0

movlw d'5'
movwf temp
bsf PORTB, 1
bcf PORTB, 1
decfsz temp, f
goto $-3

bsf PORTB, 0

movlw d'3'
movwf temp
bsf PORTB, 1
bcf PORTB, 1
decfsz temp, f
goto $-3

return

EIGHT bcf PORTB, 0

bsf PORTB, 1
bcf PORTB, 1

bsf PORTB, 0

movlw d'7'
movwf temp
bsf PORTB, 1
bcf PORTB, 1
decfsz temp, f
goto $-3

return

NINE bcf PORTB, 0

bsf PORTB, 1
bcf PORTB, 1

bsf PORTB, 0

movlw d'2'
movwf temp
bsf PORTB, 1
bcf PORTB, 1
decfsz temp, f
goto $-3

bcf PORTB, 0

bsf PORTB, 1
bcf PORTB, 1

bsf PORTB, 0

movlw d'4'
movwf temp
bsf PORTB, 1
bcf PORTB, 1
decfsz temp, f
goto $-3

return


DELAY movlw d'2'
movwf d1
movlw d'24'
movwf d2
movlw d'167'
movwf d3
LOOP decfsz d3, f
goto LOOP
decfsz d2,f
goto LOOP
decfsz d1,f
goto LOOP
return

DELAYLONG movlw d'18'
movwf d1
movlw d'24'
movwf d2
movlw d'167'
movwf d3
LOOP2 decfsz d3, f
goto LOOP2
decfsz d2,f
goto LOOP2
decfsz d1,f
goto LOOP2
return


END
 

Attachments

  • readfromregoutput - Copy.txt
    7.3 KB · Views: 104

Old Steve

Jul 23, 2015
734
Joined
Jul 23, 2015
Messages
734
Aaaaargh, you're kidding!

max_torch, first a point I must raise - you have to use code tags when posting code. The above looks terrible. The length doesn't help - it's virtually unreadable.
You'll find the code tags on the toolbar above the edit window. Hover your mouse over the fourth item from the right and an "Insert..." tooltip will appear. Click on that button and select "Code", then paste your code into the window that appears.

It's also a good idea to get rid of all superfluous spacing, particularly when posting a long example as you have. You don't need all of those spaces between lines - it makes it much harder to read.

Correct formatting would help, too, with the instructions indented, (I'll bet you're getting lots of assembler errors), and the subroutine labels on separate lines.

Then someone might take the time to look at it, but even then, it's just plain too long.
Also, mention which assembler and the IDE you're using, if any, when you post.

You should also include liberal comments, so someone reading your code can tell what's going on at a particular point.

For me, this is just too long and messy to contemplate. You could correct your post - it's not too late. (Then I'll edit this reply to reflect your 'repaired' post.)

Edit: It's best to fully format your code before pasting it into the "code" window, too. It's much harder to format there, since 'tab' can't be used to indent.
 
Last edited:

max_torch

Feb 9, 2014
111
Joined
Feb 9, 2014
Messages
111
I could no longer edit the OP. Please consider this the new OP. I hope the code now would be 'readable'

I am just practicing how to use shift registers to expand a microcontroller's output. So far I'm only practicing using assembler language, I haven't yet dabbled in using C or BASIC with microcontrollers.
Here is a schematic I made:
shiftreg-png.22377

The shift registers im using is the 4094 and the microcontroller is PIC16F84A, with oscillator set to 4MHz.
I wrote a program that will count from 0 to 29, wherein the ones place is at the bottom, and then display 1 in all the segments after that for a brief duration, then loop back to the start.
It sort of works..
My problem is that in some frames, the output doesn't come out right, but when the program loops back to the start and reaches that same frame it then comes out okay but then other frames don't come out right.
Basically, everytime it runs it seems like on some frames the output randomly doesn't display the numbers properly and there is no way to predict on which frames the error will occur.

Please help me find what is wrong with my program, or circuit.
When I built the source code there was no error or warning. All the labels are in the first column and all assembler instructions are in the second indent.
The IDE I'm using is MPLAB.
The source code is attached in a zip file as a .asm, because if I try to copy it to notepad, or to here using the code tag the indentations get screwed up.
 

Attachments

  • send.zip
    1.2 KB · Views: 98
Last edited:

max_torch

Feb 9, 2014
111
Joined
Feb 9, 2014
Messages
111
Also, I'm using Proteus VSM to simulate.
Here is the .dsn file of the simulation:
 

Attachments

  • dsn.zip
    20.7 KB · Views: 93

Old Steve

Jul 23, 2015
734
Joined
Jul 23, 2015
Messages
734
I could no longer edit the OP. Please consider this the new OP. I hope the code now would be 'readable'

I am just practicing how to use shift registers to expand a microcontroller's output. So far I'm only practicing using assembler language, I haven't yet dabbled in using C or BASIC with microcontrollers.
Here is a schematic I made:
shiftreg-png.22377

The shift registers im using is the 4094 and the microcontroller is PIC16F84A, with oscillator set to 4MHz.
I wrote a program that will count from 0 to 29, wherein the ones place is at the bottom, and then display 1 in all the segments after that for a brief duration, then loop back to the start.
It sort of works..
My problem is that in some frames, the output doesn't come out right, but when the program loops back to the start and reaches that same frame it then comes out okay but then other frames don't come out right.
Basically, everytime it runs it seems like on some frames the output randomly doesn't display the numbers properly and there is no way to predict on which frames the error will occur.

Please help me find what is wrong with my program, or circuit.
When I built the source code there was no error or warning. All the labels are in the first column and all assembler instructions are in the second indent.
The IDE I'm using is MPLAB.
The source code is attached in a zip file as a .asm, because if I try to copy it to notepad, or to here using the code tag the indentations get screwed up.
I don't have time to go over that much code searching for your errors, it would take me hours. I don't usually write in assembly. I write in C or PICBasic, because assembly is too slow and difficult to debug. I can help with simple, short assembly snippets, but not this megalith.

And please don't PM me again personally asking me to check it.

The best I can suggest is that you run it in the MPLAB simulator, or wait for someone more fluent in PIC assembly language to help out.
 

wrighty

Aug 1, 2009
10
Joined
Aug 1, 2009
Messages
10
Your code would be much simpler if you had 2 loops.
Inner loop does segment data and outer loop takes in data for segment from a table in memory.
 

Colin Mitchell

Aug 31, 2014
1,416
Joined
Aug 31, 2014
Messages
1,416
Start by simplifying everything

for instance
d'18'
is .18

a file or register in a delay will 255 or 256 times without having to load it at the start.
This saves 2 lines of code.

Use a table. This will simplify the listing.

See talkingelectronics.com website for .asm guides and a complete list of subroutines
 

CDRIVE

Hauling 10' pipe on a Trek Shift3
May 8, 2012
4,960
Joined
May 8, 2012
Messages
4,960
Start by simplifying everything
Reading your stuff is always fun but it sometimes (most times) requires extensive training in the art of ciphers and deciphering. I'm not an ASM wiz but this code snippet was easy. Change d'18' (="d"ecimal 18) to .18.
for instance
d'18'
is .18
But then we move along to Molasses Swamp and get bogged down repeatedly reading your next sentence. Are there words missing?? "Will" what?
a file or register in a delay will 255 or 256 times without having to load it at the start.
This saves 2 lines of code.
Does it matter if it's Shaker, Stickley, Queen Ann, other? Sorry, I couldn't help myself! :p
Use a table. This will simplify the listing.
Ah, while instructive words may always seem to be missing in your posts this plug is something that's never forgotten. Hey, just bust'n your 'OO'. I woke up this morning and thought I was Martin. :D We do need a 'OO' busting smiley though!

Cheers,
Chris
See talkingelectronics.com website for .asm guides and a complete list of subroutines
 
Top