I2C and Attiny2313

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

I am new to MC. One of the first things that i tried to do, was connection between tiny and LCD1602 module by I2C. For that purpose i wrote some functions, but seems like they works wrong because device on bus can't be detected.

So ... can somebody help me with mistake in the code ?

#define I2C_PORT PORTD
#define I2C_PIN PIND
#define I2C_DDR DDRD
#define I2C_DELAY 2
#define SCL 0
#define SDA 1
#define I2C_MASK 0b10000000

void sda_low(){
	I2C_PORT &= ~(1<<SDA);
	I2C_DDR |= 1<<SDA; 
}

void sda_high(){
	I2C_DDR &= ~(1<<SDA);
	I2C_PORT |= 1<<SDA;
}

void scl_low(){
	I2C_PORT &= ~(1<<SCL);
	I2C_DDR |= 1<<SCL;
}

void scl_high(){
	I2C_DDR &= ~(1<<SCL);
	I2C_PORT |= 1<<SCL;
}

void i2c_init(){
	I2C_DDR &= ~(1<<SDA | 1<<SCL);
	I2C_PORT |= 1<<SDA | 1<<SCL;
	_delay_ms(I2C_DELAY);
}

void i2c_start(){
	sda_low();
	_delay_ms(I2C_DELAY);
	scl_low();
	_delay_ms(I2C_DELAY*4);
}

void i2c_stop(){
	scl_high();
	_delay_ms(I2C_DELAY);
	sda_high();
	_delay_ms(I2C_DELAY*4);
}

uint8_t i2c_ack(){
	sda_high();
	_delay_ms(I2C_DELAY);
	scl_high();
	_delay_ms(I2C_DELAY);
	uint8_t result = I2C_PIN & (1<<SDA);
	_delay_ms(I2C_DELAY);
	scl_low();
	_delay_ms(I2C_DELAY);
	return result;
}

uint8_t i2c_write(uint8_t data){
	for (int i=0; i<8; i++){
		if (I2C_MASK & data)
			sda_high();
		_delay_ms(I2C_DELAY);
		scl_high();
		_delay_ms(I2C_DELAY);
		scl_low();
		_delay_ms(I2C_DELAY);
		sda_low();
		_delay_ms(I2C_DELAY);
		data <<= 1;
	}
	return i2c_ack();
}

void led_show(uint8_t mode){
	DDRD |= (1<<2);
	if (mode)
		PORTD |= (1<<2);
	else 
		PORTD &= ~(1<<2);
}

int main(void)
{
	_delay_ms(1000);
	i2c_init();
	led_show(0);
	//Searching devices on bus
	for (int i=0; i<127; i++){ 
		i2c_start();
		//Trying to send 3 bytes ... 
			if (!i2c_write(i<<1))
				led_show(1);
			if (!i2c_write(i<<1))
				led_show(1);
			if (!i2c_write(i<<1))
				led_show(1);
		i2c_stop();
	}
	while(1){}
}

 

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

Use well proven I2C library. No need to re-inventing the wheel.
.
MG

I don't know why I'm still doing this hobby

Last Edited: Mon. Oct 2, 2017 - 12:37 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One of the best is Peter Fleury's I2C library. Google knows where it is.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

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

Nucrea wrote:
I am new to MC. One of the first things that i tried to do, was connection between tiny and LCD1602 module by I2C.

That's rather a huge leap for your first project!

 

surprise

 

I think you are trying to run before you've learned to walk!

 

See: http://www.avrfreaks.net/comment...

 

Also: http://www.avrfreaks.net/comment...

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

I would suggest starting with an Arduino Uno!

 

Jim

 

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

Good point.

 

@Nucrea: So what is your main objective here:

 

  • To learn the basics of microcontrollers?
     
  • To get stuff done?

 

 

If the former, then you really need to start with the basic foundations - as described in #4;

 

If the latter, then get an Arduino and get on with it!

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

Perhaps also tell us more about the I2C connected 1602 module as well?

 

The fact is that the person who created that will already have chosen some I2C address number for it. So doing stuff like:

	//Searching devices on bus
	for (int i=0; i<127; i++){ 

looks a bit like over-engineering. It's not suddenly going to up roots and move. If the designer assigned it an address of 0x63 then that's where you are always going to find it and you can hard code 0x63 as the address of it into your 2313 program.

 

The one possible complication is that some I2C libraries use 7 bit addresses and some use 8 so even if told it is 0x63 then depending on the library code you use you may specify this as 0x63 or it might actually require 0xC6 (which is 0x63 * 2). But once you know the number it won't change.

 

(This is not like DHCP/ARP on a TCP/IP Ethernet network where devices are dynamically assigned address numbers that could change over time).

Last Edited: Mon. Oct 2, 2017 - 02:14 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would echo Andy Neil.   Buy an Arduino Uno.   The Chinese clones are incredibly cheap.

Arduino support is excellent for the Uno.

 

If you really want to use a 16x2 with I2C backpack,   I can post you the appropriate CodeVision library that works with a Tiny2313.

Or the equivalent for GCC.

 

It is not difficult to bit-bash the LCD with an I2C port expander and TWI.   Having to bit-bash the I2C as well complicates matters.

It is not a beginner project.

 

David.

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

clawson wrote:
 some I2C libraries use 7 bit addresses and some use 8 

See: http://www.avrfreaks.net/comment...

 

And follow the link for more detail: http://www.avrfreaks.net/comment...