hai
I need to read ADS1115 sensor values through the i2c protocol . i am, using lpc824 mcuxpresso i am, try last 2 week referred the ads1115 datasheet and lpc824 datasheet. but i got only junk values , please let me know the solution to correct my faults.
plz refer my code and give me somr solution i am asking this assistance last 2 week but till i couldn't get proper o/p
i refered lpc example coding which provided in the mcuxpresso ide but in that code also i didn't got any proper solution . in that examples code there is no adc reading code in i2c plz give the solution
//#ifdef __USE_CMSIS
#include "LPC8xx.h"
//#endif
//#include <cr_section_macros.h>
#include <stdio.h>
#include "lpc8xx_i2c.h"
#include "lpc8xx_syscon.h"
#include "lpc8xx_swm.h"
#include "utilities.h"
extern void setup_debug_uart(void);
#define BUFFER_SIZE 35
#define WaitForUART0txRdy while(((LPC_USART0->STAT) & (1<<2)) == 0)
void setup_debug_uart(void);
unsigned char the_prompt[] = "Enter some characters to be transmitted from the I2C master to the slave\n\r";
unsigned char the_massage[] = "Characters received by the I2C slave were \n\r";
unsigned char u0_rx_buffer[BUFFER_SIZE];
unsigned char slave_rx_data[BUFFER_SIZE];
volatile enum {false, true} uart_handshake;
static uint32_t rx_char_counter = 0;
static uint32_t slave_data_counter = 0;
#define slave_board_address 0x48
const char promptstring[] = "IOT I2C ADC list:\n\r ADC 0:\n\r ADC 1:\n\r ADC 2:\n\r ADC 3:\n\r";
void UART0_IRQHandler() {
unsigned char temp;
temp = LPC_USART0->RXDAT ;
u0_rx_buffer[rx_char_counter] = temp; // Append the current character to the rx_buffer
WaitForUART0txRdy; // Wait for TXREADY
LPC_USART0->TXDAT = temp; // Echo it back to the terminal
if (temp == 0x0D) { // CR (carriage return) is current character. End of string.
u0_rx_buffer[rx_char_counter+1] = 0x0A; // Append a new line character to u0_rx_buffer.
u0_rx_buffer[rx_char_counter+2] = 0x00; // Append a NUL terminator character to u0_rx_buffer to complete the string.
WaitForUART0txRdy; // Wait for TXREADY
LPC_USART0->TXDAT = 0x0A; // Echo a NL (new line) character to the terminal.
uart_handshake = true; // Set handshake for main()
rx_char_counter = 0; // Clear array index counter
}
else { // Current character is not CR, keep collecting them.
rx_char_counter++; // Increment array index counter.
if (rx_char_counter == BUFFER_SIZE) // If the string overruns the buffer, stop here before all hell breaks lose.
while(1);
}
return;
}
/*****************************************************************************
** Function name: I2C0_IRQHandler
**
** Descriptions: I2C0 interrupt service routine.
**
** parameters: None
** Returned value: None
**
*****************************************************************************/
/*void I2C0_IRQHandler(void) {
uint32_t temp;
if ((LPC_I2C0->STAT & SLAVE_STATE_MASK) == STAT_SLVADDR) {
LPC_I2C0->SLVCTL = CTL_SLVCONTINUE; // ACK the address
return;
}
if ((LPC_I2C0->STAT & SLAVE_STATE_MASK) == STAT_SLVRX) {
temp = LPC_I2C0->SLVDAT; // Read the data
slave_rx_data[slave_data_counter++] = temp; // Store it in the array, increment counter
//PutTerminalString(LPC_USART0,slave_rx_data);
LPC_I2C0->SLVCTL = CTL_SLVCONTINUE; // ACK the data
if (temp == 0) // If current char is NUL terminator
slave_data_counter = 0; // clear the counter for next string
return;
}
while(1); // Any other slave state, stop here and debug
}
*/
void I2C0_IRQHandler(void) {
uint32_t temp=0;
unsigned int five=50009;
// if ((LPC_I2C0->STAT & MASTER_STATE_MASK) == STAT_MSTIDLE) {
// LPC_I2C0->MSTCTL = CTL_MSTCONTINUE; // ACK the address
// return;
// }
if ((LPC_I2C0->STAT & MASTER_STATE_MASK) == STAT_MSTRX) {
temp = LPC_I2C0->MSTDAT; // Read the data
slave_rx_data[slave_data_counter++] = temp; // Store it in the array, increment counter
PutTerminalchar2(LPC_USART0,slave_rx_data);
// PutTerminalchar2(LPC_USART0, five);
LPC_I2C0->MSTCTL = CTL_SLVCONTINUE; // ACK the data
if (temp == 0) // If current char is NUL terminator
slave_data_counter = 0; // clear the counter for next string
return;
}
//while(1); // Any other slave state, stop here and debug
}
int main(void) {
int temp,temp1=0;
unsigned int abc= 3,abc1=5009,abc2=5,abc3=6;
int a="ABCDEFGHIJKLMN1234567/n";
// Configure the debug uart (see Serial.c)
setup_debug_uart();
// Enable clocks to I2C, SWM (see lpc8xx_syscon.h)
LPC_SYSCON->SYSAHBCLKCTRL |= (I2C0|SWM);
// SWM settings for I2C0 (master):
// P0.10 = I2C0_SCL
// P0.11 = I2C0_SDA0
LPC_SWM->PINENABLE0 &= ~(I2C0_SCL|I2C0_SDA); // Use for LPC824
// Give I2C a reset (see lpc8xx_syscon.h)
LPC_SYSCON->PRESETCTRL &= (I2C0_RST_N);
LPC_SYSCON->PRESETCTRL |= ~(I2C0_RST_N);
// PutTerminalchar(LPC_USART0, abc);
// PutTerminalString(LPC_USART0, (uint8_t *) the_prompt); // IOT PROJECT STRING
// Configure the I2C clock divider
// Desired bit rate = Fscl = 100,000 Hz
// Use default clock high and clock low times (= 2 clocks each)
// So 4 I2C_PCLKs = 100,000/second, or 1 I2C_PCLK = 400,000/second
// I2C_PCLK = SystemClock = 30,000,000/second, so we divide by 30/.4 = 75
// Remember, value written to DIV divides by value+1
//
LPC_I2C0->DIV = (75-1);
//LPC_I2C0->DIV = (30-1);
LPC_I2C0->CFG = CFG_MSTENA;
//LPC_I2C0->MSTDAT = (slave_board_address<<1) | 1;
//NVIC_EnableIRQ(I2C0_IRQn);
while(1) {
WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_IDLE);
LPC_I2C0->MSTDAT = (slave_board_address<<1) |1; //// ( read )
LPC_I2C0->MSTCTL = CTL_MSTSTART; // Start the transaction.
WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_RX );
// LPC_I2C0->MSTCTL = CTL_MSTCONTINUE;
temp1 = LPC_I2C0->MSTDAT;
LPC_I2C0->MSTCTL = CTL_MSTCONTINUE;
slave_rx_data[slave_data_counter++] = temp1;
PutTerminalchar2(LPC_USART0,(uint8_t*)slave_rx_data);
WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_RX );
LPC_I2C0->MSTCTL = CTL_MSTSTOP;
if (temp1 == 0) // If current char is NUL terminator
{
slave_data_counter = 0;
}
} // end of while(1)
} // end of main
Hello Aravind palanisamy,
About reading data from ADS1115, please refer to the datasheet of ADS1115 -> reading from registers sequence part:
"
To access a specific register from the ADS111x, the master must first write an appropriate value to register
address pointer bits P[1:0] in the Address Pointer register. The Address Pointer register is written to directly after
the slave address byte, low R/W bit, and a successful slave acknowledgment. After the Address Pointer register
is written, the slave acknowledges, and the master issues a STOP or a repeated START condition.
When reading from the ADS111x, the previous value written to bits P[1:0] determines the register that is read. To
change which register is read, a new value must be written to P[1:0]. To write a new value to P[1:0], the master
issues a slave address byte with the R/W bit low, followed by the Address Pointer register byte. No additional
data has to be transmitted, and a STOP condition can be issued by the master. The master can now issue a
START condition and send the slave address byte with the R/W bit high to begin the read. Figure 37 details this
sequence. If repeated reads from the same register are desired, there is no need to continually send the Address
Pointer register, because the ADS111x store the value of P[1:0] until it is modified by a write operation. However,
for every write operation, the Address Pointer register must be written with the appropriate values.
" Also refer to the Figure 30.Timing Diagram for Reading From ADS111x .
In your code , I haven't see write " slave address byte", and " write an appropriate value to register
address pointer bits P[1:0] in the Address Pointer register."
And if still have problem, suggest you use a logic analysis signals, compare with Fig 30 of ADS1115 datasheet.
Hope it helps,
Have a great day,
TIC
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------
THIS is my updated code but this also doesn't work
/*
===============================================================================
Name : Example_I2C_MasterSlave.c
Author : $(author)
Version :
Copyright : $(copyright)
Description : main definition
===============================================================================
*/
#include "LPC8xx.h"
//#include <cr_section_macros.h>
//#include <stdio.h>
#include "lpc8xx_i2c.h"
#include "lpc8xx_swm.h"
#include "lpc8xx_syscon.h"
#include "utilities.h"
#define BUFFER_SIZE 35
#define WaitForUART0txRdy while(((LPC_USART0->STAT) & (1<<2)) == 0)
#define Self_Slave_address 0x48U
#define ADS1015_REG_POINTER_MASK (0x03)
#define ADS1015_REG_POINTER_CONVERT (0x00)
#define ADS1015_REG_POINTER_CONFIG (0x01)
#define ADS1015_REG_POINTER_LOWTHRESH (0x02)
#define ADS1015_REG_POINTER_HITHRESH (0x03)
#define config_high 0x84
#define config_low 0x83
#define config_line 0x0083
void setup_debug_uart(void);
const unsigned char the_prompt[] = "Enter some characters to be transmitted from the I2C master to the slave\n\r";
const unsigned char the_massage[] = "Characters received by the I2C slave were \n\r";
const unsigned char start_bit[] = "Startbit \n\r";
const unsigned char stop_bit[] = "Stopbit \n\r";
unsigned char u0_rx_buffer[BUFFER_SIZE];
//unsigned char slave_rx_data[BUFFER_SIZE];
unsigned int slave_rx_data[BUFFER_SIZE];
unsigned char TEMP1[]="5";
volatile enum {false, true} uart_handshake;
static uint32_t rx_char_counter = 0;
static uint32_t slave_data_counter = 0;
/*****************************************************************************
** Function name: UART0_IRQHandler
**
** Description: UART0 interrupt service routine.
** This ISR reads one received char from the UART0 RXDAT register,
** appends it to the u0_rx_buffer array, and echos it back via the
** UART0 transmitter. If the char. is 0xD (carriage return),
** a new line char (0xA) is appended to the array and echoed,
** then a NUL char (0x0) is appended to the array to terminate the string
** for future use.
**
** Parameters: None
** Returned value: void
**
*****************************************************************************/
void UART0_IRQHandler() {
unsigned char temp;
temp = LPC_USART0->RXDAT ;
u0_rx_buffer[rx_char_counter] = temp; // Append the current character to the rx_buffer
WaitForUART0txRdy; // Wait for TXREADY
LPC_USART0->TXDAT = temp; // Echo it back to the terminal
if (temp == 0x0D) { // CR (carriage return) is current character. End of string.
u0_rx_buffer[rx_char_counter+1] = 0x0A; // Append a new line character to u0_rx_buffer.
u0_rx_buffer[rx_char_counter+2] = 0x00; // Append a NUL terminator character to u0_rx_buffer to complete the string.
WaitForUART0txRdy; // Wait for TXREADY
LPC_USART0->TXDAT = 0x0A; // Echo a NL (new line) character to the terminal.
uart_handshake = true; // Set handshake for main()
rx_char_counter = 0; // Clear array index counter
}
else { // Current character is not CR, keep collecting them.
rx_char_counter++; // Increment array index counter.
if (rx_char_counter == BUFFER_SIZE) // If the string overruns the buffer, stop here before all hell breaks lose.
while(1);
}
return;
}
/*****************************************************************************
** Function name: I2C0_IRQHandler
**
** Descriptions: I2C0 interrupt service routine.
**
** parameters: None
** Returned value: None
**
*****************************************************************************/
/*void I2C0_IRQHandler(void) {
uint32_t temp;
if ((LPC_I2C0->STAT & SLAVE_STATE_MASK) == STAT_SLVADDR) {
LPC_I2C0->SLVCTL = CTL_SLVCONTINUE; // ACK the address
return;
}
if ((LPC_I2C0->STAT & SLAVE_STATE_MASK) == STAT_SLVRX) {
temp = LPC_I2C0->SLVDAT; // Read the data
slave_rx_data[slave_data_counter++] = temp; // Store it in the array, increment counter
PutTerminalNUM(LPC_USART0, TEMP1);
LPC_I2C0->SLVCTL = CTL_SLVCONTINUE; // ACK the data
if (temp == 0) // If current char is NUL terminator
slave_data_counter = 0; // clear the counter for next string
return;
}
while(1); // Any other slave state, stop here and debug
}*/
void I2C0_IRQHandler(void) {
uint32_t temp;
unsigned char temp1=5;
if ((LPC_I2C0->STAT & MASTER_STATE_MASK) == STAT_MSTIDLE) {
LPC_I2C0->MSTCTL = CTL_MSTCONTINUE; // ACK the address
return;
}
if ((LPC_I2C0->STAT & MASTER_STATE_MASK) == STAT_MSTRX) {
temp = LPC_I2C0->MSTDAT; // Read the data
slave_rx_data[slave_data_counter++] = temp; // Store it in the array, increment counter
PutTerminalString(LPC_USART0, temp1);
LPC_I2C0->MSTCTL = CTL_MSTCONTINUE; // ACK the data
WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_TX); // Wait for the data to be ACK'd
//
LPC_I2C0->MSTCTL = CTL_MSTSTOP; // Send a stop to end the transaction
if (temp == 0) // If current char is NUL terminator
slave_data_counter = 0; // clear the counter for next string
return;
}
// while(1); // Any other slave state, stop here and debug
}
/*****************************************************************************
*****************************************************************************/
int main(void) {
uint32_t temp ,msb_byte,lsb_byte;
unsigned char * tx_ptr;
unsigned int temp1=5009;
// Configure the debug uart (see Serial.c)
setup_debug_uart();
// Enable clocks to I2C0, SWM (see lpc8xx_syscon.h)
LPC_SYSCON->SYSAHBCLKCTRL |= (I2C0 | SWM);
// SWM settings for I2C0:
// P0.10 = I2C0_SCK
// P0.11 = I2C0_SDA
// Configure the SWM (see utilities_lib and lpc8xx_swm.h)
// On the LPC824, I2C0_SDA and I2C0_SCL are fixed pin functions which are enabled / disabled in the pinenable0 register
LPC_SWM->PINENABLE0 &= ~(I2C0_SCL|I2C0_SDA); // Use for LPC824
//ConfigSWM(I2C0_SCL, P0_10); // Use for LPC812
//ConfigSWM(I2C0_SDA, P0_11); // Use for LPC812
// Give I2C0 a reset (see lpc8xx_syscon.h)
LPC_SYSCON->PRESETCTRL &= (I2C0_RST_N);
LPC_SYSCON->PRESETCTRL |= ~(I2C0_RST_N);
// Configure the I2C0 clock divider
// Desired bit rate = Fscl = 100,000 Hz (1/Fscl = 10 us, 5 us low and 5 us high)
// Use default clock high and clock low times (= 2 clocks each)
// So 4 I2C_PCLKs = 100,000/second, or 1 I2C_PCLK = 400,000/second
// I2C_PCLK = SystemClock = 30,000,000/second, so we divide by 30/.4 = 75
// Remember, value written to DIV divides by value+1
LPC_I2C0->DIV = (75 - 1);
// LPC_I2C0->DIV = (30 - 1);
// Configure the I2C0 CFG register:
// Master enable = true
// Slave enable = true
// Monitor enable = false
// Time-out enable = false
// Monitor function clock stretching = false
LPC_I2C0->CFG = CFG_MSTENA| CFG_SLVENA ;
// Configure the I2C0 SLVADR3 address register with 0 in l.s.b. to enable slave address 3
//LPC_I2C0->SLVADR3 = (Self_Slave_address<<1) | 1;
LPC_I2C0->INTENSET = STAT_MSTPEND|STAT_SLVPEND ;
///////////////////////////////////////////////////////////////////////////////////////
//////////////////write from master to ADS1115 I2C MODULE/////////////////////////////////////////////
LPC_I2C0->MSTCTL = CTL_MSTSTART; // Start the transaction by setting the MSTSTART bit to 1 in the Master control register.
LPC_I2C0->MSTDAT = (Self_Slave_address<<1) | 0; // Address with 0 for RWn bit (WRITE)
WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_TX ); // Wait for the address to be ACK'd
LPC_I2C0->MSTDAT = ADS1015_REG_POINTER_CONFIG; // Address with 0 for RWn bit (WRITE)
WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_TX ); // Wait for the address to be ACK'd
LPC_I2C0->MSTDAT = config_high; // Address with 0 for RWn bit (WRITE) config
WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_TX ); // Wait for the address to be ACK'd
LPC_I2C0->MSTDAT =config_low; // Address with 0 for RWn bit (WRITE) config
WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_TX ); // Wait for the address to be ACK'd
LPC_I2C0->MSTCTL = CTL_MSTSTOP; // Send a stop to end the transaction
// LPC_I2C0->MSTDAT = ADS1015_REG_POINTER_CONVERT;
// WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_TX); // Wait for the address to be ACK'd
// LPC_I2C0->MSTCTL = CTL_MSTCONTINUE;
LPC_I2C0->MSTCTL = CTL_MSTSTART;
LPC_I2C0->MSTDAT = (Self_Slave_address<<1) | 0; // Address with 0 for RWn bit (write)
WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_TX);
LPC_I2C0->MSTDAT = ADS1015_REG_POINTER_CONVERT;
WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_TX); // Wait for the address to be ACK'd
LPC_I2C0->MSTCTL = CTL_MSTSTOP;
while(1)
{
////////////////// write to ads1115 conversion register/////////////////////////////////////////////
// LPC_I2C0->MSTCTL = CTL_MSTSTART;
// LPC_I2C0->MSTDAT = (Self_Slave_address<<1) | 0; // Address with 0 for RWn bit (write)
// WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_TX); // Wait for the address to be ACK'd
// //PutTerminalString(LPC_USART0, start_bit);
// LPC_I2C0->MSTDAT = ADS1015_REG_POINTER_CONVERT;
// WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_TX); // Wait for the address to be ACK'd
// PutTerminalString(LPC_USART0, start_bit);
// LPC_I2C0->MSTCTL = CTL_MSTSTOP; // Send a stop to end the transaction
// // LPC_I2C0->MSTCTL = CTL_MSTSTART; // Start the transaction by setting the MSTSTART bit to 1 in the Master control register.
LPC_I2C0->MSTCTL = CTL_MSTSTART;
LPC_I2C0->MSTDAT = (Self_Slave_address<<1) | 1; // Address with 0 for RWn bit (read)
WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_RX);
msb_byte = LPC_I2C0->MSTDAT; // Read the data
WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_RX);
lsb_byte = LPC_I2C0->MSTDAT; // Read the data
WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_RX);
// slave_rx_data[slave_data_counter++] = temp; // Store it in the array, increment counter
// PutTerminalString1(LPC_USART0, temp1);
PutTerminalString1(LPC_USART0, msb_byte);
PutTerminalString1(LPC_USART0, lsb_byte);
// PutTerminalchar0(LPC_USART0, lsb_byte);
// LPC_I2C0->MSTCTL = CTL_MSTCONTINUE; // ACK the data
// PutTerminalString(LPC_USART0,temp);
// WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_RX); // Wait for the data to be ACK'd
// NVIC_EnableIRQ(I2C0_IRQn);
LPC_I2C0->MSTCTL = CTL_MSTSTOP; // Send a stop to end the transaction
PutTerminalString(LPC_USART0, (uint8_t *)stop_bit);// Print a massage
} // end of while 1
} // end of main
/////////////////////////////////////