Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Inquiry

Status
Not open for further replies.

YAN-1

New Member
Hello. I have a question. If I am to have a 16F877 communicate with several PICs through the I2C module AND communicate with a PC through the RS232 using the USART module at the same time, all while executing a certain program, will there be a problem? I mean if I use the available interrupts to acknowledge the recieving processes and buffer status, overflow issues,..... will the 2 modules be able to operate simultaneously from their hardware modules without any problems while executing another program and just recieving and sending whenever the programs requires it? Thanks.
 
Serial UART and I2C are separate hardware resources and do not conflict.
UART interrupts must be serviced in a finite amount of time. I2C does not have to have its interrupts serviced in any definite period of time as long as you didn't write a short "timeout" onto the other device's software.

You only need to be sure the ISRs aren't so lengthy that a UART interrupt could be missed before the previous instance is serviced, i.e. an overrun.
 
Because PICs have a Buffered USART (2~3 bytes), it is not critical, so you can "mis" two Interrupts from USART and it will still work.
 
I see. Thank you. I also have another question. I am using a 20 MHz crystal and I want to set the bit rate of the I2C module to 400 KHz. The value I should place in the SSPADD register should equal:
((Fosc/bit rate)/4) - 1
When calculated, it is 11.5. How do I write this decimal number in the 8-bit register?!
 
YAN-1 said:
I see. Thank you. I also have another question. I am using a 20 MHz crystal and I want to set the bit rate of the I2C module to 400 KHz. The value I should place in the SSPADD register should equal:
((Fosc/bit rate)/4) - 1
When calculated, it is 11.5. How do I write this decimal number in the 8-bit register?!
Asuming that your calculation and formula is ok, you have to round this number (and except certain error), so enter either 11 or 12...
 
Or use a crystal of higher or lower frequency which gives you a nice integer for the required data.
 
eblc1388 said:
Or use a crystal of higher or lower frequency which gives you a nice integer for the required data.
Becuase 20Mhz is a maximum for 16F877, only lower frequency would produce a nice result.
 
You do not need to go very high to get an integer.

Using the same formula, one only need to use a 20.8MHz crystal to get a nice "12" for setting up the register.

Would you consider 20.8MHz pushing the PIC a bit hard? I would say it is fine. However, I would definitely do not advise others to use crystal like 24 or 30MHz.
 
eblc1388 said:
You do not need to go very high to get an integer.

Using the same formula, one only need to use a 20.8MHz crystal to get a nice "12" for setting up the register.

Would you consider 20.8MHz pushing the PIC a bit hard? I would say it is fine. However, I would definitely do not advise others to use crystal like 24 or 30MHz.
20.8 is fine (I though you wanted to overclock it much higher then that), but keep in mind it might interfere with some time critical code...
 
Jay.slovak said:
... but keep in mind it might interfere with some time critical code...

Do you think one can program a PIC to find out what crystal frequency it is operating on and so to adjust the timing of critical code.

So a simple LED blinker would blink with the same period no matter what crystal you give it.

I think it is impossible for a PIC to find that out without external circuitry. But the external circuit can be as simple as a R and C combination on an input pin which can also be used for sensing keypress. The R is already there so you just need an extra small capacitor. I'll work on that.
 
I suspect you'll find that integer 11 or integer 12 will work just fine for 400-KHz operation using your 20-MHz crystal...

I accidentally forgot to subtract the one at the end of that formula and used the value 13 on a 20-MHz 18F258 project with a 24LC256 device and it worked fine... I ended up using the value 12 because I thought it was probably better to run the I2C at slightly slower than 400-KHz instead of slightly faster...

Good luck with your project... Regards, Mike
 
YAN-1 said:
I see. Thank you. I also have another question. I am using a 20 MHz crystal and I want to set the bit rate of the I2C module to 400 KHz. The value I should place in the SSPADD register should equal:
((Fosc/bit rate)/4) - 1
When calculated, it is 11.5. How do I write this decimal number in the 8-bit register?!

You can round. Now 3 things here- the PIC is overbuilt for I2C spec and there's probably no problem operating a few percent over 400KHz.
Second, I2C freq is determined by the master so selecting a nonspecified freq- 363.1221324KHz- is no problem at all for any I2C slave.
The final thing here is be sure to evaluate your bitrate needs. 400KHz can do a lot, so you might want to see what you even need. This is important for running extra-long I2C wires between 2 PICs.
 
eblc1388 said:
Jay.slovak said:
... but keep in mind it might interfere with some time critical code...

Do you think one can program a PIC to find out what crystal frequency it is operating on and so to adjust the timing of critical code.

So a simple LED blinker would blink with the same period no matter what crystal you give it.

I think it is impossible for a PIC to find that out without external circuitry. But the external circuit can be as simple as a R and C combination on an input pin which can also be used for sensing keypress. The R is already there so you just need an extra small capacitor. I'll work on that.
I was thinking about that too. Maybe if you connect 32768Hz crystal to T1 oscilator... but this is a waste of 2 I/Os and one crystal...
 
Oznog said:
You can round. Now 3 things here- the PIC is overbuilt for I2C spec and there's probably no problem operating a few percent over 400KHz.
Second, I2C freq is determined by the master so selecting a nonspecified freq- 363.1221324KHz- is no problem at all for any I2C slave.

Perhaps a fourth thing?, perhaps so obvious no one has bothered mentioning it yet? - but the 400KHz is the MAXIMUM specified operating frequency - you can use anything you want lower than that, no need to run anywhere near 400KHz unless you need maximum possible speed?.

Wasn't the original I2C spec only 100KHz, and the 400KHz is an updated version with the speed increased?, only available on some devices.

If you ever scope an I2C rail where it was designed for (Inter IC communication in TV sets), you will see that it doesn't usually run anywhere near the 100Khz original spec.
 
Hmmm.. I see. Thanks everyone. Another question if I may. How can I send numbers like 13.567 or 350.98 or 0.1325 ...etc through either the UART or the I2C or the PSP? Should I send the integer part alone and then the fraction and then join them back at the receiver end?
 
YAN-1 said:
Hmmm.. I see. Thanks everyone. Another question if I may. How can I send numbers like 13.567 or 350.98 or 0.1325 ...etc through either the UART or the I2C or the PSP? Should I send the integer part alone and then the fraction and then join them back at the receiver end?
it depends if you want to proces it or just dispaly it on the other end. For displaying only, send all digits in separate bytes 13.567 => <1> <3> <.> <5> <6> <7>. this is very simple...
 
Actually no. I don't need to display it. Just process it. I guess I'll end up sending the integer part and the fraction separately.
 
YAN-1 said:
Actually no. I don't need to display it. Just process it. I guess I'll end up sending the integer part and the fraction separately.

You need to think carefully what you are doing, and why!. There's rarely any need to use floating point numbers, and it's always best to avoid them, as they are a GREAT deal slower than integers, and also lack accuracy.

A little bit of thought before you start often removes any requirement for them, for example if you were doing calculations using money, you wouldn't EVER use floating point (spreadsheets don't!).

So rather than $23.49, you would use 2349 cents, simply shift the decimal point, this is known as scaling - by using integer values it keeps the maths exactly correct, and avoids a bill for $23.4876487624387556 - which is inaccurate, and looks absolutely horrible!.

If you need to display a decimal point, you simply insert it in the display routines!.

So if you're displaying voltages?, don't store as 5.60V, but use 5600mV instead!.

Bear in mind, your variables should be stored as binary numbers, so two bytes gives up to 65535, and 4 bytes gives up to 4294967295, 16 bit and 32 bit precision respectively.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top