This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hello everyone,
I'm a fresher of coding TM4C123GH6PM microcontroller. I have some questions like this:
1) I'm working with I2C on this board. The code is fine and there are no errors in it but I'm unable to write and read the data from the slave. I'm using TMS123GH6PM as a master and AT24C04 as a slave. Here is my code. Please check it for me.
2) I want to use I2C to communicate several TM4C123GXL boards. So how Can I find the address of each I2C module in TM4C123GXL board?
Thanks,
Best regards,
#define ADDRESS_DEVICE 0x50 //0x24HC04 (A0, A1 = LOW)
#include "I2C.h"
void Config_I2C(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
GPIOPinConfigure(GPIO_PA6_I2C1SCL);
GPIOPinConfigure(GPIO_PA7_I2C1SDA);
GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6);
GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7);
I2CMasterInitExpClk(I2C1_BASE, SysCtlClockGet(), true);
}
void I2c_Read_Buffer(uint8_t regAddress, uint8_t *pData, uint8_t length)
{
I2CMasterSlaveAddrSet(I2C1_BASE, ADDRESS_DEVICE, false);
I2CMasterDataPut(I2C1_BASE, regAddress);
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_SEND);
while(I2CMasterBusy(I2C1_BASE));
I2CMasterSlaveAddrSet(I2C1_BASE, ADDRESS_DEVICE, true);
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);
while(I2CMasterBusy(I2C1_BASE));
pData[0]=I2CMasterDataGet(I2C1_BASE);
uint8_t index=1;
for(index=1;index<length-1;index++)
{
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
while(I2CMasterBusy(I2C1_BASE));
pData[index]=I2CMasterDataGet(I2C1_BASE);
}
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
while(I2CMasterBusy(I2C1_BASE));
pData[index]=I2CMasterDataGet(I2C1_BASE);
}
void I2c_Read_Char(uint8_t regAddress, uint8_t *pData)
{
I2CMasterSlaveAddrSet(I2C1_BASE, ADDRESS_DEVICE, false);
I2CMasterDataPut(I2C1_BASE, regAddress);
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_SEND);
while(I2CMasterBusy(I2C1_BASE));
I2CMasterSlaveAddrSet(I2C1_BASE, ADDRESS_DEVICE, true);
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
while(I2CMasterBusy(I2C1_BASE));
*pData=I2CMasterDataGet(I2C1_BASE);
}
void I2c_Write_Buffer(uint8_t regAddress, uint8_t *pData, uint8_t length)
{
I2CMasterSlaveAddrSet(I2C1_BASE, ADDRESS_DEVICE, false);
I2CMasterDataPut(I2C1_BASE, regAddress);
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_START);
while(I2CMasterBusy(I2C1_BASE));
uint8_t index=0;
for(index=0;index<length-1;index++)
{
I2CMasterDataPut(I2C1_BASE, pData[index]);
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
while(I2CMasterBusy(I2C1_BASE));
}
I2CMasterDataPut(I2C1_BASE, pData[length-1]);
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
while(I2CMasterBusy(I2C1_BASE));
}
HI,
Nguyen Trong Tuan said:1) I'm working with I2C on this board. The code is fine and there are no errors in it but I'm unable to write and read the data from the slave. I'm using TMS123GH6PM as a master and AT24C04 as a slave. Here is my code. Please check it for me.
Do you have pull up resistors on the SCL and SDA bus?
You setup the I2C for 400Kbps. Are you sure the AT24C04 can operate at 400Kbps. You need to check the slave device datasheet to confirm. You can try 100Kbps by setting to I2CMasterInitExpClk(I2C1_BASE, SysCtlClockGet(), false);
Do you have a scope or logic analyzer capture of the I2C bus? The scope/LA capture will provide a lot of information on what is going on the bus.
Nguyen Trong Tuan said:2) I want to use I2C to communicate several TM4C123GXL boards. So how Can I find the address of each I2C module in TM4C123GXL board?
If you are setting up the MCU as a slave then you can configure each slave with an unique slave address by usng I2CSlaveAddressSet() API.
Hi Charles,
Thanks for your reply.
1) I have tried your solution. The I2C read function works well because It returns "255". I wonder if it read right or wrong? But When I use I2C write-function and then use I2C read function, it still returns "255". Is that a problem with my I2C write function??
2) I will try this API. Thanks for your suggestion.
regard,
Greetings,
Vendor's Charles has delivered his "usual" thoughtful:
We'll thus look more towards your Slave's demands & system implementation.
My small (outsider) group likes much of your posting - especially the neatness of the code & your identification of your "I2C Slave" and your determination of its address. (note to vendor - your syntax highlighter (always) confounds our ability to "edit and/or highlight our comments/corrections!")
We dislike your (poster's) "elimination of "main" - which disables a clear description of your, "Order of function calls" and/or "other program elements" - withheld from "helper view!" (in most cases - if posters' "really knew what could be withheld" - they'd not wind up here...)
Now some more concrete/focused comments:
That's not quite true/correct for your 4Kb device. Your slave's manual reveals:
Thus - you must "Ground pin A2 - which you've not presented here" and A0 (you marked low) is a "No Connect."
Your Slave manual presents a far simpler "Write Method" - and mastery of that is likely, "Faster, easier & more destined to succeed."
The far more complex "buffer" opens up multiple "Avenues of Error" - many of which bear "No Relationship" to I2C! Indeed that buffer idea may prove useful "downstream" (later) - but is premature now - and (almost) guarantees that your program will "fail to meet objectives." KISS rules - one small (and eased, measured/verified) Step at a Time!
Hi,
You did not answer me if you have the pullup resistors on the SDA and SCL bus. Without the scope/LA capture, it is difficult what is going on on the bus. You read the data into the pData array. What is the size of the pData? Note that the return value of the I2CMasterDataGet is cast to 32 bit. Also check if you are getting any errors. Check the ERROR bit in the I2CMCS register.
Hi Charles,
I have pulled up resistors on the SDA and SCL bus. The size of the pData is uint8_t. Does it okay with this type??
Hi,
I have connected the pin A2, A1, WP, GND to ground. I pulled up the resistors on the SDA and SCL bus as Mr.Charles told me. But It still the same as I did before. Is there anything else related to the hardware?
Hi,
You have not shown any scope/LA capture of the bus. The scope capture will provide a lot of information on what is going on the bus. Also change your variable uint32_t.
Thank you - good to (now) know that those hardware basics are covered.
At what voltage do you power the EEprom? While it has a wide input voltage range - if you power it from 5V - while your MCU is powered from 3V3 - you will not meet the EEprom's Vih (input) spec. (must be 70% of Vcc - MCU reaching 3V5 proves unlikely.)
The largest issue remaining is your decision to employ a buffer - which as we detailed earlier - forces much extra effort upon yourself and hapless helpers. The focus should ()properly) converge around "I2C" - and the dedicated I2C API functions! The intrusion of the buffer distracts from that while creating an array of "unwanted" error possibilities.
We are quite certain that your "Following the Write data example" which we copied from the EEprom's manual - proves your, "Shortest path to success." You (really) should "think & employ KISS!" "Premature Optimization" (i.e. creation of that buffer) has been "endlessly" proven - to CAUSE ISSUES! (and keeps firms like mine - in business!)
Hi,
Yes, But because of COVID 19, I'm unable to enter my lab so I can't use scope or logic analyzer. I may buy one to check it out.
Hi,
Thank for your help. I figured it out. I have some problems with my power supply so the SCL hay SDA cannot pulled up to 5V.
Thanks,
Best regards,
Hi Charles,
I checked the Scope and my data is unable to transfer signal because of my power supply. I have fixed it and it run well.
Thanks,
Best regards,