Hallo,

ich bin an der Entwicklung eines Programms für einen Tiny25. Ich bentöige dabei Werte, die ich über den integrierten ADC einlese irgendwo angezeigt. Da der Tiny25 so wenige Pins hat habe ich mir überlegt diese Werte über die ISP-Schnittstelle zu senden, da ich diese eh "onboard" habe um den Controller darüber zu programmieren.

Meine Idee war es also einen kleinen Umsetzer zu bauen, der mir die ISP-Daten auf eine serielel Schnittstelle übersetzt und umgekehrt. Für dieses Projekt habe ich einen Tiny2313 verwendet, da der noch rumlag. Die ISP-Schnittstelle ist ebenfalls so verdrahtet, dass ich den Tiny2313 darüber programmieren kann mit der Ausnahme das ich die Reset-Leitung per Jumper trennen kann und die Reset-Leitung von "außen" auf einen Eingangspin geht, damit ich die ISP-Schnittstelle abschalten kann solange der Tiny25 programmiert wird. Wenn also der externe Reset auf Low geht möchte ich die ISP-Schnittstelle abschalten.

Leider ist aus den Datenblättern für mich nicht so ganz ersichtlich wie ich das ganze programmieren soll. Den Umsetzer mit dem Tiny2313 habe ich mir als ISP-Slave gedacht. Hier mal mein Code dafür:

Code:
#define AVRGCC/**
ISP_RS232:
Interface um Daten zwischen ISP und RS232 zu übersetzen.
IO:
PB0  out   LED gelb (Daten RS232 vorhanden)
PB1  out   LED grün (Daten ISP vorhanden)
PB2  frei
PB3  frei
PB4  frei
PB5  MOSI
PB6  MISO
PB7  SCK
PD0  RXD
PD1  TXD
PD2  in   disable (ext. Reset)
PD3  frei
PD4  frei
PD5  frei
PD6  Out   LED rot (Buffer Überlauf)
**/
 
#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 BufferSize    16
#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 LED_rt_0    PORTD = ~(~PORTD | (1<<PD6))
#define LED_rt_1    PORTD = (PORTD | (1<<PD6))
#define disable     ((PIND & 1<<PD2) == 0)
#define RS232ready    ((UCSRA & (1<<UDRE)) != 0)
#define AccessRead    0
#define AccessWrite    1
#define BufferRS232    0
#define BufferISP    1
 
volatile bool currentState = FALSE;
volatile U8  InBuffer[2][BufferSize];
volatile U8  Pointer[2][2];
 

void sendMsg (char *Msg, bool addCR)
{
 while (*Msg != 0)
 {
  while ( !(UCSRA & (1<<UDRE)));
  UDR = *Msg++;
 }
 if (addCR)
  sendMsg ("\r\n", FALSE);
}
 
void incPointer (U8 Buffer, U8 Access)
{
 if (++Pointer[Buffer][Access] >= BufferSize)
  Pointer[Buffer][Access] = 0;
}
bool BufferDone (U8 Buffer)
{
 return (Pointer[Buffer][AccessRead] == Pointer[Buffer][AccessWrite]);
}
void add2Buffer (U8 Buffer, U8 value)
{
 U8 tmp = Pointer[Buffer][AccessWrite];
 if (++tmp >= BufferSize)
  tmp = 0;
 
 if (tmp != Pointer[Buffer][AccessRead])
 {
  Pointer[Buffer][AccessWrite] = tmp;
  InBuffer[Buffer][tmp] = value;
 }
 else
  LED_rt_1;
}
U8 readBuffer (U8 Buffer)
{
 return (InBuffer[Buffer][AccessRead]);
}
 
ISR (USART_RX_vect)
{
 add2Buffer (BufferRS232, UDR);
}
 
ISR (USI_OVERFLOW_vect)
{
 U8 value = USIDR;
 if (currentState)
 {
  add2Buffer (BufferISP, value);
  if (!BufferDone (BufferRS232))
   incPointer (BufferRS232, AccessRead);
  if (!BufferDone (BufferRS232))
   USIDR = readBuffer (BufferRS232);
  else
   USIDR = 0;
 }
 else
  LED_rt_1;
}
 
int main (void)
{
 DDRB =  0b00000011;
 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;
 Pointer[BufferRS232][AccessRead] = 0;
 Pointer[BufferRS232][AccessWrite] = 0;
 Pointer[BufferISP][AccessRead] = 0;
 Pointer[BufferISP][AccessWrite] = 0;
 sei ();
 
 sendMsg ("", TRUE);
 sendMsg ("RESET", TRUE);
 
 while (1)
 {
  if (disable)
  {
   if (currentState)
   {
    USICR = 0;
    sendMsg ("TARGET RESET", TRUE);
   }
   currentState = FALSE;
  }
  else
  {
   if (!currentState)
   {
    USICR = (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) |(1<<USIOIE);
    sendMsg ("TARGET START", TRUE);
    if (!BufferDone (BufferRS232))
     USIDR = readBuffer (BufferRS232);
    else
     USIDR = 0;
   }
   currentState = TRUE;
  }
 
 
 
  if (RS232ready & !BufferDone (BufferISP))
  {
   UDR = readBuffer (BufferISP);
   incPointer (BufferISP, AccessRead);
  }
 
  if (BufferDone (BufferISP))
   LED_gn_0;
  else
   LED_gn_1;
  if (BufferDone (BufferRS232))
   LED_ge_0;
  else
   LED_ge_1;
 }
 
 return (0);
}
Die RS232-Kommunikation läuft. RESET wird gemeldet und TARGET RESET bzw. TARGET START wird auch gemeldet. Und wenn ich etwas sende geht die gelbe LED als Anzeige an, dass etwas im RS232-Buffer vorhanden ist. (Nach 16 Bytes geht dann auch die rote LED an)

Der Tiny25 soll dann als ISP-Master funktionieren. Hier mal mein Test-Code um etwas zu senden:

Code:
#define AVRGCC
/**
Voltage Detector:

IO:
PB0  MOSI
PB1  MISO out   LED
PB2  SCK
PB3  analog in (ADC3)
PB4  frei
**/
 
#include <avr/io.h>
#include <util/delay.h>
#include <compiler.h>
 
//F_CPU = 1000000
#define LED0      PORTB = ~(~PORTB | (1<<PB1))
#define LED1      PORTB = (PORTB | (1<<PB1))
 
int get_analog_input (void)
{
 ADCSRA |= (1<<ADSC);
 while ((ADCSRA & (1<<ADSC)) > 0);
 return ((ADCH<<8) | ADCL) - 512;
}
 
int main (void)
{
 DDRB =  0b00000010;
 PORTB = 0b00000000;
 DIDR0 = (1<<ADC3D);
 ADMUX = (1<<REFS1) | (1<<REFS2) | (1<<MUX1) | (1<<MUX0);
 ADCSRA = (1<<ADEN);
 USICR = (1<<USIWM0);

USIDR = 'A';
U8 i1;
for (i1 = 0; i1 < 8; i1++)
{
 USICR |= (1<<USICLK);
 _delay_ms (1);
}

 while (1);

 return (0);
}
Leider kommt beim Umsetzer nichts an (grüne LED bleibt aus). Wenn ich den Tiny25 programmiere erkennt der Umsetzer aber brav die Reset-Leitung und meldet "TARGET RESET" und "TARGET START".

Wo könnte mein Problem liegen? Liegt es an der Verdrahtung? Kann ich vielleicht gar keine Kommunikation bei einer 1:1 verdrahteten ISP-Schnittstelle aufbauen? So wie ich das Verstehe müsste es gehen, da die Pins ja MISO (Master In Slave Out) und MOSI (Master Out und Slave In) heißen. Allerdings habe ich in der Beschreibung der Register für die USI-Schnittstelle nirgendwo gesehen wie ich Master und Slave konfiguriere.

Viele Grüße
Andreas