Ronny10
27.05.2006, 16:20
Wie ich in einem anderen Beitrag in diesem Forum berichtete, ist es ja durch meinen neuen Bootloader für den ASURO möglich, den Resonator auszulöten und die freigewordenen Pins für eine Software-I2C-Schnittstelle zu nutzen (PB6=SDA/PB7=SCL). Da ich gerne an meinem ASURO analoge Abstands-Sensoren von Sharp betreiben möchte stand ich vor dem Problem, aber wo anschliessen? Auf die Linienverfolgung will ich nicht verzichten, deshalb schied ein Auslöten der Bauteile der Linienverfolgung, um an den dann freiwerdenden analogen Eingängen die Astands-Sensoren anzuschliessen, für mich aus. AD-Wandler für den I2C-Bus sind auch nicht gerade billig. Also habe ich an den I2C-Bus einen zusätzlichen ATmega8L angeschlossen (kostet 2,70 Euro) der mit einer von mir geschriebenen Software jetzt als I2C-Slave arbeitet. Damit habe ich jetzt zusätzlich 4 ADC-Eingänge und 16 digitale I/O-Pins zur Verfügung. Wenn das mal nicht ausreichen sollte, kann man ja noch einen ATmega8-Slave mit einer anderen Slave-Adresse draufpacken. Den ATmega8-Slave habe ich auf einer der Experimentier-Platinen des ASURO aufgebaut. Ich werde Henk mal bitten, die Software für den I2C-Slave, einige Programmbeispiele und die Bilder von der Erweiterungs-Platine auf seiner Homepage bereitzustellen. Evtl. hat Arexx ja auch Interesse, eine Erweiterungsplatine speziell für diese Anwendung zu erstellen? Ein kleines Anwendungsbeispiel (dieses Programm erzeugt beim Slave-ATmega8 an PB1 von PORTB ein Rechtecksignal):
#include <avr/io.h>
#include "i2cmaster.h"
#include "twi_register.h"
#define BIT(n) (1<<(n))
/***************************************
sendet einen befehl plus parameter
zum m8-slave
****************************************/
void twi_send( unsigned char befehl, unsigned char parameter )
{
i2c_start_wait(TWI_ADR+I2C_WRITE); // verbindung aufbauen
i2c_write( befehl ); // befehl für den slave
i2c_write( parameter ); // parameter des befehls
i2c_stop(); // verbindung beenden
}
/******************
hauptprogramm
*******************/
int main(void)
{
i2c_init(); // i2c initialisieren
twi_send( TWI_SET_DDRB, BIT(PB1) );// pinb1 von portb = ausgang
for( ; ; ) // endlosschleife
{
twi_send( TWI_SET_PINB, PB1 ); // pinb1 von portb auf h setzen
twi_send( TWI_RES_PINB, PB1 ); // pinb1 von portb auf l setzen
}
return(0);
}
Zur Erklärung: Der I2C-Atmega8-Slave wartet in der I2C-Interruptroutine auf einen Befehl vom Master und einen evtl. dem Befehl zugehörenden Parameter. Somit ist es möglich, beim Slave Portpins als Aus-oder Eingänge zu programmieren, den Zustand der Portpins oder der ADC-Eingängen zu lesen, usw.
Das Programm erzeugt am PB1 des Slaves ein Signal von ca. 1,5KHz. D.h. für das Setzen oder Rücksetzen eines Portpins benötigt das Programm ca. 0,3ms was für Reaktionen auf irgenwelche externen Ereignisse dicke ausreicht.
Viele asurorische Grüße, Peter (Ronny10 ehem. Peli51)
#include <avr/io.h>
#include "i2cmaster.h"
#include "twi_register.h"
#define BIT(n) (1<<(n))
/***************************************
sendet einen befehl plus parameter
zum m8-slave
****************************************/
void twi_send( unsigned char befehl, unsigned char parameter )
{
i2c_start_wait(TWI_ADR+I2C_WRITE); // verbindung aufbauen
i2c_write( befehl ); // befehl für den slave
i2c_write( parameter ); // parameter des befehls
i2c_stop(); // verbindung beenden
}
/******************
hauptprogramm
*******************/
int main(void)
{
i2c_init(); // i2c initialisieren
twi_send( TWI_SET_DDRB, BIT(PB1) );// pinb1 von portb = ausgang
for( ; ; ) // endlosschleife
{
twi_send( TWI_SET_PINB, PB1 ); // pinb1 von portb auf h setzen
twi_send( TWI_RES_PINB, PB1 ); // pinb1 von portb auf l setzen
}
return(0);
}
Zur Erklärung: Der I2C-Atmega8-Slave wartet in der I2C-Interruptroutine auf einen Befehl vom Master und einen evtl. dem Befehl zugehörenden Parameter. Somit ist es möglich, beim Slave Portpins als Aus-oder Eingänge zu programmieren, den Zustand der Portpins oder der ADC-Eingängen zu lesen, usw.
Das Programm erzeugt am PB1 des Slaves ein Signal von ca. 1,5KHz. D.h. für das Setzen oder Rücksetzen eines Portpins benötigt das Programm ca. 0,3ms was für Reaktionen auf irgenwelche externen Ereignisse dicke ausreicht.
Viele asurorische Grüße, Peter (Ronny10 ehem. Peli51)