Software I2C for EEPROM using PIC18F4620 - Page 1
Forum section: electronics / general

author: yashrk
author_rank: Frequent Contributor
timestamp: June 06, 2016, 09:00:41 am
content: Hey Guys,I am currently working on a project involving PIC18F4620, there I have to add an EEPROM (24FC64C) but I cannot use the hardware serial so I am trying to find some reference to for software serial but I cannot find any specific library that works with PIC18 series.I have found this (http://ww1.microchip.com/downloads/cn/AppNotes/cn560799.pdf) Application Note from microchip but the code uses PIC16_I2C_BITBANG.h and they have mentioned it will work with PIC16 and PIC12. I have to use RD0 and RD1 for communication. And if we find one how do I specify the communication frequency or baud rate.I am using MPLAB X v3.30 with XC8 compiler.Thank youguys in advance,Yash.

author: JPortici
author_rank: Super Contributor
timestamp: June 06, 2016, 09:41:07 am
content: Have you at least gave a quick look at the source code? there is literally nothing that prevents you to use it on a pic18.QuoteCode:* All timings assume a 10 MHz crystal oscillator is used. If a* different crystal frequency is desired, care must be taken to* avoid violating device timing specs.If your frequency is higher you might have to modify the library and add some NOPs here and there to slow things down

author: Kjelt
author_rank: Super Contributor
timestamp: June 06, 2016, 09:45:58 am
content: I don't know much about Microchip but reading that document it states at the last page:QuoteSo it is even tested on a PIC18, what was your question again

author: yashrk
author_rank: Frequent Contributor
timestamp: June 06, 2016, 09:48:53 am
content: Yes, I read the code and I am trying it now but I thought that there may be available something for PIC18 that I am missing.And can you tell me how do I set frequency or baud rate my micro is running at 40MHz? I have to run EEPROM at <1MHz.

author: Kjelt
author_rank: Super Contributor
timestamp: June 06, 2016, 10:15:25 am
content: Quote from: yashrk on June 06, 2016, 09:48:53 amI never looked at the code before so this is with a large grain of salt but if this is the code to shift a bit out on the i2c busCode:void bit_out(unsigned char data){unsigned int i;SCL = 0; // ensure SCL is lowSDA_TRIS=0; // configure SDA as an outputSDA= (data>>7); // output the MSBfor (i=0;i<2;i++) NOP();SCL = 1; // pull SCL high to clock bitfor (i=0;i<3;i++) NOP();SCL = 0; // pull SCL low for next bit}Then you can count the speed by looking up the nr of cycles each of the instructions will take, but easier (quicker) to hookup an oscilloscope and measure the bit time.If you need a slower bit time then you can do it the quick and dirty way by adding more NOP statements in the for (i=0;i<2;i++) NOP(); loop so actually changing the i<x where x is the amount needed to slow it down.Be sure to keep it 50% DC though, so both delay loops need to be equal or if you need a real slow bus by adding your interrupt service routine to some hardware timer you programmed (not sure if you have a hardware timer left) or even more slow a software timer.But as I said I am not a Microchip programmer so maybe ask someone else.

author: JPortici
author_rank: Super Contributor
timestamp: June 06, 2016, 10:25:53 am
content: on PIC16_I2C_BITBANG.h you have the defines for the pins and tris bits, change them accordinglyon PIC16_I2C_BITBANG.c, for example in bit_outCode:void bit_out(unsigned char data){unsigned int i;SCL = 0; // ensure SCL is lowSDA_TRIS=0; // configure SDA as an outputSDA= (data>>7); // output the MSBfor (i=0;i<2;i++) NOP();SCL = 1; // pull SCL high to clock bitfor (i=0;i<3;i++) NOP();SCL = 0; // pull SCL low for next bit}the for cycles that excecute NOPs will define the baud rate. hook up an oscilloscope and adjust the values until you achieve the desired baud rate

author: dannyf
author_rank: Super Contributor
timestamp: June 06, 2016, 10:55:27 am
content: "SDA= (data>>7); // output the MSBfor (i=0;i<2;i++) NOP();"Don't see terribly efficient.Sounds like it is outputig thee bits through the data register. Not as reliable as through the direction register, especially on fast chips without the output latch registers.

author: JPortici
author_rank: Super Contributor
timestamp: June 06, 2016, 11:16:11 am
content: the op wants it to be run at 1MHz max.. i assume that it doesn't need to be so efficient.maybe it could be all timer-based so you don't have to waste a ton of time doing nothing but that's up to him to write a specific routine for this specific applicationCode:#define SDA_TRIS TRISCbits.TRISC4#define SCL_TRIS TRISCbits.TRISC3#define SDA PORTCbits.RC4#define SCL PORTCbits.RC3the compiler will translate a write operation into a BSF or BCF instruction to the defined PORT pin

author: dannyf
author_rank: Super Contributor
timestamp: June 06, 2016, 11:30:18 am
content: A setter aoproag iss to turn the SDA scll pins to input and output a zero on them.When you want to set a pin, turn it's direction bit to input. The bus gets pulled up by thee resistor.When you want to clear a bin, turn it's direction bit to output. The bus gets pulled down.Quasi open draiin output.Thee microchip approach of outputig bits through the data regussterbis really non i2c compliant.

author: Kjelt
author_rank: Super Contributor
timestamp: June 06, 2016, 11:42:43 am
content: Besides that come to think of it who thinks of creating a bit_out function with a unsigned char as inputOr document which bit is the one shifting out but better to make it a boolean or restrict the input char to 0 or !0 (so any value not 0 is always 1).If you always have to shift a whole byte out I would just create a byte_out function instead.

author: yashrk
author_rank: Frequent Contributor
timestamp: June 07, 2016, 11:20:49 am
content: Sorry guys my bad I messed up in library includes. Thank you all.

author: JPortici
author_rank: Super Contributor
timestamp: June 07, 2016, 12:01:06 pm
content: Quote from: Kjelt on June 06, 2016, 11:42:43 amif you take a look at the whole library you'll the i2c transmission routine will indeed transmit a byte.. by performing 8 bit_out

author: Kjelt
author_rank: Super Contributor
timestamp: June 07, 2016, 12:40:16 pm
content: Quote from: JPortici on June 07, 2016, 12:01:06 pmYes I saw that still weird to use it that way don't you think?

author: JPortici
author_rank: Super Contributor
timestamp: June 07, 2016, 01:17:30 pm
content: i suppose. A for cycle likeCode:for (i=0;i<7;i++) {SCL = 0;if(data > 127)SDA = 1;elseSDA = 0;[...]handle the clock[...]data <<= 1;}should be more efficient