Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
7 years, 7 months ago.
STM32F429ZI (master) to STM32F429ZI(slave) I2C protocol reg
I am trying check the I2c protocol using two STM board .I have not received any output when I was checking in the serial terminal using "pc.print "
Master Code:
- include "mbed.h"
I2C i2c(PB_9,PB_6); Serial pc(USBTX, USBRX);
int main() { const int addr = 0xA0; int a,b; char buff[10]; const char data[]="message master";
i2c.frequency(10000);
while(1) { /* i2c.start(); a=i2c.read(addr, buff,10,1); wait(1); pc.printf("Read %d", a); i2c.stop(); pc.printf("MASTER READ: %s \n\r", buff);*/ i2c.start(); b=i2c.write( addr, data, strlen(data)+1); wait(0.07); i2c.stop(); pc.printf("Write %d\n\r", b); for(int i = 0; i < 10; i++) buff[i] = 0;
} }
SLAVE CODE:
- include "mbed.h"
I2C i2c(PB_9,PB_6); Serial pc(USBTX, USBRX);
int main() {
const char test[]= "message slave"; char buf[10]; int i, b;
i2c.frequency(10000); slave.address(0xA0);
while(1) {
i = slave.receive(); wait(0.75);
switch (i) {
case I2CSlave::ReadAddressed:
slave.stop(); b=slave.write(test, strlen(test) + 1); wait(0.75);
pc.printf("Return Slave %d", b); only to check return value
break; case I2CSlave::WriteGeneral:
slave.stop(); slave.read(buf, 10); wait(0.75); pc.printf("SLAVE Read G: %s\n\r", buf); break; case I2CSlave::WriteAddressed:
slave.stop(); slave.read(buf, 10); wait(0.75); pc.printf("SLAVE Read A: %s\n\r", buf); break; } for(int i = 0; i < 10; i++) buf[i] = 0;
} }
1 Answer
7 years, 7 months ago.
Hi. A few pointers.
1) apply the <<code>> your code <</code>>
markers when you post your source code so it is easier for others to review. Here is your code reformatted using these special markers.
Master code:
#include "mbed.h" I2C i2c(PB_9,PB_6); Serial pc(USBTX, USBRX); int main() { const int addr = 0xA0; int a,b; char buff[10]; const char data[]="message master"; i2c.frequency(10000); while(1) { /* i2c.start(); a=i2c.read(addr, buff,10,1); wait(1); pc.printf("Read %d", a); i2c.stop(); pc.printf("MASTER READ: %s \n\r", buff); */ i2c.start(); b=i2c.write( addr, data, strlen(data)+1); wait(0.07); i2c.stop(); pc.printf("Write %d\n\r", b); for(int i = 0; i < 10; i++) buff[i] = 0; } }
Slave Code:
#include "mbed.h" I2C i2c(PB_9,PB_6); Serial pc(USBTX, USBRX); int main() { const char test[]= "message slave"; char buf[10]; int i, b; i2c.frequency(10000); slave.address(0xA0); while(1) { i = slave.receive(); wait(0.75); switch (i) { case I2CSlave::ReadAddressed: slave.stop(); b=slave.write(test, strlen(test) + 1); wait(0.75); pc.printf("Return Slave %d", b); // only to check return value break; case I2CSlave::WriteGeneral: slave.stop(); slave.read(buf, 10); wait(0.75); pc.printf("SLAVE Read G: %s\n\r", buf); break; case I2CSlave::WriteAddressed: slave.stop(); slave.read(buf, 10); wait(0.75); pc.printf("SLAVE Read A: %s\n\r", buf); break; } for(int i = 0; i < 10; i++) buf[i] = 0; } }
2) Read my post here on a similar review:
https://developer.mbed.org/questions/78077/I2CSlave-mbed-code-review/
3) Remove the use of:
i2c.start(); // remove from your code i2c.stop(); // remove from your code slave.stop(); // remove from your code
The START and STOP states are automatically inserted by the I2C routines and your manual use of these lines will break the code.
4) Be sure that you have a single pair of pull-up resistors as required by the I2C spec. The value of the resistors is not critical but recommended values are 2k2 to say 10k to 3v3. The same ST port pins for I2C use a 5 volt tolerant so it is also safe to apply the same pull-up resistors to +5 volts if required. The resistors are mandatory to pull up the port pins to a logic high as I2C pins are open collector when the s/w outputs a high.
5) Most important is the use of the I2CSlave routine. As per my review last week, the Slave I2C read MUST use the proper buffer size. For your example, your I2C master is sending to the I2C Slave a string length of 14 bytes + 1 EOF marker = 15 bytes.
Try the following revised code (not tested as my setup is at work):
I2C Master:
#include "mbed.h" I2C i2c(PB_9,PB_6); Serial pc(USBTX, USBRX); int main() { const int addr = 0xA0; int a,b; char buff[10]; const char data[]="message master"; i2c.frequency(10000); while(1) { /* i2c.start(); a=i2c.read(addr, buff,10,1); wait(1); pc.printf("Read %d", a); i2c.stop(); pc.printf("MASTER READ: %s \n\r", buff); */ b=i2c.write( addr, data, strlen(data)+1); wait(0.07); pc.printf("Write %d\n\r", b); for(int i = 0; i < 10; i++) buff[i] = 0; } }
I2C Slave:
#include "mbed.h" I2C i2c(PB_9,PB_6); Serial pc(USBTX, USBRX); int main() { const char test[]= "message slave"; // 13 bytes + 1 EOF = 14 bytes char buf[10]; int i, b; i2c.frequency(10000); slave.address(0xA0); while(1) { i = slave.receive(); wait(0.75); switch (i) { case I2CSlave::ReadAddressed: b=slave.write(test, strlen(test) + 1); wait(0.75); pc.printf("Return Slave %d", b); // only to check return value break; case I2CSlave::WriteGeneral: slave.read(buf, 15); // since the I2C master is sending to the slave 14 bytes of data + 1 EOF marker = 15 bytes wait(0.75); pc.printf("SLAVE Read G: %s\n\r", buf); break; case I2CSlave::WriteAddressed: slave.read(buf, 15); // since the I2C master is sending to the slave 14 bytes of data + 1 EOF marker = 15 bytes wait(0.75); pc.printf("SLAVE Read A: %s\n\r", buf); break; } for(int i = 0; i < 10; i++) buf[i] = 0; } }
The I2C Slave routine will block if more bytes are being read than what the I2C Master is sending. Ok if reading less bytes from the I2C Master but suggest to use the exact send buffer size.
After testing, please post your results.