Setting Address on a I2C DAC - Page 1
Forum section: electronics / general

author: dan3460
author_rank: Frequent Contributor
timestamp: May 27, 2017, 10:08:24 pm
content: I need to setup a new address for the I2C bus for a DAC chip (MCP4728T), I didn't realized that the instructions are very specific, there are 4 bytes to be sent and you have to toggle a pin up and down. The problem is where the pin needs to go from high to low and from low to high. "The LDAC pin needs to transition from high to low at during the negative part of the 8 bit of the second byte..." similar for the low to high on the 8 bit of the 4 byte. Is there anyway to monitor the SCL pin on the Atmel328P. maybe put an interrupt at the 8th pulse of every 9?I Know that I can do this by "brute" force by timing the high and low of three pins on the 328p.

author: Ian.M
author_rank: Super Contributor
timestamp: May 27, 2017, 10:15:40 pm
content: Comes from:https://www.eevblog.com/forum/microcontrollers/weird-behavior-on-arduino-envioroment/msg1218848/#msg1218848If its so fussy that you have to toggle the LDAC pin at a particular point in a single bit of the I2C transfer, the best option would be to ignore the TWI module and bit-bang the whole I2C transfer!

author: dan3460
author_rank: Frequent Contributor
timestamp: May 28, 2017, 01:19:30 am
content: Yes, that is what I thought. Almost done making a little program that tickles the pins up and down in the right sequence.Thanks for the help

author: dan3460
author_rank: Frequent Contributor
timestamp: May 28, 2017, 11:39:03 am
content: I was able to change the address of the chip. In case that any one needs to do this I have included the little program that I made. I'm sure that there are many things that can be changed to make it more efficient but I only needed to do this once and this "brute" force approach suited me.Code:/** MPC4728_address_changer.cpp** Created: 5/27/2017 10:42:53 AM* Author : Daniel Kolbach* This program changes the address to the DAC chip MPC4728.* The specs for the chip indicate that you need to control the LDAC pin at a very specific point* during the sequence of commands sent to the chip via I2C.* Refer to page 42 of the chip in question* Disclaimer: This software is provided with no implicit or explicit warranties.*/#define F_CPU 16000000#include <avr/io.h>#include <util/delay.h>int main(void){DDRB |= (1<<PORTB4)|(1<<PORTB1)|(1<<PORTB0); // Using Arduino Uno, port 8 (PB0) SCL, port 9 (PB1) SDA, port 12 (PB4) LDACPORTB |=(1<<PORTB4)|(1<<PORTB1)|(1<<PORTB0);uint8_t command={1,1,0,0,0,0,0,0, // Initial address is 0x60 (0xC0 with the write bit added0,1,1,0,0,0,0,1,0,1,1,0,0,1,1,0, // Address changed to 0x610,1,1,0,0,1,1,1};PORTB &= ~(1<<PORTB1); // Sending the start condition for the I2C bus_delay_us(1.5);PORTB &= ~(1<<PORTB0);_delay_us(1.5);for (int x=0; x<4; x++) // Repeat this for each of the commands.{for (int y=0; y<8; y++){if(command == 1) PORTB |= (1<<PORTB1); // Check from the command table if high or low needs to be written to SDAelse PORTB &= ~(1<<PORTB1);_delay_us(0.5);PORTB |= (1<<PORTB0);// Send the clock pulse_delay_us(1.3);PORTB &= ~(1<<PORTB0);}DDRB &= ~(1<<PORTB1); // Change SDA to input to check for the answer from the chipif(x==1) PORTB &= ~(1<<PORTB4); // LDAC needs to be pulled down before the 9th clock pulse only on the second commandif(x==3) PORTB |= (1<<PORTB4); // LDCA needs to be pulled up before the 9th clock pulse only on the 4th command_delay_us(0.5);PORTB |= (1<<PORTB0); // Sending the 9th clock pulse_delay_us(1.5);PORTB &= ~(1<<PORTB0);_delay_us(0.3);DDRB |= (1<<PORTB1); // Returning the SDA line back to outputPORTB |= (1<<PORTB1);_delay_us (1.7);}PORTB &= ~((1<<PORTB0)|(1<<PORTB1)); // Sending the stop signal_delay_us(1.5);PORTB |= (1<<PORTB0);_delay_us(1.5);PORTB |= (1<<PORTB1);while (1){}}