| Electronics > Beginners |
| Assembly code Help! PIC16F57 |
| << < (7/32) > >> |
| 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 |
| Message Index |
| Next page |
| Previous page |