PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Mit AtMega128 per I2C einen PIC16F872 (SD20 ansprechen?



klucky
18.12.2004, 20:40
Wie spreche ich in C einen SD20 an? Bzw wie geb ich von dem Atmel einen Befehl an den SD20 das sich ein servo in eine bestimmte position bewegt? Oder wie lese ich z.b. werte von einem Sensor (z.b. Ulraschall aus)? Hat wer von euch vielleicht nen beispiel?

THX für eure hilfe!

MFG Klucky

Thorsten
18.12.2004, 21:47
Hi,

hier mal ein codeschnipsel aus der Bastelkiste *g*:

Die Dateien twi_master.c und .h sind die Appnote von Atmel
nur für den gcc Angepasst.
twi.c zeigt wie man Daten von von einen I²C Slavet ließt.
Ist aber alles genau in der Appnot (auch im Archiv) bechrieben.
Wenn du noch Fragen hasst meld dich einfach.


viel Spass
Thorsteb

klucky
20.12.2004, 14:56
Erstmal einmal den gesamten Code damit ihrs im Zusammenhang habt:



/* motormodul.c

************************************************** *

************************************************** *
$Log:$


*/
#include <avr/io.h>

#include <avr/interrupt.h>
#include <avr/signal.h>

#include <inttypes.h> /* fuer uint32_t */

#include <avr/delay.h>

#include "twi.h"
#include "TWI_Master.h"


#define LED1 PC0
#define LED2 PC1
#define LED_PORT PORTC
#define KEY1 PC2
#define KEY2 PC3
#define KEY_PORT PINC
#define ENABLE PB0
#define ENABLE_PORT PINB

#define MOTOR_PORT PORTB
#define MOTOR1_RICHTUNG PB3
#define MOTOR1_PWM PB1
#define MOTOR2_RICHTUNG PB4
#define MOTOR2_PWM PB2

#define SWAP(port, pin) (port ^= _BV(pin))

#define READ 1
#define WRITE 0

void init_io(void);


/* Adresse vom Slave */
BYTE slave_adress = 0x40;
BYTE buf[4];

int main (void)
{


/* Ports einstellen */
init_io();


/* TWI Initialisieren */
TWI_Master_Initialise();

/* Interrupts global aktivieren */
sei();




/* Hauptprogramm */
for(;;)
{

/* Ausgänge auf High setzen */
buf[0] = slave_adress | WRITE;
buf[1] = 0xFF;
TWI_Start_Transceiver_With_Data( buf, 2);

/** Eingänge lesen **/
buf[0] = slave_adress | READ;
TWI_Start_Transceiver_With_Data( buf, 1); // Adresse senden
/* Daten lesen, in buf[0] steht die Slave Adresse, danach
kommen die gelesenen Daten */
TWI_Get_Data_From_Transceiver( buf, 2);



_delay_loop_2(16000);

if( buf[1] == 0xFF)
sbi( LED_PORT, LED1);
else
cbi( LED_PORT, LED1);

}
}


void init_io(void)
{
/* PB0 als Eingang alle anderen als Ausgang */
DDRB = _BV(PB1)| _BV(PB2)| _BV(PB3)| _BV(PB4)| _BV(PB5);
PORTB = _BV(PB0); /* Pull-Up PB0 ein */

DDRC = _BV(LED1)| _BV(LED2); /* PC0 und 1 als Ausgang */
PORTC = _BV(KEY1)| _BV(KEY2); /* Pull-Ups Eingang */

DDRD = 0x00; /* Port D als Ausgang */
}


So wie funtktioniert das mit dem buf[] das ist wenn ich es richtig sehe ein array und wenn ich dann dieses stück code sehe:



/* Ausgänge auf High setzen */
buf[0] = slave_adress | WRITE;
buf[1] = 0xFF;
TWI_Start_Transceiver_With_Data( buf, 2);


da werden 2 werte in den array geschrieben aber nur einer übertragen warum oder seh ich da etwas falsch?

Thorsten
20.12.2004, 15:26
Jup buf ist ein Array

Mit:

TWI_Get_Data_From_Transceiver( buf, 2);
Übergibst du die Startadresse (also die Adresse wo buf anfängt)
an die Funktion.

siehe twi_master.h:

unsigned char TWI_Get_Data_From_Transceiver( unsigned char *, unsigned char );

Siehe auch http://www.pronix.de/modules/C/openbook/c_programmierung_14.php#5 zur Übergabe von Arrays an Funktionen.

Mit der 2 die du Übergibst, sagst du der Funktion die Größe des Arrays.

Zum lesen von Daten schreibst du also in buf[0] die Slave Adresse.
Die Größe vom Array muss dann Mindestens
Anzahl der zu lesenden bytes+1 sein. Das entspricht dann auch dem
2 Parameter der Funktion.

Die ersten gelesenen Daten stehen dann in buf[1] die nächsten in buf[2] usw.


Thorsten

klucky
20.12.2004, 19:10
buf[0] = slave_adress | WRITE;
buf[1] = 0xFF;
TWI_Start_Transceiver_With_Data( buf, 2);


Das habe ich jetzt glaub ich soweit verstanden es ist ein Array der die Daten übergibt und ich bei 0 die 7Bit lange adresse des Slaves rein und in das Letzte bit ob gelesen oder geschrieben werden soll. Dann wird mit dem Befehl aus der Libary die Übertragung gestartet.

Naja aber wenn ich jetzt z.b. daten abfrage woher weiß der dann wo er die daten in dem Controller lesen soll?

Und ich wollte jetzt z.b. meinen SD20 (0xC2) ansprechen bei dem muss ich in die register 1 - 20 einen wert von 0 bis 255 schreiben ich weiß jetzt zwar wied ich die adresse angebe und sage dass er schreiben soll aber ich weiß noch net wie ich ihm sage wohin er schreiben soll, wie sag ich ihm er soll in register schreiben und wie er soll den wert direkt an einen ausgang ausgeben?

Thorsten
21.12.2004, 13:39
Ich hab mit dem SD20 noch nicht gearbeitet, aber meistens schreibt man
die Slave Adresse, dann die Registernummer und dann die Daten.

Also z.B.

buf[0] = SD20_ADRESS | WRITE;
buf[1] = register; // z.B 0x01 für Register 1
buf[2] = data; // servostellung
TWI_Start_Transceiver_With_Data(buf, 3);


Wenn du Daten lesen willst musst du erst die Registeradresse senden
und dann die Daten lesen:


buf[0] = SD20_ADRESS | WRITE;
buf[1] = register; // z.B 0x01 für Register 1
TWI_Start_Transceiver_With_Data(buf, 2); /* Slave Adresse und Registernummer senden */
TWI_Get_Data_From_Transceiver(buf, 2); /* Slave Adresse senden und Daten
lesen */



Thorsten

klucky
21.12.2004, 13:52
Aso also kommen beim schreiben die daten aus dem nachfolgenden platz im array in das register wenn ich also könnt ich auch mehrere auf einmal übertragen ... ?



buf[0] = SD20_ADRESS | WRITE;
buf[1] = register; // z.B 0x01 für Register 1
buf[2] = data; // servostellung1
buf[3] = register; // z.B 0x02 für Register 2
buf[4] = data; // servostellung2
TWI_Start_Transceiver_With_Data(buf, 3);



Und beim lesen werden die daten dann in das register geschrieben in dem die adresse stand von der es gelesen werden sollte?

Thorsten
21.12.2004, 14:25
Aso also kommen beim schreiben die daten aus dem nachfolgenden platz im array in das register wenn ich also könnt ich auch mehrere auf einmal übertragen ... ?
Also irgendwie steig ich da nicht durch *g*

Aber ich sag mal:
Du kannst mehrere Daten übertragen, allerdings weiß ich nicht
genau wie das beim SD20 ist. Allgemein schreibst du die Daten
in buf[n], der zweite Parameter gibt dann an wieviel Daten gesendet
werden (immer -1, buf[0] enthält ja die Slave-Adress).


Und beim lesen werden die daten dann in das register geschrieben in dem die adresse stand von der es gelesen werden sollte?
Beim lesen stehen die ersten gelesen daten in buf[1], die nächsten in
buf[2]...
In buf[0] steht die Slave Adresse. Die Anzahl der zu lesenden Daten gibt wieder
der 2te Parameter an.

[/quote]