8 bit communication between AVR using TWI

Go To Last Post
41 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've two AVRs (both are Atm8535) for my robot.
I need a fast protocol to communicate between them.
since 10 pins are free on each, i could use TWI (Ten Wire Interface) :D, just to speed up data transfer
since 7 ultrasonics & electric compass are assigned to the slave

It's so confused to implement the handshaking. Is there anyone implemented this before? or is it possible to modify some I2C / TWI routine available here?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SPI is also a "nice and easy" communcation for a couple of AVRs in close proximity.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
I need a fast protocol to communicate between them.

what fast have to be the protocol ?

Guderian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

rasto_novak wrote:

I need a fast protocol to communicate between them.

what fast have to be the protocol ?

It should be 1 - 2 Mbps.
I've used USART before, since my target board uses 4 MHz crystal, i set baud rate to 9600bps and set U2X to enhance transfer rate. But this setting will give 0.2% error. The data being transfered consists 7 byte & i dont want to lose 1 bit.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
But this setting will give 0.2% error.

I think that you are misunderstanding what this value means. It does not mean "0.2 % of the time there will be an error". It means that the baud rate is off by 0.2%. This is a very different thing. UARTs are tolerant of baud rate errors up to 2.0%, so 0.2% shouldn't cause you any problems. But for short distances such as this TWI (two wire interface), or SPI might still be a better choice. Or you could use an entire 8 bit port for data and another pin as a strobe/latch signal (and one more pin to indicate direction if you need bi-directional).

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've done almost exactly what you're trying to do. First off, with both micros running at the same frequency (4mhz), there is no baudrate error between the 2 micros, so set the UBRR to 1 and run 115.2K. That 8.5% error will only occur if you try to communicate with another device like a PC, that's using standard baudrates and standard frequencies.

Here's the maze runner I did that with http://www.parex.org/parex_autoe...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dksmall wrote:
First off, with both micros running at the same frequency (4mhz), there is no baudrate error between the 2 micros, so set the UBRR to 1 and run 115.2K.
That's not entirely correct. There will be some baud rate error since the two micros are not running at exactly 4 MHz. If they're running on external crystals or resonators, for example, the baud rate error is insignificant. However, if either is running on the internal RC oscillator, the baud rate error can be significant.

Don

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

donblake wrote:
dksmall wrote:
First off, with both micros running at the same frequency (4mhz), there is no baudrate error between the 2 micros, so set the UBRR to 1 and run 115.2K.
That's not entirely correct. There will be some baud rate error since the two micros are not running at exactly 4 MHz. If they're running on external crystals or resonators, for example, the baud rate error is insignificant. However, if either is running on the internal RC oscillator, the baud rate error can be significant.

Don

This is true, I was thinking external resonators, since that's what I did.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gedex wrote:
It should be 1 - 2 Mbps.

well you won't get that rate with the AVR's TWI hardware, and you certainly won't get there through a bit banged solution either. SPI is probably your bst option here, and the implementation is quite straight forward.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
since 10 pins are free on each, i could use TWI (Ten Wire Interface) Very Happy, just to speed up data transfer

I think you were joking about TWI being a 10 wire interface, but if you do have 10 free pins on each micro, why not use a 4 or 8-bit dbi-directional interface between the two? A 4-bit interface shouldn't be too difficult. An 8-bit bi-directional interface with 2 control lines is a bit more challenging. If the 10 free pins include the SPI pins then you could always drop back to that if you decide you don't want to continue working on the parallel interface.

SPI would be easier than TWI, but a parallel interface would be more interesting to implement.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

zoomcityzoom wrote:
Quote:
since 10 pins are free on each, i could use TWI (Ten Wire Interface) Very Happy, just to speed up data transfer

I think you were joking about TWI being a 10 wire interface,

Hint, what if that was a binary number?

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Doh!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

It's so confused to implement the handshaking.

Quote:

10 pins are free on each,

Confused is right. With a summary of above: "It will take some pins on each plus a bunch of stuff to implement a 'fast protocol'", why not do it on one AVR such as Mega640? [I'm guessing that A/D channels are the limiting factor.]

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gedex wrote:
rasto_novak wrote:

I need a fast protocol to communicate between them.

what fast have to be the protocol ?

It should be 1 - 2 Mbps.
I've used USART before, since my target board uses 4 MHz crystal, i set baud rate to 9600bps and set U2X to enhance transfer rate. But this setting will give 0.2% error. The data being transfered consists 7 byte & i
dont want to lose 1 bit.

Note that the concept of error in this case is quite relative.

With a 4MHz oscillator, you can only get within 0.2% from exact 9600bps for PC communications, but with a 4MHz oscillator, you can make the two AVRs talk to eachoter with 0% error at least 250kbps, or 500kbps if you use the U2X feature.

The error only comes from the crystals, which should be less than 1000ppm (0.1%). You won't lose any bits, as anything less than 2% mismatch should be ok.

- Jani

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

glitch wrote:
zoomcityzoom wrote:
Quote:
since 10 pins are free on each, i could use TWI (Ten Wire Interface) Very Happy, just to speed up data transfer

I think you were joking about TWI being a 10 wire interface,

Hint, what if that was a binary number?

Another joke:

There are only 10 kinds of people. Those who understand binary numbers, and those who don't.

Actually I think I've seen this on a T-shirt somewhere or something.

- Jani

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jepael wrote:

Another joke:

There are only 10 kinds of people. Those who understand binary numbers, and those who don't.

Actually I think I've seen this on a T-shirt somewhere or something.

- Jani

I've got a 100 wheel drive car with 10 rear wheels and 10 front wheels.

Why don't you use USI?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm thinking of a 1000 cylinder 100 wheel drive track with 10 front wheels and 1 only driver!

Dentist has charged me for all my 100000 teeth!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

RES wrote:
Why don't you use USI?
FWIW, I just got slave TWI (I2C) working on a ATTiny2313 using USI. It's based on Atmel's AVR312 Application Note. I ported the code to WINAVR GCC, did some cleanup and fixed several errors. If anyone's interested, I can make it available.

Don

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

donblake wrote:
RES wrote:
Why don't you use USI?
FWIW, I just got slave TWI (I2C) working on a ATTiny2313 using USI. It's based on Atmel's AVR312 Application Note. I ported the code to WINAVR GCC, did some cleanup and fixed several errors. If anyone's interested, I can make it available.

Don

If you could post that, it would be great. I'm working on a similar project now. I have one master microcontroller, which I want to speak to three slave ones separately depending on the address. Right now I use an 8-bit bus, 3 address bits, and 2 control bits for a hand-shake, before realizing that TWI is probably the way to go.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SPI is more along the master/peripheral addressing scheme found in classic microprocessor architecture. You have an SS line which functions as a chip select for each SPI chip hooked to the master. That would allow you to keep your 3 address lines.

TWI is reliable (for me) using the TWI hardware, and questionably reliable with the USI hardware. Atmel is looking into this, I think.

TWI can be quite nice, but you need to put your own message protocol on top of it. TWI gives you the addressing capability of 128 possible addresses using the 7 bit addressing scheme, but certain addresses are reserved. You might want to look at the nxp (www.nxp.com) site for more information on addressing. I'd suggest at a minimum the combination of address/count/command/data with a possible return of count/status/data for each message.

Harvey

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

TWI hardware is limited to 400 Kbps so if you want 1-2 Mbps this is not an option...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ZachSt wrote:
If you could post that, it would be great. I'm working on a similar project now. I have one master microcontroller, which I want to speak to three slave ones separately depending on the address. Right now I use an 8-bit bus, 3 address bits, and 2 control bits for a hand-shake, before realizing that TWI is probably the way to go.
I've tried several times to add this code as an attachment - a small zip file. I've tried it from both Firefox an MS IE. It seems like attachments are broken.

Don

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thx for all recommendations.
i've decided to use UART, since it's easier to me (coz my project is near to deadline).
But if i've free time, i'll try TWI & SPI.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

donblake wrote:
I've tried several times to add this code as an attachment - a small zip file. I've tried it from both Firefox an MS IE. It seems like attachments are broken.
Hey - attachments are now working!
donblake wrote:
FWIW, I just got slave TWI (I2C) working on a ATTiny2313 using USI. It's based on Atmel's AVR312 Application Note. I ported the code to WINAVR GCC, did some cleanup and fixed several errors. If anyone's interested, I can make it available.

Here it is. I've tested slave receive but not slave transmit. Use at your own risk. Enjoy.

Don

[edit]
Code update: fixed ACK of slave address on a read.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

will that work with an at90s2313?

Thanks!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try a parallel version of I2C.

Use 8 bits for the data and the two remaining bits for handshaking signals. Start with one AVR as 'master' and one as 'slave' Set the eight port bits used as the data byte on the master as all outputs. Turn on the pull up resistors and set the master's two handshake bits as inputs. They will pull to logic high.
Start with the ten port bits on the slave as all inputs. Put a data byte on the master's data eight-bit data port pins. Make the master's NewDataReady handshake bit be an output and make it logic low. This signals to the slave that there is new data available. The slave reads the 8 data bits as a single input instruction, puts the data in SRAM or processes it. Then it makes the other handshake line an output and pulls it low.
The master sees the low from the slave and makes its active handshake line back into an input. It is pulled high by the internal resistor. The slave sees the master's active handshake line go high and returns its handshake line to an input, which makes it high. The master sees that the slave's handshake is high and puts the next byte onto the data lines. Then starts the process over.

Is this a bidirectional data transfer between the two AVRs? If so then maybe a standard SPI would be better, or even standard AVR I2C (TWI).

How fast is fast data transfer? Are you sending data in fixed length bursts? Or is the receiving AVR doing processing on each byte as it is received?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

xchip wrote:
will that work with an at90s2313?

Thanks!

I assume you are asking about Don Blake's USI_TWI code.

This will not work with the obsolete AT90S2313.
It will work with the current ATtiny2313.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ok thank you!!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

just wondering has any1 tested don's code to transmit date from the slave

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

has anybody implemented a 2-wire SPI in a PIC16F877A or in any microcontroller as the master?need some info for this because my slave IC which is an energy IC is configured as 2 wire SPI..all i need is to supply serial clock from the PIC to the slave so that i can get the data..the data comes from the slave..

is it possible that a PIC can be configured as 2 wire SPI using only the SCK and SDI pin?will the PIC(master) can still supply a serial clock if it is configured as 2 wire SPI?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please describe exactly what you want to do quoting part numbers. e.g. I want to control my type 'ABC123' energy IC made by Company123.inc with an Atmel ATmega88 or whatever.

I am not sure what 2-wire SPI is.
I know what a I2C protocol is.
I know what a PIC16F877A is. It can do I2C or 3-wire SPI or 4-wire SPI.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

i want to initiate a SPI communication between "PIC16F877A(master)" and "STPM01(slave)". the operation will be like this, the STPM01 will measure electrical energy consumption from the load and then store it in its embedded energy registers. when i want to get the energy data from STPM01, i must send serial clocks to it but instead of 3 wire SPI the STPM01 implements a 2 wire SPI, one for DATA pin and the other for serial CLOCK input..the master(PIC) will be the one initiating the clock..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

From a brief look at the STP01 data sheet, it does not really seem to behave like a regular I2C device.

So I would just stick with 4-wire SPI and be done with it.

The PIC18F877 has a MSSP module, and you configure it for SPI.

This is an Atmel site. All AVRs can do SPI. You will have a similar procedure to using the Microchip parts.

Google is your friend.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

as what i've understand, only two("SDAT" & "SCL")of the four pins of the STPM01's SPI module that will be connected to the SPI module of the PIC..the other two("SCS" & "SYN") will be connected to any general purpose I/O pin..because the "SCS" and "SYN" controls the function of the SDAT pin..the SDAT pin can be configured as input or outpin pin for data..so i think only the SDAT & SCL pin can be connected to the SPI module of the PIC(SDA & SCK)..because when the master sends serial clock to the slave, the data from the slave will be shifted to the master(PIC)..

i think a 2-wire SPI will be implemented in the PIC..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Section 9.1 of the PIC16F8X data sheet.

Quote:
The SPI mode allows 8 bits of data to be synchronously
transmitted and received simultaneously. All four
modes of SPI are supported. To accomplish communication,
typically three pins are used:
• Serial Data Out (SDO)
• Serial Data In (SDI)
• Serial Clock (SCK)
Additionally, a fourth pin may be used when in a Slave
mode of operation:
• Slave Select (SS)

I am sure that you can use the different modes of the STPM01. You have to read the STPM01 data sheet. It is easier to use the "standard" interface.

You can use the PIC MSSP in different modes too.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

donblake wrote:
Hey - attachments are now working!
donblake wrote:
FWIW, I just got slave TWI (I2C) working on a ATTiny2313 using USI. It's based on Atmel's AVR312 Application Note. I ported the code to WINAVR GCC, did some cleanup and fixed several errors. If anyone's interested, I can make it available.

Here it is. I've tested slave receive but not slave transmit. Use at your own risk. Enjoy.

Don

This is going to sound dumb, so I apologize in advance, but I haven't done much work with AVRs and I've run into a problem using this. Where do I put these files? I've dropped them into the winavr/avr/include/avr folder (where the other headers like io.h reside) and when I reference it, I end up in something of an infinite loop as it tries to include it over and over, it seems. Here's what I'm doing:

/*Includes*/
#include 
#include 
#include 
#include 

and the result:

> "make.exe" all
avr-gcc -Wall -Os -DF_CPU=8000000 -mmcu=attiny2313 -c main.c -o main.o
In file included from c:/winavr-20100110/lib/gcc/../../avr/include/avr/usiTwiSlave.h:44,
                 from c:/winavr-20100110/lib/gcc/../../avr/include/avr/usiTwiSlave.h:44,
                 from c:/winavr-20100110/lib/gcc/../../avr/include/avr/usiTwiSlave.h:44,
                 from c:/winavr-20100110/lib/gcc/../../avr/include/avr/usiTwiSlave.h:44,
                 from c:/winavr-20100110/lib/gcc/../../avr/include/avr/usiTwiSlave.h:44,
                 from c:/winavr-20100110/lib/gcc/../../avr/include/avr/usiTwiSlave.h:44,

etc etc

If anyone has any links on where to put header/c files and how to include them, that would be great - a search didn't lead me to anything that seemed immediately relevant.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would delete all the directories in your WinAVR installation and re-install.

Personally, I never add "weird" include files to the system include directories.

Either add the 'weirdo' directory to your project, so it searches the system directories and your weirdo one.

Or you copy the weird.h to your project directory and access with #include "weird.h".

Remember that avr-cpp searches for and "weird.h" in different ways.

If you are going to use a respected library regularly, the first method is preferable.

Note that if the "weird.h" is from an unknown source, it is worth checking it over carefully. In particular for guards against multiple inclusion.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
Or you copy the weird.h to your project directory and access with #include "weird.h".

Thanks, this is exactly what I was looking for. It's been awhile since my last programming class and this jogged my memory - now I'm embarrassed I forgot. :oops: Perhaps it's time to open up an old textbook for a refresher.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One last problem when I run make:

usiTwiSlave.h:257: error: `TWI_RX_BUFFER_SIZE' undeclared here

Same thing with TWI_TX_BUFFER_SIZE, TWI_TX_BUFFER_MASK, and TWI_RX_BUFFER_MASK. I'm assuming this is a simple matter of defining these with an appropriate value, but am not sure what those values should be.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Nevermind, answered my own question with a little google-fu. For those with the same question, here's a little more documentation (especially on buffer sizes and masks): http://wtfmoogle.com/wiki/index.php/UsiTwiSlave.h

It seems that somehow my .h file was the same as the .c, so I was missing those definitions. Thanks for the great code!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello guys.
Excuse me for dumb question (and for my engish), but how I can use this code for recieving 7 byte messege?

Steps:
1) Init. ( usiTwiSlaveInit() )
2) I don't now whats next:)

How to take my messege (7 bytes) in some buffer?

Thanks.