Electronics > Beginners
Assembly code Help! PIC16F57
KL27x:
edited for clarity Ok, so your version doesn't do a bunch of that stuff and doesn't use the non-existent portC, right?
Oh, I was looking at the wrong part of the datasheet for the 16F54. And you use the 57. So disregard this.
--- Quote ---they kept adding features until they run out of program memory and ended up with just 3 bytes to spare!
--- End quote ---
Ok, this is good. I went over it and found TWO seemingly unused registers, 0x0E and 0x0F.
The code uses fsr and ind here and there, so I can't be 100% positive without even MORE work, but if they said it and I found two, it looks like these are in the clear.
*Also in the 16F57, there are actually many more available registers. If it were the 16F54, then yeah, there would only be these couple left.
Fix: (this will not affect anything except pattern)
1. define a new variable as follows. At the top with all the other variables, add this:
;Variables
temp_reg1 equ 08
temp_reg2 equ 09
temp_reg3 equ 0A
temp_reg4 equ 0B
mode_byte equ 0C
function_byte equ 0D
new_byte equ 0E ;bit 0 used for extending "pattern" to 5 bit range. new_byte<7-1> are available. init2 loads 0x00
loop_divider equ 10
credit_count equ 11
2. Good practice to initialize variables. So in init2, add this line
init2
clrf fsr
movlw 30 ;FILE TABLE START POSITION
movwf data_counter
movlw 01
movwf digit_pointer
movwf mode_byte
clrf switch_old
clrf switch_new
clrf counter_lo
clrf counter_hi
clrf credit_count
clrf leds_value
clrf credit_display
clrf new_byte
3.This is where we are using the new bit to save information. Change sequence1 to
sequence1
bsf counter_lo,7
incf counter_lo,f
btfss status,zer
goto sequend
incf counter_hi,f
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;insert this code
movlw .1
btfsc counter_hi,4
xorwf new_byte,f ;this toggles bit0 of new_byte when counter_hi overflows to 16
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
bcf counter_hi,4 ;this must go back to the original bcf counter_hi,4 !!
4. This is where we recall this information and utilize it. Change feature to:
feature
clrf fsr
clrw
movwf portA ;SWITCH OFF DIGIT DRIVE
movf credit_display,W
btfss mode_byte,5
goto feature1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; movf counter_hi,W
;
clrw
btfsc new_byte,0 ;if this bit is set
movlw 0x10 ;we are going to add .16 to whatever is in the counter_hi and place the result
addwf counter_hi,w ;in w, leaving counter_hi alone. So this is invisible to the rest of the code.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
call pattern
5. Ok, this is where the paging thing throws error. so you have to go to "dummy" and change the position of the org instruction
org 0x600 ;put the org 600 instruction in front of "dummy"
dummy
clrf fsr
movf data_counter,W
movwf fsr
movlw 4
addwf fsr,f
movlw slowdown_time ;CONSTANT FOR SPEED CONTROL
movf ind,f
btfss status,zer ;HAS 'SLOW' REACHED 0 ?
decf ind,W
movwf ind ;RESET 'SLOW' CONSTANT
retlw 00
; org 600 ; remove the org 600 instruction from here and put it in front of this subroutine.
The change you made to feature1 doesn't make any difference, anymore. You can leave it or change it back to how it was, before.
6. Cross your fingers. >:D
westfw:
KL27x - that was really excellent analysis (and write-up)! (man, talk about write-only code, though!)
--- Quote ---which for a win is the "pattern2" table.
--- End quote ---
Unfortunately, that's exactly what you'd expect to happen. The program is using the same code to display pattern and pattern2, so both patterns need to be the same length. Can you just add empty or repeated code to pattern2? It seems to still compile for the simulator for me.
KL27x:
^yeah, that would have fixed the pattern2 bug, if you just redundantly copied those 16 lines! Good catch! (But my previous change was adding just 1 line of code by comparison, which was better!) But there seems to also be something going on with win2, as well. So by not clearing counter_hi at 16 in the "sequence1", and clearing it at 32, instead, you might adversely affect some other part of the code that is also using counter_hi before reloading the value.
As I said, it is sometimes easier to just use more memory to add stuff, so you know there is no conflict. It is one of those things that go along with writing absolute code. Keeping track of memory is a pain and should be notated, carefully, especially on device with tiny amount of memory! In this case we used just one more bit of memory and left the rest of the byte usable.
Also, if you're playing along, write "errorlevel -305" and "errorlevel -306" at the top of the page, in case you aren't aware of that. Very handy to clean up your error code dialog box.
westfw:
--- Quote ---, ran out of program memory.
--- End quote ---
--- Quote ---their recollection is they kept adding features until they run out of program memory and ended up with just 3 bytes to spare!
--- End quote ---
Really? The assembly shows lots of space left. Though of course there's that PIC limitation where it's a lot harder to use the 2nd half of each "program" page...
(Or am I missing something else? It's been a long time since I've looked very hard at a low-end PIC...)
--- Code: --- Program Memory Usage Start End
--------- ---------
0x000000 0x00008b
0x000200 0x0002c7
0x000400 0x00050b
0x000600 0x000708
0x000fff 0x000fff
874 out of 2053 program addresses used, program memory utilization is 42%
--- End code ---
KL27x:
Yeah, I was wrong when I "ran out of program memory." In fact, I got a "must be in lower half of page" error, which I admit I am not even sure I know what that means, anymore. In the modern midrange, when you run across the page boundary, that usually means you have to shuffle code and might be out of space - at least on the current page... and since all the code is written with short calls and gotos, this is like running out of easily used space, even if you have blank pages! I just jumped the gun on that because I had to be somewhere's else. There is none of this half page stuff in the modern PICs.
When OP said that they ran out of program memory, I assume he means variable memory, not programming space. (In PIC Harvard architecture, program memory is separate from variable memory!) And the "3 bytes left" seems to be a match. I found 0x0E, 0x0F are undefined. And it LOOKS like 0x10 might also be unused, but I'm not positive. It is defined, but the name is not used in the program, anywhere. But fsr and ind are used to initialize it to zero, and many a time I use code space without naming it (but I will notate the used sections of memory) :-//
In the datasheet, general purpose (this is basically RAM or variable memory) is located between 0x07 and 0x1F. So this thing has nearly zip for memory. 25 bytes.
--- Quote ---where it's a lot harder to use the 2nd half of each "program" page...
--- End quote ---
Yeah, I have no clue what this means. It has been a decade since I used this type of chip, and I don't think I ever learned this part. But I take it that there are some people who actually get this bit. If changing the position of "dummy" subroutine borks the OP's code, I am at a loss. It wouldn't assemble until I did that.
*edit: oh, I was looking at 16F54. The 16F57 has 72 bytes! So there's plenty more variable memory, too.
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version