Guten Morgen,

dieses Problem ist immer noch aktuell und benötigt eine Lösung. Da ich zur Zeit für andere Projekte auf Teile warte habe ich selbst noch mal etwas Zeit investiert und bin ein Stück weiter. Die erste Erkenntnis nach genauer Studie des Datenblattes ist, dass der Master den Takt für die ISP-Schnittstelle per Software selbst generieren muss. Das finde ich schade. Ich dachte ich schiebe mein Datenbyte ins USIDR Register und setze ein Flag "Start" und erhalte dann, wie von RS232 gewohnt, einen Interrupt sobald die Übertragung abgeschlossen ist.
Aber vielleicht finde ich da noch eine Lösung. (Ich hoffe, dass ich das im Datenblatt noch übersehen habe)

Auf jeden Fall habe ich den Tiny25 zum Master gemacht mit folgendem Code:
Code:
#define AVRGCC
#include <avr/io.h>
#include <util/delay.h>
#include <compiler.h>
//F_CPU = 1000000
U8 ISP_send (U8 value)
{
 USISR |= (1<<USIOIF);
 USICR = (1<<USIWM0) | (1<<USITC);
 USIDR = value;
 while ((USISR & (1<<USIOIF)) == 0)
 {
  USICR = (1<<USIWM0) | (1<<USITC) |(1<<USICLK);
  _delay_ms (100);
  USICR = (1<<USIWM0) | (1<<USITC);
  _delay_ms (100);
 }
 return (USIDR);
}
int main (void)
{
 DDRB =  0b00000110;
 PORTB = 0b00000000;
 U8 value = 'A';
 while (1)
 { 
  ISP_send (value++);
  if (value > 'Z')
   value = 'A';
  _delay_ms (5000);
 }
 return (0);
}
Es wird mit sehr langsam Takt die Buchstaben des Alphabets mit jeweils 5 Sekunden Pause zwischen den Buchstaben gesendet, damit man die Bits quasi noch mal dem Auge verfolgen kann. Das scheint zu funktionieren, zumindest tut sich was auf den Datenleitungen. Hier mal ein Video:

http://www.car-mp3.de/RNetz/ISP.zip

Die grün LED ist der Takt und gelb die Daten. Die linke/obere Platine ist der Master mit dem Tiny25. Rechts/unten ist das ISP/RS232-Interface mit dem Tiny2313 als Slave. Hier der Code für das Interface:

Code:
#define AVRGCC
#include <avr/io.h>
#include <compiler.h>
#include <avr/interrupt.h>
//F_CPU = 8000000
#define BAUD     9600L
#define UBRRValue    (F_CPU / (BAUD * 16) - 1)
#define LED_ge_0    PORTB = ~(~PORTB | (1<<PB0))
#define LED_ge_1    PORTB = (PORTB | (1<<PB0))
#define LED_gn_0    PORTB = ~(~PORTB | (1<<PB1))
#define LED_gn_1    PORTB = (PORTB | (1<<PB1))
#define RS232ready    ((UCSRA & (1<<UDRE)) != 0)
void sendNumber (U32 Number, bool addCR)
{
 if (Number == 0)
 {
  while ( !(UCSRA & (1<<UDRE)));
  UDR = '0';
 }
 else
 {
  U32  ZifferGrundWert = 1000000000;
  bool ZifferWert;
  bool started = FALSE;

  while ((Number > 0) | (started & (ZifferGrundWert > 0)))
  {
   if (ZifferGrundWert == 1)
   {
    ZifferGrundWert = 0;
    ZifferWert = Number;
    Number = 0;
   }
   else
   {
    ZifferWert = 0;
   
    while (Number >= ZifferGrundWert)
    {
     Number = Number - ZifferGrundWert;
     ZifferWert++;
    }
    ZifferGrundWert = ZifferGrundWert / 10;
   }
 
   while ( !(UCSRA & (1<<UDRE)));
   if ((ZifferWert > 0) | started)
   {
    UDR = '0' + ZifferWert;
    started = TRUE;
   }
   else
   {
    if (started)
     UDR = '0';
   }
  }
 }
 if (addCR)
  sendMsg ("\r\n", FALSE);
}
ISR (USI_OVERFLOW_vect)
{
 USISR |= (1<<USIOIF);
 sendNumber (USIDR, TRUE);
}
int main (void)
{
 DDRB =  0b00000011;  // Alternativ: DDRB =  0b00100011; Richtig müsste es eigentlich 0b01000011 sein
 PORTB = 0b00000000;
 
 DDRD =  0b01000000;
 PORTD = 0b00000000;
 UCSRB = (1<<RXCIE) | (1<<TXEN) | (1<<RXEN);
 UCSRC = (1<<UCSZ1) | (1<<UCSZ0);
 UBRRH = (U8)(UBRRValue>>8);
 UBRRL = (U8)UBRRValue;
 USISR |= (1<<USIOIF);
 USICR = (1<<USIWM0) | (1<<USICS1) | (1<<USIOIE);
 sei ();
 while (1)
 {
  if ((PINB & 1<<PB7) == 0)
   LED_gn_0;
  else
   LED_gn_1;
  if ((PINB & 1<<PB6) == 0)
   LED_ge_0;
  else
   LED_ge_1;
 }
 return (0);
}
Wie man sieht werden die Leds im Code geschaltet und hängen nicht direkt an den Datenleitungen. Es kommt also was am Slave an. Und wenn der Master das Datenbyte übertragen hat wird auch der USI_OVERFLOW_vect Interrupt ausgelöst. Die ISP-Initialisierung ist zumindest teilweise korrekt. Nur leider ist der empfangene Datenwert immer 255. Wenn ich die Alternative DDRB Initialisierung, wie im Code kommentiert verwende empfange ich immer als Datenwert 0.

Es scheint so, als ob die Datenleitungen noch vertauscht werden müssen. Das zeigt auch die Initialisierung von DDRB. Normalerweise müsste es ja 0b01000011 heißen. Dann bleibt aber die gelbe LED dunkel und die beiden Atmels kämpfen mit ihren Ausgängen "gegeneinander".
Ich habe es im Datenblatt leider nicht gefunden: Kann man die ISP-Schnittstelle so konfigurieren, dass die Pins als ISP-Slave verwendet werden? Also MOSI und MISO vertauscht? Müsste ja eigentlich gehen, da die Leitungen ja schon so heißen und man einfach 1:1 durchverdrahten kann.

Viele Grüße
Andreas