![]() | ![]() | ![]() |
| | |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
| | Thread Tools | Display Modes |
| | (permalink) |
| New Member | Hi, Im just starting out with the PICs. Im currently using the PIC16F628 to play with. My objective is to make an LED controller that has multiple light patterns, etc. Thanks to Nigel Goodwin's site and others I have that part covered. I will be using a momentary switch to change the patterns. Again, that has been adequately explained. Now I am stuck on saving the pattern. That is, I want to be able to store pattern number 8 as the startup pattern instead of having to cycle through 7 other patterns every time I start up the LEDs. My first guess is using the 128bytes of EEPROM, however I am more than willing to entertain other suggestions. I am sure this has been addressed, however I have been unsuccessful in my attempt to find the code or tutorial applicable. Thanks, Clayton |
| | |
| | (permalink) |
| Experienced Member | Check out Nigels tut5 - there's a eeprom read and write routine. http://www.winpicprog.co.uk/pic_tutorial5.htm |
| | |
| | (permalink) |
| New Member | Thats exactly what I was looking for. Thanks. Clayton |
| | |
| | (permalink) |
| New Member | I have run into another problem. I have attempted to use the EE_Write and EE_read subroutines from the above tutorial, yet my chip doesnt cooperate. It works fine w/o the eeprom routines. Here are the routines as I have them now, with minor modifications to meet my program: EE_Read bsf STATUS, RP0 ; Bank 1 movlw EEPROM_Addr movwf EEADR ; Address to read bsf EECON1, RD ; EE Read movf EEDATA, W ; W = EEDATA bcf STATUS, RP0 ; Bank 0 movwf PatternCount ; returns value of pattern call CheckSwitch ; calls routine to select pattern EE_Write movfw PatternCount ; read current value bsf STATUS, RP0 ; Bank 1 bsf EECON1, WREN ; Enable write movwf EEDATA ; set EEPROM data movlw EEPROM_Addr movwf EEADR ; set EEPROM address movlw 0x55 movwf EECON2 ; Write 55h movlw 0xAA movwf EECON2 ; Write AAh bsf EECON1, WR ; Set WR bit ; begin write bcf STATUS, RP0 ; Bank 0 btfss PIR1, EEIF ; wait for write to complete. goto $-1 bcf PIR1, EEIF ; and clear the 'write complete' flag bsf STATUS, RP0 ; Bank 1 bcf EECON1, WREN ; Disable write bcf STATUS, RP0 ; Bank 0 retlw 0x00 PatternCount is my defined variable. I have defined EEPROM_Addr as Equ 0x00. I did not see any of the other labels being defined in Nigel's tutorial so I presume they are understood by the MPLAB IDE. Again, I have searched around, including on this site, but I cant make heads or tails of this matter. Any and all help greatly appreciated. Thanks, Clayton |
| | |
| | (permalink) |
| Experienced Member | You should not define EEPROM_Addr as equ 00. You should define EEPROM_Addr to somewhere that is user RAM. Such as 0x20. You should then write zero to EEPROM_Addr. So, at the top of your code you would have, EEPROM_Addr Equ 0x20 Or some other address that is not used for something else. And then in you main code you would have either, clrf EEPROM_Addr Or, movlw 0x00 movwf EEPROM_Addr HTH Mike. |
| | |
| | (permalink) |
| Experienced Member | P.S. You can see if your write routine is working by putting the chip back in the programmer and reading it. Mike. |
| | |
| | (permalink) |
| New Member | Pommie, I see what you're getting at. I modifed the above to look like this: movf 0x00, w ; read current value bsf STATUS, RP0 ; Bank 1 bsf EECON1, WREN ; Enable write movwf EEDATA ; set EEPROM data movlw 0x2100 movwf EEADR ; set EEPROM address movlw 0x55 movwf EECON2 ; Write 55h movlw 0xAA movwf EECON2 ; Write AAh bsf EECON1, WR ; Set WR bit ; begin write bcf STATUS, RP0 ; Bank 0 btfss PIR1, EEIF ; wait for write to complete. goto $-1 bcf PIR1, EEIF ; and clear the 'write complete' flag bsf STATUS, RP0 ; Bank 1 bcf EECON1, WREN ; Disable write bcf STATUS, RP0 ; Bank 0 movlw 0x02 movwf PORTB retlw 0x00 As you see, I changed the address of EEADR to 0x2100. The LED at 0x02 on PORTB lights up indicating completion of the routine, but the change in not reflected when I read the chip. Any other suggestions? Thanks, Clayton |
| | |
| | (permalink) |
| New Member | BTW the above routine is the only one running in the program. Again, Thanks, Clayton |
| | |
| | (permalink) |
| Super Moderator | So how do you expect to fit 0x2100 in an 8 bit variable?. My tutorial routine is fully working, why not use it 'as is' to prove it works, THEN try and modify it to do exactly what you want. |
| | |
| | (permalink) |
| New Member | As always, Mr. Goodwin, you are doing a fine job of exposing poor PIC/electronics understanding by us new guys. Believe it or not, I do appreciate it. As to your suggestion, I did take it. Here it is in its current version. EE_Write movf PatternCount, w ; read current value bsf STATUS, RP0 ; Bank 1 bsf EECON1, WREN ; Enable write movwf EEDATA ; set EEPROM data movlw 0x00 movwf EEADR ; set EEPROM address movlw 0x55 movwf EECON2 ; Write 55h movlw 0xAA movwf EECON2 ; Write AAh bsf EECON1, WR ; Set WR bit ; begin write bcf STATUS, RP0 ; Bank 0 btfss PIR1, EEIF ; wait for write to complete. goto $-1 bcf PIR1, EEIF ; and clear the 'write complete' flag bsf STATUS, RP0 ; Bank 1 bcf EECON1, WREN ; Disable write bcf STATUS, RP0 ; Bank 0 retlw 0x00 As you see, not much has changed. I changed the initial f register to PatternCount and I hard coded 0x00 into EEADR instead of using a constant. Minor change, really. Refresher on my program, I am using a table to sequence the LEDs. PatternCount is what I am using to store the counter in. Each time the switch is pressed, PatternCount is increased. I know this part is working as the LED patterns do change. However, the EE_Write is not writing this to the EEPROM. I have the Call to EE_Write immediately before the increment counter commands in the same routine. Therefore, every time the pattern is changed EE_Write should be firing and updating the EEPROM. However, that is not the case. I am hoping that either you or someone else might have an idea. Thanks, Clayton |
| | |
| | (permalink) |
| Super Moderator | On a brief look at that I don't spot any obvious problem, what about the rest of the program?. |
| | |
| | (permalink) |
| New Member | Nigel, Due to the size of the program (252 lines) I decided to email it to you. It went to the lpilsley.co.uk account. Anyone else interested in helping, I will be glad to email other copies after I wake up this afternoon. Thanks, Clayton |
| | |
| | (permalink) |
| New Member | Ok, I just found out how to post the code in that scrolling window. So here is the program. Code: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Sequence of LEDs ; ;Author Clayton Bradley ; ;This version cycles through different ; ;possibilities. Also allows selection ; ;of a specific pattern by means of a ; ;momentary switch ; ;Credit due to Nigel Goodwin for various; ;routines borrowed throughout this ; ;program. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LIST p=16F628 ;tell assembler what chip we are using include "P16F628.inc" ;include the defaults for the chip __config 0x3D18 ;sets the configuration settings (oscillator type etc.) cblock 0x20 ;start of general purpose registers count1 ;used in delay routine counta ;used in delay routine countb ;used in delay routine LightVal ;the lit LED StrobeCount ;Counter for number of times the LED strobes StrobeTimes ;number of times the LED strobes PatternCount ;Choose pattern endc SWPORT equ PORTB SW1 equ 0x00 AllLEDs equ b'11000110' ;Just a bunch of easy to use mnemonics for the LEDs LeftLEDs equ b'00000110' RightLEDs equ b'11000000' TopLEDs equ b'01000010' BottomLEDs equ b'10000100' LeftXLEDs equ b'10000010' RightXLEDs equ b'01000100' LED1 equ b'00000010' LED2 equ b'00000100' LED3 equ b'01000000' LED4 equ b'10000000' PatternNumber equ 0x07 org 0x0000 ;org sets the origin, 0x0000 for the 16F628, ;this is where the program starts running movlw 0x07 movwf CMCON ;turn comparators off (make it like a 16F84) bsf STATUS, RP0 ;select bank 1 movlw b'00000001' ;set PortB all outputs except port 0 movwf TRISB bcf STATUS, RP0 ;select bank 0 movlw 0x03 ;moves the number 3 into StrobeTimes movwf StrobeTimes ;number of times the LEDs strobe clrf PatternCount ;initialize Pattern Count ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;Start of Program routine;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; call EE_Read CheckSwitch call EE_Write CSDelay call Delay_On ;allow time for debounce btfss SWPORT, SW1 ;check if momentary switch has returned to open call CSDelay ;if not, cycle through again incf PatternCount, 0 ;increase pattern count, so as to cycle through next pattern xorlw PatternNumber ;check for last entry by xoring value in Pattern Number with Pattern Count btfsc STATUS, Z ;check status bit to see if set, if so, Pattern Count higher than Pattern Number clrf PatternCount ;if status set, reset Pattern Count movfw PatternCount ;move value of Pattern Count to W to be used in choosing from table incf PatternCount ;increase Pattern Count to next value call PatternTable ;now got to Pattern Table to select the next pattern ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;CODE TO STROBE LEDS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Strobe_LED ;code for strobing the LEDs movwf LightVal ;moves the LED code in the W reg into LightVal for safekeeping movfw StrobeTimes ;moves the value of StrobeTimes into the W register movwf StrobeCount ;moves the value to the W register into StrobeCount StrobeLoop movfw LightVal ;move LightVal into W movwf PORTB ;move W into PORTB to turn on selected LEDs btfss SWPORT, SW1 call CheckSwitch call Delay_On ;call the delay we set for LED on time movlw 0x00 ;moves value for LEDs off into W movwf PORTB ;sets PORTB to off btfss SWPORT, SW1 call CheckSwitch call Delay_Off ;calls the delay set for time LED off decfsz StrobeCount, 1 ;decreases StrobeCount, skip if zero call StrobeLoop ;loops back for another flash retlw 0x00 ;return code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EEPROM ROUTINE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EE_Write movf PatternCount, w ; read current value bsf STATUS, RP0 ; Bank 1 bsf EECON1, WREN ; Enable write movwf EEDATA ; set EEPROM data movlw 0x00 movwf EEADR ; set EEPROM address movlw 0x55 movwf EECON2 ; Write 55h movlw 0xAA movwf EECON2 ; Write AAh bsf EECON1, WR ; Set WR bit ; begin write bcf STATUS, RP0 ; Bank 0 btfss PIR1, EEIF ; wait for write to complete. goto $-1 bcf PIR1, EEIF ; and clear the 'write complete' flag bsf STATUS, RP0 ; Bank 1 bcf EECON1, WREN ; Disable write bcf STATUS, RP0 ; Bank 0 retlw 0x00 EE_Read bsf STATUS, RP0 ; Bank 1 movlw 0x00 movwf EEADR ; Address to read bsf EECON1, RD ; EE Read movf EEDATA, W ; W = EEDATA bcf STATUS, RP0 ; Bank 0 movwf PatternCount ; restore previous value retlw 0x00 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;LED LOOPS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; WigWag_Loop ;loop for the WigWag option call WigWag_LEDs ;calls the actual code of WigWag goto WigWag_Loop ;continuous loop X_Loop call X_LEDs ;calls the actual code of X_LED goto X_Loop TopAndBottom_Loop ;loop for TopAndBottom option call TopAndBottom_LEDs ;calls the actual code of TopAndBottom goto TopAndBottom_Loop ;continuous loop Sequence_Loop ;loop for Sequence option call Sequence_LEDs ;calls the actual code of Sequence goto Sequence_Loop ;continuous loop ZigZag_Loop ;loop for ZigZag call ZigZag_LEDs ;calls the actual code of ZigZag goto ZigZag_Loop ;continuous loop All_Loop ;calls a variety of flash patterns call All_LEDs call All_LEDs call WigWag_LEDs call WigWag_LEDs call X_LEDs call X_LEDs call TopAndBottom_LEDs call TopAndBottom_LEDs call Sequence_LEDs movlw LED1 call Strobe_LED call ZigZag_LEDs movlw LED1 call Strobe_LED goto All_Loop ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;LED CALLS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; All_LEDs ;code for flashing all LEDs movlw AllLEDs ;move all LEDs into W call Strobe_LED ;strobe retlw 0x00 ;return code WigWag_LEDs ;code for WigWag pattern movlw LeftLEDs ;move left LEDs into W call Strobe_LED ;strobe movlw RightLEDs ;move right LEDs into W call Strobe_LED ;strobe retlw 0x00 ;return code X_LEDs ;code for flashing an X pattern movlw LeftXLEDs ;move top left and bottom right LEDs into W call Strobe_LED ;strobe movlw RightXLEDs ;move bottom left and top right LEDs into W call Strobe_LED ;strobe retlw 0x00 ;return code TopAndBottom_LEDs ;code for top and bottom pattern movlw TopLEDs ;move top row of LEDs into W call Strobe_LED ;strobe movlw BottomLEDs ;move bottom row of LEDs into W call Strobe_LED ;strobe retlw 0x00 ;return code Sequence_LEDs ;code for sequence of LEDs movlw LED1 ;move top left LED into W call Strobe_LED ;strobe movlw LED2 ;move bottom left LED into W call Strobe_LED ;strobe movlw LED3 ;move top right LED into W call Strobe_LED ;strobe movlw LED4 ;move bottom right LED into W call Strobe_LED ;strobe movlw LED3 ;move top right LED into W call Strobe_LED ;strobe movlw LED2 ;move bottom left LED into W call Strobe_LED ;strobe retlw 0x00 ;return code ZigZag_LEDs ;code for zigzagging LEDs movlw LED1 ;move top left LED into W call Strobe_LED ;strobe movlw LED3 ;move top right LED into W call Strobe_LED ;strobe movlw LED2 ;move bottom left LED into W call Strobe_LED ;strobe movlw LED4 ;move bottom right LED into W call Strobe_LED ;strobe movlw LED2 ;move bottom left LED into W call Strobe_LED ;strobe movlw LED3 ;move top right LED into W call Strobe_LED ;strobe retlw 0x00 ;return code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;DELAY CODE;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Delay_On movlw d'40' ;delay 40 ms (4 MHz clock) movwf count1 d1 movlw 0xC7 movwf counta movlw 0x01 movwf countb Delay_0 decfsz counta, f goto $+2 decfsz countb, f goto Delay_0 decfsz count1 ,f goto d1 retlw 0x00 Delay_Off movlw d'75' ;delay 75 ms (4 MHz clock) movwf count1 d2 movlw 0xC7 movwf counta movlw 0x01 movwf countb Delay_1 decfsz counta, f goto $+2 decfsz countb, f goto Delay_1 decfsz count1, f goto d2 retlw 0x00 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;LED PATTERN TABLE;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PatternTable addwf PCL, f ;add W from Check Switch to the PCL to select proper pattern call WigWag_Loop call TopAndBottom_Loop call X_Loop call Sequence_Loop call ZigZag_Loop call All_Loop end Thanks, Clayton Last edited by Clayton; 22nd March 2007 at 12:07 PM. |
| | |
| | (permalink) |
| New Member | Turns out, I was having some stack overflow issues also. They never became a problem until I tried to use the EEPROM routines. Thanks again to any and all who scratched their heads on my behalf. Clayton |
| | |
| | (permalink) | |
| Super Moderator | Quote:
| |
| | |
| Bookmarks |
| Thread Tools | |
| Display Modes | |
| |
| | ||||
| Thread | Thread Starter | Forum | Replies | Latest |
| Spurious write or corrupting EEPROM ??? | Mr.Anderson | Micro Controllers | 5 | 19th August 2006 01:33 AM |
| working with eeprom pages? | justDIY | Micro Controllers | 1 | 7th October 2005 09:21 AM |
| Writing Data to the EEPROM | Electrix | Micro Controllers | 2 | 31st August 2005 06:39 AM |
| sequential read to AT24C01A serial EEPROM | giaracam | Micro Controllers | 2 | 26th October 2004 03:19 AM |
| Writing to EEPROM | rizzy | Micro Controllers | 3 | 27th January 2004 04:00 AM |