C Problem mit der I2C Kommunikation beim SRF08

Schunki

Neues Mitglied
17. Apr. 2012
1
0
0
49
Sprachen
Hallo zusammen!

Ich schreibe derzeit an meiner Studienarbeit und muss dabei mehrere Ultraschallsensoren über einem µC ansteuern und die Messwerte weiterverarbeiten.
Da ich in der Programmierung von µC noch nicht so fit bin, wollte ich zuerst mal nur einen Sensor ansteuern. Mein Ziel war es den auf ein STK500 Board gesteckten Atmega32 so zu programmieren, dass ich vorerst ein Byte mit einem bestimmten Bitmuster setzte (Low_Byte) dieses Bitmuster kann ich mir durch drücken eines Tasters (S5) auf den LED anzeigen lassen.
Nach betätigen des Tasters S0 soll nun die Messung ausgelöst werden. Kurz warten.... dann S1 betätigen welcher bewirken soll, dass der Messwert des Register 3 ausgelesen und in die Varriable Low_Byte geschrieben wird. Diese kann ich mir dann wieder über S5 neu auf den LEDs anzeigen lassen. Allerdings ist nach der Messung der Wert der Var Low_Byte=11111111, da keine LED mehr leuchtet.

Hier mal mein Code:

Code:
#ifndef 	F_CPU				
#define 	F_CPU 8000000UL
#endif

#include <avr/io.h>
#include <util/delay.h>

#define I2C_DDR			DDRC					// Register für die I2C Kommunikation
#define I2C_DDR_REG_BIT	DDC7					//
#define I2C_PORT		PORTC					// I2C Port definition

#define SCL				PC6						// Port C Pin 6
#define SDA				PC7						// Port C Pin 7

#define SDA_LESE_PIN 	PINC
#define SDA_LESE_BIT 	SDA

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void sda_low()
{
	I2C_PORT 		&=  ~(1<<SDA);    			// internen Pull-Up aus
	I2C_DDR 		|=   (1<<I2C_DDR_REG_BIT);  // Pin von SDA als Ausgang

}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void sda_high()
{
	I2C_DDR 		&= ~(1<<I2C_DDR_REG_BIT);  	// Pin von SDA als Eingang 
	I2C_PORT 		|=  (1<<SDA);    			// internen Pull-Up an 
} 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
////////////////////////////////////////////////////////////////////////////////////////////

#define I2C_SCL_LOW		I2C_PORT &= ~(1 << SCL)	// Clock Low Output
#define I2C_SCL_HIGH	I2C_PORT |=  (1 << SCL)	// Clock High Output

#define I2C_SDA_LOW		sda_low()				// Daten Leitung Low
#define I2C_SDA_HIGH	sda_high()				// Daten Leitung High

#define	ACK				0						// Ack empfangen
#define	NACK			1						// Ack nicht empfangen

#define S_DELAY			_delay_loop_1(1);		// ca. 2.76µs H-Time
#define M_DELAY			_delay_us(1);
#define DELAY			_delay_ms(1);			

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned char i2c_try_scl(unsigned char start_trials)
{
	// 10 Mal kurz warten, wenn SCL auf LOW gehalten wird
	while((!SCL) && (start_trials <50))
	{
		start_trials++;
		S_DELAY;
	}
	if(!SCL) return 0 ; return 1;
}

void i2c_master_stop(void);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

////////////////////////////////////////////////////////////////////////////////////////////
// I2C-Master Interface Standard Routinen
////////////////////////////////////////////////////////////////////////////////////////////
void i2c_master_init(void)
{
	I2C_DDR |=  (1<<SCL);  						// SCL Leitung als Ausgang definieren
		S_DELAY;
	I2C_SCL_HIGH;								// Cockleitung auf H setzen
	I2C_SDA_HIGH;								// Datenleitung auf H setzen
		S_DELAY;								// kurz warten
	i2c_master_stop();
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void i2c_master_clk_toggle(void)
{
	i2c_try_scl(0x0A);

	I2C_SCL_HIGH;
		S_DELAY;
		S_DELAY;
	I2C_SCL_LOW;
 		S_DELAY;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void i2c_master_start(void){
	// Übergang von H->L auf SDA, wobei SCL H ist.
	i2c_try_scl(0x0A);

	I2C_SDA_HIGH;			// SDA vorsichtshalber auf HIGH ziehen
	//	S_DELAY;
	I2C_SCL_HIGH;			// SCL auf High	
		S_DELAY;
	I2C_SDA_LOW;			// SDA auf Low ziehen
		M_DELAY;
		M_DELAY;
		M_DELAY;
	I2C_SCL_LOW;			// SCL auf low
		S_DELAY;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void i2c_master_stop(void)		
{
	// Übergang von L->H auf SDA, wobei SCL H ist.
	i2c_try_scl(0x0A);
		S_DELAY;
	I2C_SDA_LOW;			// SDA vorsichtshalber auf LOW ziehen
		S_DELAY;			// Kurz abwarten
	I2C_SCL_HIGH;			// SCL auf High setzen
		S_DELAY;		
	I2C_SDA_HIGH;			// SDA von L auf H ziehen
		S_DELAY;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned char i2c_master_write(unsigned char b)
{	
	char i=0;
	for(i=0;i<8;i++)
	{
		if (b & 0x80)	            // Wenn höchstes Bit=1 
		{
			I2C_SDA_HIGH;
		}
		else                        // Wenn höchstes Bit=0
		{
			I2C_SDA_LOW;
		}
		b=b<<1;                     // Daten Linksshift
		S_DELAY;
		i2c_master_clk_toggle();
	}
	// Auf ACK vom Slave Prüfen   
	I2C_SDA_HIGH;
	i2c_master_clk_toggle();		                                                                                                                   
	if(SDA==1)	
	{
		return 0;
	}
	else
	{ 
		return 1;
	}	
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned char i2c_master_read(unsigned char a)
{	
	unsigned char i,c=0b00000000;
	I2C_SDA_HIGH;      

	for(i=0;i<8;i++)		
	{
		c=c<<1;				

		// Bitweise OR verknüpfen mit dem Eingang, MSB zuerst
		if(SDA_LESE_PIN & (1 << SDA_LESE_BIT)) c|=1;			
		i2c_master_clk_toggle();
	}

	// ACK oder NACK | ACK=0; NACK=1
	if(a==ACK)	{I2C_SDA_LOW;} else {I2C_SDA_HIGH;}  
	i2c_master_clk_toggle();
	return c;
}


int main(void)
{   DDRD=0b00000000;
	DDRB=0b11111111;
	uint8_t lightsensor=0b00100000;
	uint8_t high_byte=0b00010000;
	uint8_t low_byte=0b00001000;
  
    while(1)
    {
		switch(PIND){
			case 0b11111110:
				PORTB=0b00000000;
				i2c_master_start();
				i2c_master_write(0xE0);
				i2c_master_write(0x00);
				i2c_master_write(0x51);
				i2c_master_stop();
				break;
			
			case 0b11111101:
				i2c_master_start();
				i2c_master_write(0xE0);
				i2c_master_write(0x03);
				i2c_master_stop();
				//lightsensor=i2c_master_read(0);
				//high_byte=i2c_master_read(0);
				i2c_master_start();
				i2c_master_write(0xE1);
				low_byte=i2c_master_read(0);
				i2c_master_stop();
				break;
			
			case 0b01111111:
				PORTB=lightsensor;
				break;
			
			case 0b10111111:
				PORTB=high_byte;
				break;
				
			case 0b11011111:
				PORTB=low_byte;
				break;
			
			default: 
				PORTB=0b11111111;
				
	
		}					
    }
	
}

Es wäre super, wenn mir mal jemand auf die Sprünge helfen könnte, da ich jetzt schon seit Tagen versuche, dass sich mein Sensor mit meinem µC unterhalten kann!

Vielen Dank schon mal im voraus!


Gruß
Andreas
 

Anhänge

  • MC_Prog_Ultra.c
    7,5 KB · Aufrufe: 26

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)