I read it again to confirm this, the attachment is my source. It also mentions 9 bits long address. Not sure who sends an ack. I see that in read statement the device send ack, so why add it to the address PIC is sending. Very confusing.
I read it again to confirm this, the attachment is my source. It also mentions 9 bits long address. Not sure who sends an ack. I see that in read statement the device send ack, so why add it to the address PIC is sending. Very confusing.
Ahhhh... okay
Let's use this info then. Looks like the address is using bits 1~7 and the Read/Write control bit is 0.
If control bit is set (=1) then Read, if bit cleared (=0) then Write
So:
%00110111 = $37 ' Read function
%00110110 = $36 ' Write function
Try that.
By the way, the device sends the ACK, or acknowledges, by holding the Data line LOW on the 9th clock cycle. The PIC will see this and continue to send data.
Louie
How do I implement this, like this below?
Code:Main: High Led : Pause 500: Low Led : PAUSE 500 Addr=$36 I2CWRITE SDA,SCL,ADDR,LOC Addr=$37 : pause 10 ' OR If SDA=1 then main I2CREAD SDA,SCL,loc,[VALUE],Fail PAUSE 25 DEBUG HEX Value,13,10 PAUSE 250 DEBUG "Done....",13,10 WHILE 1 : WEND Goto Main Fail: toggle portc.2 goto main
Just notice the address missing on the Read function.
Moved the Fail label after Write to test this part first. This will let you know if the Write address was recognized so the Pause 10 is not needed.
Code:Main: High Led : Pause 500: Low Led : PAUSE 500 Addr=$36 I2CWRITE SDA,SCL,ADDR,LOC, Fail ' Test here first Addr=$37 ': pause 10 ' OR If SDA=1 then main I2CREAD SDA,SCL,ADDR,loc,[VALUE] ',Fail PAUSE 25 DEBUG HEX Value,13,10 PAUSE 250 DEBUG "Done....",13,10 WHILE 1 : WEND Goto Main Fail: toggle portc.2 goto main
Louie
Checked it. It fails on the first write statement.
Fails on the second statement if I swap the values of Addr. i.e. First $37, second Addr $36. First one goes fine.
Okay let's fix that first.Checked it. It fails on the first write statement.
Put brackets around the Loc as shown in the PBP manual to see if that helps.
Code:Main: High Led : Pause 500: Low Led : PAUSE 500 Addr=$36 I2CWRITE SDA,SCL,ADDR,[LOC],Fail ' Test here first Addr=$37 ': pause 10 ' OR If SDA=1 then main I2CREAD SDA,SCL,ADDR,[LOC,VALUE] ',Fail PAUSE 25 DEBUG HEX Value,13,10 PAUSE 250 DEBUG "Done....",13,10 WHILE 1 : WEND Goto Main Fail: toggle portc.2 goto main
Last edited by LinkMTech; - 27th July 2013 at 19:56. Reason: Reply timing!
Louie
I did exactly the same as above and the sequence completed fine. BUT the values are not consistent with the datasheet, I should get '$2E' from location 0, but WHATEVER location I try to read, I am getting '$FF'
I just discovered, that the I am actually receiving only 1 byte as expected. Rest are just "Start......"13,10 and "Done",13,10. Yesterday got too exhausted and missed this mistake of mine.
Here is the current code withEvery time Change line goes low (detected something), I try to read first 4 memory locations. The communication fails a lot of times (both write and read (write more than read) )in this attempt but I do get the data on the screen finally. Secondly, the data which comes is wrong. For example, memory locations 0 does not read 2E for a start.Code:Start: Loc=0 Start_Again: I2CWRITE SDA,SCL,$36,[LOC],Fail1 Main: Value=0 High Led : Pause 500: Low Led : PAUSE 500 I2CREAD SDA,SCL,$37,[VALUE] ,Fail2 PAUSE 250 DEBUG Value Loc=Loc+1 If Loc<4 then Start_Again ' Read first 4 locations x=0 WHILE !Change ' Stay here if Change Stays High Pause 500 : x=x+1 If x =10 then LOC=3 : Goto Main ' Do another read Endif WEND while Change : pause 100 : wend ' Stay here if change is Low Goto Start Fail1: ' Try Write again For x=0 to 50 High Portc.2 : Pause 50 : Low PortC.2 : Pause 50 Next x Goto Start_again Fail2: ' Try read again For x=0 to 5 High Portc.2 : Pause 250 : Low PortC.2 : Pause 250 Next x Goto Main
Success but with one question.
Finally, I put 20MHz clock. It started working with absolutely no problems.
This leaves me with one MAJOR question - Is there any way, I can run the whole show at 4MHz, any settings I missed or anything I can do. I have got no extra pins on my PIC to put an external oscillator, I want to confirm the answer to this question before I start again and choose another suitable PIC. My task will get much much easier if there is a way to run it at 4 Sweet Megahertz.
Many many many thanks to you guys for trying to helping me out on this. This forum is the best.
16F688 can go up to 8MHz on internal oscillator.
I'd try that before changing PIC.
Robert
I put a test circuit together on my LAB-X4 using the PIC16F688 to talk to a 128kB FRAM.
I could feel your pain when trying to make your test program work so decided to start from almost scratch.
The TRIS statements were missing some bit assignments which are not a good thing, from what I read somewhere here by Henrik Olssen, so I put them in.
The order of CONFIG's and other setups were rearranged as well. Not really sure which fixed it but,
The end results were that it works at 4MHz and here's the program to compare with.
Code:' ' This setup uses a PIC16F688 and a FM24V01, 128kB Nonvolatile RAM to test ' the I2CREAD/WRITE functions at 4MHz. ' ' First: The FRAM memory is loaded with values 1~5 starting from ' location 0 using Word size address. The values written are sequentially ' loaded into the next memory location, so only the starting address is ' needed for this test. ' Read address = $A0 ' Write address = $A1 ' ' Second: The FRAM memory locations 0 thru 4 are READ in a loop then stops ' and waits the Test button on the LAB-4X to be pushed and repeats. ' ' The data was monitored with the Saleae Logic scope. ' Max clock speed measured at 4Mhz was 29kHz ' ' The DEBUG function was not used during this test '**************************************************************** #CONFIG ifdef PM_USED device pic16F688, intrc_osc_noclkout, wdt_on, mclr_on, protect_off else __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _IESO_OFF & _FCMEN_OFF endif #ENDCONFIG '----------------------------------------------------- PORTA=0 PORTC=0 TRISA = %00001000 ' All 8 bits assigned one way or the other TRISC = %00000000 ' All 8 bits assigned one way or the other CMCON0 = 7 ANSEL = 0 OPTION_REG = 128 ' PORTA pullups disabled INTCON=128 OSCCON = %01100001 ' Oscillator set to 4MHz DEFINE DEBUG_REG PORTC DEFINE DEBUG_BIT 3 DEFINE DEBUG_BAUD 2400 DEFINE DEBUG_MODE 1 DEFINE OSC 4 Include "modedefs.bas" '----------------------------------------------------------- Value VAR BYTE WR_Addr VAR BYTE RD_Addr VAR BYTE LOC VAR WORD ' FRAM address must be sent as Word size x VAR BYTE '------------------------------------------------------------ SCL VAR PORTA.4 ' RA4, pin #3 SDA VAR PORTA.5 ' RA5, pin #2 Change VAR PORTA.3 ' Push button on LAB-X4 LED VAR PORTA.0 ' Test LED. LOW = ON '------------------------------------------------------------ LOC = 0 ' Start at 0 LED = 1 ' Turn LED OFF PAUSE 1000 ' Give me a chance to start the monitor GOSUB Load_Mem ' Load FRAM memory locations 0~4 with values 1~5 Main: FOR LOC = 0 TO 4 LED = 0 ' Turn ON LED, scope monitored I2CWRITE SDA,SCL,$A0,[LOC],Fail1 PAUSEUS 25 ' Paused to see on display I2CREAD SDA,SCL,$A1,[VALUE],Fail2 PAUSEUS 500 ' Paused to seperate packets, viewing purpose only LED =1 ' Turn OFF LED NEXT LOC WHILE CHange: WEND ' Wait until button pushed PAUSE 500 ' Cheap debounce GOTO Main '----------------------- Fail routines ------------------------------- Fail1: ' Try Write again FOR x=0 to 50 LOW LED : PAUSE 50 : HIGH LED : PAUSE 50 Next x GOTO Main Fail2: ' Try read again For x=0 to 5 LOW LED : PAUSE 250 : HIGH LED : PAUSE 250 Next x GOTO Main '---------------------- Load FRAM -------------------------------------- Load_Mem: LED = 0 ' Turn ON LED, scope monitored I2CWRITE SDA,SCL,$A0,[LOC,1,2,3,4,5],Fail1 LED = 1 ' Turn OFF LED RETURN END
This first screenshot is from:
The 2nd and 3rd from the first and last loop Reads showing the values 1 and 5 after the $A1 READ address.Code:Load_Mem: LED = 0 ' Turn ON LED, scope monitored I2CWRITE SDA,SCL,$A0,[LOC,1,2,3,4,5],Fail1 LED = 1 ' Turn OFF LED RETURN
Louie
Bookmarks