I have been trying to use the read data EEPROM feature of the 16F88, but can't get it to work. I have used the sample code from Microchip's datasheet. Attached is the (entire) ASM file that I am using. It should (I had hoped) store the value h'BB' in the register count1. Then read it from the data EEPROM location (h'20') and store it into the register count2. When I step through it in the simulator, the EEDATA register gets the value h'FF' instead of h'BB'. I can't figure this out and have spent many hours on it so would be very grateful if someone could help. Code follows... LIST N=90,ST=OFF,p=16F88 INCLUDE P16f88.INC ;Register definitions errorlevel 0,-302 __config _config1, _hs_osc & _wdt_off & _pwrte_on & _cp_off & _boden_off & _CCP1_RB0 & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF __config _config2, _IESO_ON & _FCMEN_ON cblock h'20' ; count1 count2 ADDR endc GOTO INITIALISE NOP NOP NOP INITIALISE banksel eedata ; Clearing these registers first to make it easier ; to see what's going on in Watch Window clrf eedata clrf eeadr banksel count1 clrf count1 clrf count2 movlw h'BB' movwf count1 read_eeprom ; This section of code taken from 16F88 datasheet BANKSEL EEADR ; Select Bank of EEADR ; MOVF ADDR,W ; I replaced this line with the literal value h'20' movlw h'20' ; (which is the address of count1) for the purposes of ; troubleshooting MOVWF EEADR ; Data Memory Address to read BANKSEL EECON1 ; Select Bank of EECON1 BCF EECON1,EEPGD ; Point to Data memory BSF EECON1,RD ; EE Read BANKSEL EEDATA ; Select Bank of EEDATA MOVF EEDATA,W ; W = EEDATA ; check to see if data read successful banksel count2 movwf count2 ; move the data value to count2 goto $ end
Problems reading data EEprom on Pic 16F88
Started by ●November 13, 2004
Reply by ●November 13, 20042004-11-13
Simon <si767676@hotmail.com> wrote in message news:6c289e8a.0411130940.75fe5ac4@posting.google.com...> I have been trying to use the read data EEPROM feature of the 16F88, > but can't get it to work. > > I have used the sample code from Microchip's datasheet. Attached is > the (entire) ASM file that I am using. It should (I had hoped) store > the value h'BB' in the register count1. Then read it from the data > EEPROM location (h'20') and store it into the register count2. > > When I step through it in the simulator, the EEDATA register gets the > value h'FF' instead of h'BB'. I can't figure this out and have spent > many hours on it so would be very grateful if someone could help. > > Code follows... > > > LIST N=90,ST=OFF,p=16F88 > INCLUDE P16f88.INC ;Register definitions > errorlevel 0,-302 > __config _config1, _hs_osc & _wdt_off & _pwrte_on & _cp_off & > _boden_off & _CCP1_RB0 & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF > __config _config2, _IESO_ON & _FCMEN_ON > > > cblock h'20' ; > count1 > count2 > ADDR > endc > > > GOTO INITIALISE > NOP > NOP > NOP > > INITIALISE > > banksel eedata ; Clearing these registers first to make it easier > ; to see what's going on in Watch Window > clrf eedata > clrf eeadr > > banksel count1 > clrf count1 > clrf count2 > movlw h'BB' > movwf count1 > > read_eeprom ; This section of code taken from 16F88 datasheet > BANKSEL EEADR ; Select Bank of EEADR > > ; MOVF ADDR,W ; I replaced this line with the literal value > h'20' > movlw h'20' ; (which is the address of count1) for the > purposes of > ; troubleshooting > > MOVWF EEADR ; Data Memory Address to read > BANKSEL EECON1 ; Select Bank of EECON1 > BCF EECON1,EEPGD ; Point to Data memory > BSF EECON1,RD ; EE Read > BANKSEL EEDATA ; Select Bank of EEDATA > MOVF EEDATA,W ; W = EEDATA > > ; check to see if data read successful > banksel count2 > movwf count2 ; move the data value to count2 > > goto $ > endHi Simon, The data EEPROM is protected from accidental corruption by use of a protocol. You need to write 0x55 and 0xAA to special function register before writing to the EEPROM. I cannot remember the details off the top of my head. Look at the 16f88 data sheet, there are flowcharts and code samples that show you exactly what you should be doing. Read the explanation carefully. Regards Sergio Masci http://www.xcprod.com/titan/XCSB - optimising PIC compiler FREE for personal non-commercial use
Reply by ●November 13, 20042004-11-13
Sergio, Thanks for your reply. At the moment, I am only trying to read the data Eeprom. I started out this project trying to write to Eeprom, and that is where the procedure involving writing 0x55 and 0xAA that you refer to comes into play. I was unsuccessful getting my program to work writing Eeprom, so decided to start at the beginning and try to get the simpler process of reading Eeprom to work first then I'd move onto writing. As far as I understand the datasheet, I have followed its instructions accurately for writing to Eeprom - the main bit of the code I use is taken directly from the datasheet. My suspicion was that my problems were caused by some kind of memory bank issue, but I've looked into every angle that I could think of and am still stuck. I think I must have overlooked something obvious. Any more ideas? Thanks, Simon. "Sergio Masci" <sergio@NO.SPAM.xcprod.com> wrote in message news:<41965207$0$1158$db0fefd9@news.zen.co.uk>...> Hi Simon, > > The data EEPROM is protected from accidental corruption by use of a > protocol. You need to write 0x55 and 0xAA to special function register > before writing to the EEPROM. I cannot remember the details off the top of > my head. Look at the 16f88 data sheet, there are flowcharts and code samples > that show you exactly what you should be doing. Read the explanation > carefully. > > Regards > Sergio Masci > > http://www.xcprod.com/titan/XCSB - optimising PIC compiler > FREE for personal non-commercial use
Reply by ●November 13, 20042004-11-13
>I was unsuccessful getting my program to work writing Eeprom, so >decided to start at the beginning and try to get the simpler process >of reading Eeprom to work first then I'd move onto writing.If your write was unsuccessful, why do you expect to read BB from that EEPROM location? If the write failed, you probably would get FF when you read. I didn't see anything wrong with your read code except for your substituting "mowlf count1" with "movwlf H'20'". That smacks of voodoo programming where you don't understand what is heppening and you are just guessing at what is causing problems. If you look at the code generated for the instruction (listing or in a debugger/simulator) then you could see if using the symbol count1 was loading the correct value into W. It's been a while since I used PIC assembly, but is cblok the right directive to use for allocating EEPROM memory?
Reply by ●November 14, 20042004-11-14
>I have used the sample code from Microchip's datasheet.I missed reading that you were using the simulator already. I assume you changed the EEPROM location in MPLAB before running your program. The code you pasted into your original message didn't assemble correctly for me. The __config statements had to be commented out as they seem to belong to a PIC18. I set the config bits using MPLAB's menu instead. The code worked for me. Are you sure you are looking at the right window for the result? You should be looking at the FILE REGISTERS window, not the EEPROM window.
Reply by ●November 14, 20042004-11-14
Hi Gary, Thanks for your reply. Sorry if I wasn't clear but when I said my program that wrote to EEPROM was was unsuccessful, I meant an earlier program that uses the procedure outlined in the 16F88 datasheet - uses EEADR EEDATA and EECON registers. The code that I posted in my original message simply writes the value BB with MOVLW, MOVWF instructions and there is no problem with this. In the simulator, you see 'BB' appear as the value in count1. The reason had I replaced Microchip's MOVF ADDR,W line with my own using movlw was because I had allocated ADDR a location in bank0 (using the cblock directive). However I have now tweaked the code - ADDR is located at 110 which is the same bank as EEADR so I can leave Microchip's code completely unaltered. You're right, I was trying voodoo to make my program work - I had tried everything logical I could think of but without success. Hence why I am posting here. And yes as far as I know I am using CBLOCK correctly. (From the MPASM manual:> Use this directive in place of or in addition to the equ directive. When creating non-relocatable (absolute) code, cblock is often used to define variable address location names. Do not use cblock or equ to define variable location names for relocatable code. )Have I understood this correctly? In the watch window, the count1 register shows its address as 0020, as expected. If anyone else thinks the code looks OK, I'd be very grateful if you could try assembling it and stepping through the simulator - see if you get the same issue that I have. Thank you. So here is the second version of the code, with the unedited version of Microchip's code to read the EEPROM ... LIST N=90,ST=OFF,p=16F88 INCLUDE P16f88.INC ;Register definitions errorlevel 0,-302 __config _config1, _hs_osc & _wdt_off & _pwrte_on & _cp_off & _boden_off & _CCP1_RB0 & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF __config _config2, _IESO_ON & _FCMEN_ON cblock h'20' ; count1 count2 endc cblock h'110' ; I have put this register at 110 ADDR ; so that it is in the same bank as endc ; the EEADR SFR. ; So that I can leave the Microchip code exactly ; unchanged GOTO INITIALISE NOP NOP NOP INITIALISE banksel eedata ; Clearing these registers first to make it ; easier to spot changes in Watch Window clrf eedata clrf eeadr clrf addr banksel count1 clrf count1 clrf count2 movlw h'BB' ; Put value 'BB' in count1 movwf count1 ; this appears successfully in watch window movlw count1 ; Move the location of count1 to W banksel addr ; (appears in watch as h'20' as expected) movwf addr ; and put that value in the ADDR register read_eeprom ; This section of code taken from 16F88 datasheet BANKSEL EEADR ; Select Bank of EEADR MOVF ADDR,W ; MOVWF EEADR ; Data Memory Address to read ; In watch window, EEADR succesfully contains ; h'20' at this point BANKSEL EECON1 ; Select Bank of EECON1 BCF EECON1,EEPGD ; Point to Data memory BSF EECON1,RD ; EE Read BANKSEL EEDATA ; Select Bank of EEDATA ; In watch window, at this point, the value ; of EEDATA changes to h'FF' MOVF EEDATA,W ; W = EEDATA ; check to see if data read successful banksel count2 movwf count2 ; move the data value to count2 goto $ end garykato@aol.com (Gary Kato) wrote in message news:<20041113214939.07586.00000665@mb-m01.aol.com>...> >I was unsuccessful getting my program to work writing Eeprom, so > >decided to start at the beginning and try to get the simpler process > >of reading Eeprom to work first then I'd move onto writing. > > If your write was unsuccessful, why do you expect to read BB from that EEPROM > location? If the write failed, you probably would get FF when you read. I > didn't see anything wrong with your read code except for your substituting > "mowlf count1" with "movwlf H'20'". That smacks of voodoo programming where you > don't understand what is heppening and you are just guessing at what is causing > problems. If you look at the code generated for the instruction (listing or in > a debugger/simulator) then you could see if using the symbol count1 was loading > the correct value into W. > > It's been a while since I used PIC assembly, but is cblok the right directive > to use for allocating EEPROM memory?
Reply by ●November 14, 20042004-11-14
I think you are confusing EEPROM with the File Registers. Their adresses overlap each other. When you do this: movlw h'BB' movwf count1 You are moving BB into the File Register at location 20. This is not altering EEPROM which can only be addressed using the EEADR register. When you read from EEPROM location 20, this is a different place than File Register location 20. This is why you get FF instead of BB. You can change the values in simulated EEPROM by using the EEPROM window. In MPLAB, look under the View menu and you will see EEPROM. This will open a window showing you what is in the EEPROM. This will initially be all FF. If you run your code to read_eeprom, you will see that address 20 in the File Register window will change to BB, but address 20 in the EEPROM window will not change. Click on address 20 in the EEPROM window and you can manually change the value. You will then find that your EEPROM read code will work.
Reply by ●November 14, 20042004-11-14
Gary Kato <garykato@aol.com> wrote in message news:20041114055727.07087.00000593@mb-m10.aol.com...> I think you are confusing EEPROM with the File Registers. Their adresses > overlap each other. When you do this: > > movlw h'BB' > movwf count1 > > You are moving BB into the File Register at location 20. This is notaltering> EEPROM which can only be addressed using the EEADR register. > > When you read from EEPROM location 20, this is a different place than File > Register location 20. This is why you get FF instead of BB. > > You can change the values in simulated EEPROM by using the EEPROM window.In> MPLAB, look under the View menu and you will see EEPROM. This will open a > window showing you what is in the EEPROM. This will initially be all FF.If you> run your code to read_eeprom, you will see that address 20 in the FileRegister> window will change to BB, but address 20 in the EEPROM window will notchange.> Click on address 20 in the EEPROM window and you can manually change thevalue.> You will then find that your EEPROM read code will work.I think Gary has nailed this. Think about it this way: you have 368 bytes of RAM on the 16f88, you also have 256 bytes of data EEPROM which are seperate to your RAM. If you write to address $20 in RAM it goes to RAM and not to EEPROM, if you write to address $20 in EEPROM it goes to EEPROM and not to RAM. Address $20 is a different location for both devices. Regards Sergio Masci
Reply by ●November 14, 20042004-11-14
You're absolutely correct - I was confused between EEPROM and general purpose registers. I thought they were one and the same thing. So thank you for your help. I have now got the EEPROM read and write working 100%. I have also now realised that the task I originally set out to do is much simpler than I thought - I should have read up on "Indirect Addressing, INDF and FSR Registers" in the first place. Still it's all useful stuff to be learning. Best wishes, Simon. p.s. Incidentally I was also puzzled by the __config directive of the 16F88 - apparently it has 2 config words unlike most of the PIC16X series that only have one. When I first started using the 16F88, my single line __config directive gave an error (Argument out of range (not a valid config register address)). So I had a look at the p16f88.inc file in the MPCHIP_Tools folder and looked at the MPLAB help file. So now I use the format: __config _config1, _hs_osc...... __config _config2, _IESO_ON & ....... Although the MPASM help file only explicitly says that is necessary on the PIC18C devices. Anyway, it works for me that way! garykato@aol.com (Gary Kato) wrote in message news:<20041114055727.07087.00000593@mb-m10.aol.com>...> I think you are confusing EEPROM with the File Registers. Their adresses > overlap each other. When you do this: > > movlw h'BB' > movwf count1 > > You are moving BB into the File Register at location 20. This is not altering > EEPROM which can only be addressed using the EEADR register. > > When you read from EEPROM location 20, this is a different place than File > Register location 20. This is why you get FF instead of BB. > > You can change the values in simulated EEPROM by using the EEPROM window. In > MPLAB, look under the View menu and you will see EEPROM. This will open a > window showing you what is in the EEPROM. This will initially be all FF. If you > run your code to read_eeprom, you will see that address 20 in the File Register > window will change to BB, but address 20 in the EEPROM window will not change. > Click on address 20 in the EEPROM window and you can manually change the value. > You will then find that your EEPROM read code will work.
Reply by ●November 14, 20042004-11-14
>p.s. Incidentally I was also puzzled by the __config directive of the >16F88 - apparently it has 2 config words unlike most of the PIC16X >series that only have one. >When I first started using the 16F88, my >single line __config directive gave an error (Argument out of range >(not a valid config register address)). So I had a look at the >p16f88.inc file in the MPCHIP_Tools folder and looked at the MPLAB >help file. So now I use the format: >__config _config1, _hs_osc...... >__config _config2, _IESO_ON & ....... >Although the MPASM help file only explicitly says that is necessary on >the PIC18C devices. >Anyway, it works for me that way!Ah. You must have turned off case sensitivity. I still have that on, so the config statements gave me errors. I then set the config options using the Configure->Configuration Bits menu item in MPLAB. It is better to have the bits specified in the source code so that there can be a record of it on printouts in case your PC crashes and burns.