AVR: ISP über serielle Schnittstelle selber programmieren

D

Dominik Schmidt

Guest
Moin !

Wir arbeiten gerade an einem kleinen Projekt. Und zwar ein Datenlogger für
den Modellbau. Das ganze funzt auch soweit schon ganz gut.
(http://www.ganzfix.de/MiniLogger/) Mein Part ist dabei die Software welche
in Delphi geschrieben ist (http://www.pibros.de/LogView/). Auch die funzt
mitlerweile ganz sauber.
Nun kam die Idee auf, aus dieser Software den AVR zu Programmieren. Dazu
steht entweder die PORT.DLL oder die RSAPI.DLL bereit, welche auch sauber
laufen (wir haben damit I2C über COM1 realisiert).
Nur an dem ISP beisse ich mir im Moment die Zähne aus. Genaugenommen geht es
um eine Funktion, die Daten zum AVR sendet und gleichzeitig empfängt. Davon
könnte man alles weitere ableiten. Ich habe am Ende mal meine aktuelle
Funktion angehängt.
Die Frage wäre nun, wer hat sich schonmal an dieses Thema rangewagt und
könnte mir evtl. mit einer Funktion oder ein paar Tips helfen
(Programmiersprache ist dabei fast egal).
Und um es vorwegzunehmen... PonyProg ist bekannt und sorry wenn das Thema
nicht 100% in diese Group passt, aber die Jungs ...delphi.misc können da
sicher nicht so viel weiterhelfen :)

Grüße Dominik

Ok, hier mein Quellcode. Die Schaltung dazu findet man übrigens hier (weit
unten):
http://www.rclineforum.de/forum/thread.php?threadid=61463&sid=&threadview=0&hilight=&hilightuser=&page=11

// #### Leitungen: MOSI (Data In) = 9 RI (Einlesen) #####
// #### 4 DTR (Ausgeben) #####
// #### MISO (Data Out) = 8 CTS (Einlesen) #####
// #### SCK (Serial Clock) = 6 DSR (Einlesen) #####
// #### 7 RTS(0|1) (Ausgeben) #####
// #### Reset = 3 TXD(0|1) #####
//Byte auf den Bus ausgeben und Byte lesen
//When WRITING serial data to the ATtiny26, data is clocked on the RISING
EDGE of SCK.
//When READING data from the ATtiny26, data is clocked on the FALLING EDGE
of SCK.
Function ISPInOut(Wert:integer): Integer;
var n, bitwert, erg:integer;
begin
bitwert:= 128;
erg := 0;
RTS(0); // SCK auf 0 setzen
Delay(5);
For n:= 1 To 8 do
begin
If (Wert And bitwert) = bitwert Then
begin // Wert (2^x) kommt in der Zahl vor (MOSI Bit auf 1 [DTR(1)])
DTR(1); // MOSI Bit setzen
RTS(1); // Takt auf 1 setzen
delay(1);
end
Else
begin // Wert kommt nicht in der Zahl vor (MOSI Bit auf 0 [DTR(0)])
DTR(0); // MOSI Bit löschen
RTS(1); // Takt auf 1 setzen
delay(1);
End;
RTS(0);
If CTS = 1 Then erg := erg + bitwert;
//delay(1);
bitwert := bitwert div 2;
end;
ISPInOut := erg;
end;
 
Ist das der ganze Quelltext den du zum Programmieren von dem AVR hast?
Wenn ja, das kann so nicht gehen ...

Hier ein kleines Programm, das ich vor 5 Jahren mal unter Borland Pascal
geschrieben habe und erfolgreich AVRs programmiert -
es sind sicher viele Sachen drin, die du brauchen kannst. (War nur mal
schnell so hingeschustert und schaut nicht besonders toll aus - geht aber
....)

uses crt,dos;

const
waittime=1;

var
f:file of byte;
t:text;
s:string;
w:word;
hibyte,lobyte:byte;
l:longint;
LPT_Data:byte;
b:byte;
LPT_status:byte;
LPT_IO:byte;
current:word;

function bin(s:string):byte;
var
c:byte;
b:byte;
res:byte;
begin
c:=128;
res:=0;
for b:=1 to 8 do begin
if s='1' then inc(res,c);
c:=c shr 1;
end;
bin:=res;
end;

procedure error(msg:string);
begin
writeln;
writeln(msg);
halt;
end;

procedure clk;
begin
LPT_Data:=LPT_Data or 128;
Port[$378]:=LPT_Data;
LPT_Data:=LPT_Data and not 128;
Port[$378]:=LPT_Data;
end;

procedure setreset;
begin
LPT_DATA:=LPT_DATA and not 1;
port[$378]:=LPT_DATA;
end;

procedure clrreset;
begin
LPT_DATA:=LPT_DATA or 1;
port[$378]:=LPT_DATA;
end;

procedure setSCK;
begin
LPT_DATA:=LPT_DATA or 128;
port[$378]:=LPT_DATA;
end;

procedure setPower;
begin
LPT_DATA:=LPT_DATA or 4;
LPT_DATA:=LPT_DATA or 2;
port[$378]:=LPT_DATA;
end;


procedure clrSCK;
begin
LPT_DATA:=LPT_DATA and not 128;
port[$378]:=LPT_DATA;
end;

procedure setDataBit;
begin
LPT_DATA:=LPT_DATA or 32;
port[$378]:=LPT_DATA;
end;

procedure clrDataBit;
begin
LPT_DATA:=LPT_DATA and not 32;
port[$378]:=LPT_DATA;
end;

procedure sendbyte(b:byte);
var
c:byte;
v:byte;
begin
c:=128;
for v:=1 to 8 do begin
if b and c=c then setDataBit else ClrDatabit;
c:=c shr 1;
SetSCK;
asm
mov cx,$ffff
repnz
end;
{ delay(waittime);}
clrsck;
asm
mov cx,$ffff
repnz
end;
{ delay(waittime);}
end;
delay(1);
end;

procedure AVRStart;
begin
setpower;
clrsck;
setreset;
delay(200);
clrreset;
delay(200);
setreset;
delay(200);
end;

procedure enableprogramming;
begin
sendbyte(bin('10101100'));
sendbyte(bin('01010011'));
sendbyte(bin('00000000'));
sendbyte(bin('00000000'));
end;

procedure ChipErase;
begin
sendbyte(bin('10101100'));
sendbyte(bin('10000000'));
sendbyte(bin('00000000'));
sendbyte(bin('00000000'));
delay(20);
end;

procedure WriteMEM(addr:word;b:word);
begin
sendbyte(bin('01000000')); { Lobyte programmieren }
sendbyte(hi(addr)); { Hi-Byte von Adresse angeben }
sendbyte(lo(addr)); { Lo-Byte von Adresse angeben }
sendbyte(lo(b)); { Lo-Byte von Daten schreiben }
delay(3);
sendbyte(bin('01001000')); { Lobyte programmieren }
sendbyte(hi(addr)); { Hi-Byte von Adresse angeben }
sendbyte(lo(addr)); { Lo-Byte von Adresse angeben }
sendbyte(hi(b)); { Lo-Byte von Daten schreiben }
delay(3);
end;


begin
clrscr;
if paramstr(1)=''then begin
writeln('PROGRAM <filename>');
halt;
end;
assign(f,paramstr(1)+'.BIN');
{$i-}
reset(f);
{$i+}
if ioresult<>0 then error('Cannot create '+paramstr(1)+'.BIN');

AVRStart;
enableprogramming;
chiperase;
delay(10);
clrReset;
delay(5);
setreset;
enableprogramming;
current:=0;
delay(200);
while not eof(f) do begin
read(f,lobyte);
read(f,hibyte);

asm
mov al,lobyte
mov ah,hibyte
mov w,ax
end;

writemem(current,w);
write('Programming Adr.',current:6,#13);
inc(current);
end;
writeln;
writeln;
close(f);
clrreset;

end.

Viel Erfolg damit ...

Gruß

Thomas


"Dominik Schmidt" <schmidom@t-online.de> schrieb im Newsbeitrag
news:cg813e$e6s$07$1@news.t-online.com...
Moin !

Wir arbeiten gerade an einem kleinen Projekt. Und zwar ein Datenlogger für
den Modellbau. Das ganze funzt auch soweit schon ganz gut.
(http://www.ganzfix.de/MiniLogger/) Mein Part ist dabei die Software
welche
in Delphi geschrieben ist (http://www.pibros.de/LogView/). Auch die funzt
mitlerweile ganz sauber.
Nun kam die Idee auf, aus dieser Software den AVR zu Programmieren. Dazu
steht entweder die PORT.DLL oder die RSAPI.DLL bereit, welche auch sauber
laufen (wir haben damit I2C über COM1 realisiert).
Nur an dem ISP beisse ich mir im Moment die Zähne aus. Genaugenommen geht
es
um eine Funktion, die Daten zum AVR sendet und gleichzeitig empfängt.
Davon
könnte man alles weitere ableiten. Ich habe am Ende mal meine aktuelle
Funktion angehängt.
Die Frage wäre nun, wer hat sich schonmal an dieses Thema rangewagt und
könnte mir evtl. mit einer Funktion oder ein paar Tips helfen
(Programmiersprache ist dabei fast egal).
Und um es vorwegzunehmen... PonyProg ist bekannt und sorry wenn das Thema
nicht 100% in diese Group passt, aber die Jungs ...delphi.misc können da
sicher nicht so viel weiterhelfen :)

Grüße Dominik

Ok, hier mein Quellcode. Die Schaltung dazu findet man übrigens hier (weit
unten):

http://www.rclineforum.de/forum/thread.php?threadid=61463&sid=&threadview=0&hilight=&hilightuser=&page=11

// #### Leitungen: MOSI (Data In) = 9 RI (Einlesen) #####
// #### 4 DTR (Ausgeben) #####
// #### MISO (Data Out) = 8 CTS (Einlesen) #####
// #### SCK (Serial Clock) = 6 DSR (Einlesen) #####
// #### 7 RTS(0|1) (Ausgeben) #####
// #### Reset = 3 TXD(0|1) #####
//Byte auf den Bus ausgeben und Byte lesen
//When WRITING serial data to the ATtiny26, data is clocked on the RISING
EDGE of SCK.
//When READING data from the ATtiny26, data is clocked on the FALLING EDGE
of SCK.
Function ISPInOut(Wert:integer): Integer;
var n, bitwert, erg:integer;
begin
bitwert:= 128;
erg := 0;
RTS(0); // SCK auf 0 setzen
Delay(5);
For n:= 1 To 8 do
begin
If (Wert And bitwert) = bitwert Then
begin // Wert (2^x) kommt in der Zahl vor (MOSI Bit auf 1 [DTR(1)])
DTR(1); // MOSI Bit setzen
RTS(1); // Takt auf 1 setzen
delay(1);
end
Else
begin // Wert kommt nicht in der Zahl vor (MOSI Bit auf 0 [DTR(0)])
DTR(0); // MOSI Bit löschen
RTS(1); // Takt auf 1 setzen
delay(1);
End;
RTS(0);
If CTS = 1 Then erg := erg + bitwert;
//delay(1);
bitwert := bitwert div 2;
end;
ISPInOut := erg;
end;
 
Moin Thomas!

Danke für deinen Quelltext. Leider komme ich da nicht so ganz mit den
Assemblerpassagen klar. Könntest du mir die erlären? Oder evtl. mal kurz
niederschreiben, wie das Senden/Empfangen theroretisch funktionieren sollte?
Das Datenblatt ist nicht so ergibig, oder ich interpretiere es falsch...

Der Quelltext ist natürlich nicht alles. Ich nutze die RSAPI.DLL um direkt
auf den seriellen Port zugreifen zu können. Das ganze Listing sieht im Mom
so aus:

// ###################################################################
// #### Versuch eines Atmel ISP Programmers #####
// #### #####
// #### 2004 by Dominik Schmidt #####
// #### #####
// #### Leitungen: MOSI (Data In) = 9 RI (Einlesen) #####
// #### 4 DTR (Ausgeben) #####
// #### MISO (Data Out) = 8 CTS (Einlesen) #####
// #### SCK (Serial Clock) = 6 DSR (Einlesen) #####
// #### 7 RTS(0|1) (Ausgeben) #####
// #### Reset = 3 TXD(0|1) #####
// #### #####
// #### Protzugriffe werden alle über RSAPI realisiert ! #####
// ###################################################################

// Serielle Schnittstelle
// Funktion Pin PC <> uC
// DCD 1 <--
// RXD 2 <--
// TXD 3 -->
// DTR 4 -->
// GND 5 -
// DSR 6 <--
// RTS 7 -->
// CTS 8 <--
// RI 9 <--

unit ISP_Progger;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, RSAPI, StdCtrls, Math;

type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

//Byte auf den Bus ausgeben und Byte lesen
//When WRITING serial data to the ATtiny26, data is clocked on the RISING
EDGE of SCK.
//When READING data from the ATtiny26, data is clocked on the FALLING EDGE
of SCK.
Function ISPInOut(Wert:integer): Integer;
var n, bitwert, erg:integer;
begin
bitwert:= 128;
erg := 0;
RTS(0); // SCK auf 0 setzen
Delay(5);
For n:= 1 To 8 do
begin
If (Wert And bitwert) = bitwert Then
begin // Wert (2^x) kommt in der Zahl vor (MOSI Bit auf 1 [DTR(1)])
DTR(1); // MOSI Bit setzen
RTS(1); // Takt auf 1 setzen
delay(1);
end
Else
begin // Wert kommt nicht in der Zahl vor (MOSI Bit auf 0 [DTR(0)])
DTR(0); // MOSI Bit löschen
RTS(1); // Takt auf 1 setzen
delay(1);
End;
RTS(0);
If CTS = 1 Then erg := erg + bitwert;
//delay(1);
bitwert := bitwert div 2;
end;
ISPInOut := erg;
end;

// ###################################################################
// #### Leitungen: MOSI (Data In) = 9 RI (Einlesen) #####
// #### 4 DTR (Ausgeben) #####
// #### MISO (Data Out) = 8 CTS (Einlesen) #####
// #### SCK (Serial Clock) = 6 DSR (Einlesen) #####
// #### 7 RTS(0|1) (Ausgeben) #####
// #### Reset = 3 TXD(0|1) #####
// ###################################################################
procedure TForm1.Button1Click(Sender: TObject);
//var info:string;
var i:integer;
begin
Memo1.Lines.Add(TimeToStr(Time) + ' # Port ' + Edit1.Text + ' geöffnet');
ComOpen(strtoint(Edit1.Text));

Memo1.Lines.Add(TimeToStr(Time) + ' # Initialisierung einleiten (Reset 0
und SCK auf 0)');
TXD(1);
RTS(0);

Memo1.Lines.Add(TimeToStr(Time) + ' # 100ms warten ...');
Delay(100);

Memo1.Lines.Add(TimeToStr(Time) + ' # Reset 1 / 100ms warten / Reset 0 /
100ms warten');
TXD(0);
Delay(100);
TXD(1);
Delay(100);
for i:=1 to 10 do
begin
Memo1.Lines.Add(inttostr(ISPInOut(172)));
Memo1.Lines.Add(inttostr(ISPInOut(83)));
Memo1.Lines.Add(inttostr(ISPInOut(0)));
Memo1.Lines.Add(inttostr(ISPInOut(0)));
end;

end;
end.

Greetz Dominik
 
* Dominik Schmidt <schmidom@t-online.de> [2004-08-21 19:34]:
Wir arbeiten gerade an einem kleinen Projekt. Und zwar ein Datenlogger für
den Modellbau. Das ganze funzt auch soweit schon ganz gut.
(http://www.ganzfix.de/MiniLogger/) Mein Part ist dabei die Software welche
in Delphi geschrieben ist (http://www.pibros.de/LogView/). Auch die funzt
mitlerweile ganz sauber.
Nun kam die Idee auf, aus dieser Software den AVR zu Programmieren. Dazu
steht entweder die PORT.DLL oder die RSAPI.DLL bereit, welche auch sauber
laufen (wir haben damit I2C über COM1 realisiert).
Nur an dem ISP beisse ich mir im Moment die Zähne aus. Genaugenommen geht es
um eine Funktion, die Daten zum AVR sendet und gleichzeitig empfängt. Davon
könnte man alles weitere ableiten. Ich habe am Ende mal meine aktuelle
Funktion angehängt.
Die Frage wäre nun, wer hat sich schonmal an dieses Thema rangewagt und
könnte mir evtl. mit einer Funktion oder ein paar Tips helfen
(Programmiersprache ist dabei fast egal).
also es gibt zwei gute OpenSource programmer: uisp und avrdude. Der
Quellcode ist frei verfügbar (allerdings Lizenz beachten!) und in C.
Müsste eigentlich weiterhelfen.

http://www.bsdhome.com/avrdude/
http://savannah.nongnu.org/projects/uisp/

Gruß,
Bernhard

--
"Ein Experte ist ein Mann, der hinterher genau sagen kann, warum
seine Prognose nicht gestimmt hat."
-- Winston Churchill
 
Hallo,

die Assemblerpassagen sind leicht erklärt -

asm
mov cx,$ffff
repnz
end;
Hier handelt es sich nur um eine einfache Warteschleife - ein äquivalent
wäre
for i:=1 to 65535 do ;

nur von den meisten compilern wird sowas immer gern wegoptimiert ... es gibt
unter windows sicher viel elegantere wege um eine wartezeit von <1ms zu
erreichen ...

asm
mov al,lobyte
mov ah,hibyte
mov w,ax
end
Das hier macht nix anderes als: w:=word(lobyte) or (word(hibyte) shl 8);
In ein 16Bit Word kommt also in den unteren 8 Bits lobyte rein, in den
oberen 8 Bits hibyte.

Wieso und was willst du eigentlich senden und empfangen?
Du willst doch das Teil nur programmieren oder?
Wenn du einen Verify-check machen willst, würde ich das Ding einfach
programmieren und danach dann auslesen ...


Du könntest auch mal hier reinschauen:
http://www.atmel.com/dyn/resources/prod_documents/doc2467.pdf

auf den Seiten 303 bis 307 (seriell programming) - da ist eigentlich alles
gut erklärt ...

Falls es weiter fragen gibt einfach fragen :)

Mfg

Thomas


"Dominik Schmidt" <schmidom@t-online.de> schrieb im Newsbeitrag
news:cg9d3n$r73$05$1@news.t-online.com...
Moin Thomas!

Danke für deinen Quelltext. Leider komme ich da nicht so ganz mit den
Assemblerpassagen klar. Könntest du mir die erlären? Oder evtl. mal kurz
niederschreiben, wie das Senden/Empfangen theroretisch funktionieren
sollte?
Das Datenblatt ist nicht so ergibig, oder ich interpretiere es falsch...

Der Quelltext ist natürlich nicht alles. Ich nutze die RSAPI.DLL um direkt
auf den seriellen Port zugreifen zu können. Das ganze Listing sieht im Mom
so aus:

// ###################################################################
// #### Versuch eines Atmel ISP Programmers #####
// #### #####
// #### 2004 by Dominik Schmidt #####
// #### #####
// #### Leitungen: MOSI (Data In) = 9 RI (Einlesen) #####
// #### 4 DTR (Ausgeben) #####
// #### MISO (Data Out) = 8 CTS (Einlesen) #####
// #### SCK (Serial Clock) = 6 DSR (Einlesen) #####
// #### 7 RTS(0|1) (Ausgeben) #####
// #### Reset = 3 TXD(0|1) #####
// #### #####
// #### Protzugriffe werden alle über RSAPI realisiert ! #####
// ###################################################################

// Serielle Schnittstelle
// Funktion Pin PC <> uC
// DCD 1 <--
// RXD 2 <--
// TXD 3 --
// DTR 4 --
// GND 5 -
// DSR 6 <--
// RTS 7 --
// CTS 8 <--
// RI 9 <--

unit ISP_Progger;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
Dialogs, RSAPI, StdCtrls, Math;

type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

//Byte auf den Bus ausgeben und Byte lesen
//When WRITING serial data to the ATtiny26, data is clocked on the RISING
EDGE of SCK.
//When READING data from the ATtiny26, data is clocked on the FALLING EDGE
of SCK.
Function ISPInOut(Wert:integer): Integer;
var n, bitwert, erg:integer;
begin
bitwert:= 128;
erg := 0;
RTS(0); // SCK auf 0 setzen
Delay(5);
For n:= 1 To 8 do
begin
If (Wert And bitwert) = bitwert Then
begin // Wert (2^x) kommt in der Zahl vor (MOSI Bit auf 1 [DTR(1)])
DTR(1); // MOSI Bit setzen
RTS(1); // Takt auf 1 setzen
delay(1);
end
Else
begin // Wert kommt nicht in der Zahl vor (MOSI Bit auf 0 [DTR(0)])
DTR(0); // MOSI Bit löschen
RTS(1); // Takt auf 1 setzen
delay(1);
End;
RTS(0);
If CTS = 1 Then erg := erg + bitwert;
//delay(1);
bitwert := bitwert div 2;
end;
ISPInOut := erg;
end;

// ###################################################################
// #### Leitungen: MOSI (Data In) = 9 RI (Einlesen) #####
// #### 4 DTR (Ausgeben) #####
// #### MISO (Data Out) = 8 CTS (Einlesen) #####
// #### SCK (Serial Clock) = 6 DSR (Einlesen) #####
// #### 7 RTS(0|1) (Ausgeben) #####
// #### Reset = 3 TXD(0|1) #####
// ###################################################################
procedure TForm1.Button1Click(Sender: TObject);
//var info:string;
var i:integer;
begin
Memo1.Lines.Add(TimeToStr(Time) + ' # Port ' + Edit1.Text + '
geöffnet');
ComOpen(strtoint(Edit1.Text));

Memo1.Lines.Add(TimeToStr(Time) + ' # Initialisierung einleiten (Reset 0
und SCK auf 0)');
TXD(1);
RTS(0);

Memo1.Lines.Add(TimeToStr(Time) + ' # 100ms warten ...');
Delay(100);

Memo1.Lines.Add(TimeToStr(Time) + ' # Reset 1 / 100ms warten / Reset 0 /
100ms warten');
TXD(0);
Delay(100);
TXD(1);
Delay(100);
for i:=1 to 10 do
begin
Memo1.Lines.Add(inttostr(ISPInOut(172)));
Memo1.Lines.Add(inttostr(ISPInOut(83)));
Memo1.Lines.Add(inttostr(ISPInOut(0)));
Memo1.Lines.Add(inttostr(ISPInOut(0)));
end;

end;
end.

Greetz Dominik
 
Noch eine Kleinigkeit ...
wie hast du deine Funktionen ausprobiert?
Einfach die RS232 Pins an den AVR angeschlossen?
Oder habt ihr da noch einen Pegelwandler dazwischen wie den MAX232 um RS232
Pegel nach TTL-Pegel zu konvertieren?
Sorry für die Frage - aber sowas kommt schon vor :)

hmm - im Datenblatt steht drin:
"the second byte ($53) will echo back when issuing the third byte of the
Programming Enable instruction"

Also das wird heißen, dass du in deiner Ausgabe erstmal
0
0
$53

bekommen wirst ... vielleicht funktionierts ja so wie es soll ...

Mfg

Thomas

"Dominik Schmidt" <schmidom@t-online.de> schrieb im Newsbeitrag
news:cg9d3n$r73$05$1@news.t-online.com...
Moin Thomas!

Danke für deinen Quelltext. Leider komme ich da nicht so ganz mit den
Assemblerpassagen klar. Könntest du mir die erlären? Oder evtl. mal kurz
niederschreiben, wie das Senden/Empfangen theroretisch funktionieren
sollte?
Das Datenblatt ist nicht so ergibig, oder ich interpretiere es falsch...

Der Quelltext ist natürlich nicht alles. Ich nutze die RSAPI.DLL um direkt
auf den seriellen Port zugreifen zu können. Das ganze Listing sieht im Mom
so aus:

// ###################################################################
// #### Versuch eines Atmel ISP Programmers #####
// #### #####
// #### 2004 by Dominik Schmidt #####
// #### #####
// #### Leitungen: MOSI (Data In) = 9 RI (Einlesen) #####
// #### 4 DTR (Ausgeben) #####
// #### MISO (Data Out) = 8 CTS (Einlesen) #####
// #### SCK (Serial Clock) = 6 DSR (Einlesen) #####
// #### 7 RTS(0|1) (Ausgeben) #####
// #### Reset = 3 TXD(0|1) #####
// #### #####
// #### Protzugriffe werden alle über RSAPI realisiert ! #####
// ###################################################################

// Serielle Schnittstelle
// Funktion Pin PC <> uC
// DCD 1 <--
// RXD 2 <--
// TXD 3 --
// DTR 4 --
// GND 5 -
// DSR 6 <--
// RTS 7 --
// CTS 8 <--
// RI 9 <--

unit ISP_Progger;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
Dialogs, RSAPI, StdCtrls, Math;

type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

//Byte auf den Bus ausgeben und Byte lesen
//When WRITING serial data to the ATtiny26, data is clocked on the RISING
EDGE of SCK.
//When READING data from the ATtiny26, data is clocked on the FALLING EDGE
of SCK.
Function ISPInOut(Wert:integer): Integer;
var n, bitwert, erg:integer;
begin
bitwert:= 128;
erg := 0;
RTS(0); // SCK auf 0 setzen
Delay(5);
For n:= 1 To 8 do
begin
If (Wert And bitwert) = bitwert Then
begin // Wert (2^x) kommt in der Zahl vor (MOSI Bit auf 1 [DTR(1)])
DTR(1); // MOSI Bit setzen
RTS(1); // Takt auf 1 setzen
delay(1);
end
Else
begin // Wert kommt nicht in der Zahl vor (MOSI Bit auf 0 [DTR(0)])
DTR(0); // MOSI Bit löschen
RTS(1); // Takt auf 1 setzen
delay(1);
End;
RTS(0);
If CTS = 1 Then erg := erg + bitwert;
//delay(1);
bitwert := bitwert div 2;
end;
ISPInOut := erg;
end;

// ###################################################################
// #### Leitungen: MOSI (Data In) = 9 RI (Einlesen) #####
// #### 4 DTR (Ausgeben) #####
// #### MISO (Data Out) = 8 CTS (Einlesen) #####
// #### SCK (Serial Clock) = 6 DSR (Einlesen) #####
// #### 7 RTS(0|1) (Ausgeben) #####
// #### Reset = 3 TXD(0|1) #####
// ###################################################################
procedure TForm1.Button1Click(Sender: TObject);
//var info:string;
var i:integer;
begin
Memo1.Lines.Add(TimeToStr(Time) + ' # Port ' + Edit1.Text + '
geöffnet');
ComOpen(strtoint(Edit1.Text));

Memo1.Lines.Add(TimeToStr(Time) + ' # Initialisierung einleiten (Reset 0
und SCK auf 0)');
TXD(1);
RTS(0);

Memo1.Lines.Add(TimeToStr(Time) + ' # 100ms warten ...');
Delay(100);

Memo1.Lines.Add(TimeToStr(Time) + ' # Reset 1 / 100ms warten / Reset 0 /
100ms warten');
TXD(0);
Delay(100);
TXD(1);
Delay(100);
for i:=1 to 10 do
begin
Memo1.Lines.Add(inttostr(ISPInOut(172)));
Memo1.Lines.Add(inttostr(ISPInOut(83)));
Memo1.Lines.Add(inttostr(ISPInOut(0)));
Memo1.Lines.Add(inttostr(ISPInOut(0)));
end;

end;
end.

Greetz Dominik
 
* Thomas Pototschnig <thomas.pototschnig@gmx.de> [2004-08-22 10:43]:
asm
mov cx,$ffff
repnz
end;

Hier handelt es sich nur um eine einfache Warteschleife - ein äquivalent
wäre
for i:=1 to 65535 do ;
gibt's in ObjectPascal nicht sowas wie in C

for (volatile i = 1; i < 65535; i++)
;

Wegen dem `volatile' darf der Compiler es dann nicht mehr
wegoptimieren, weil die Variable von außerhalb verändert werden
könnte.


Gruß,
Bernhard

--
"Unix is the most user friendly system I know, the point is the it
is really selective about who is indeed its friend."
-- Luigi Genoni
 
Moin !

Einfach die RS232 Pins an den AVR angeschlossen?
Oder habt ihr da noch einen Pegelwandler dazwischen wie den MAX232 um
RS232
Pegel nach TTL-Pegel zu konvertieren?
Sorry für die Frage - aber sowas kommt schon vor :)
Jo, einfach angeschlossen, ohne Max232. Allerdings schon mit Widerständen in
den Leitungen. Die Scahltung kann man auf
http://www.rclineforum.de/forum/thread.php?threadid=61463&sid=&threadview=0&hilight=&hilightuser=&page=11
sehen.
Ich sag mal so, mit PonyProg funzt das wunderbar. Also muss man das ja auch
irgendwie anders hinbekommen...

Greetz Dominik
 
"Bernhard Walle" <Bernhard.Walle@gmx.de> wrote

http://www.bsdhome.com/avrdude/
http://savannah.nongnu.org/projects/uisp/
Viel Dank Bernd. Ich schaue mir das mal an. Mir geht es ja nur darum zu
verstehen, wie das ganze vom Ablauf her funzt. Proggen werde ich es wenn
überhaupt in Delphi.

Greetz Dominik
 
Tschuldigung für meine nachfolgende Wortwahl:

Gibt volatile unter der armseligen Programmiersprache Delphi? :)

Gruß

Thomas

"Bernhard Walle" <Bernhard.Walle@gmx.de> schrieb im Newsbeitrag
news:slrncigoh7.qee.Bernhard.Walle@news.bwalle.de...
:

asm
mov cx,$ffff
repnz
end;

Hier handelt es sich nur um eine einfache Warteschleife - ein äquivalent
wäre
for i:=1 to 65535 do ;

gibt's in ObjectPascal nicht sowas wie in C

for (volatile i = 1; i < 65535; i++)
;

Wegen dem `volatile' darf der Compiler es dann nicht mehr
wegoptimieren, weil die Variable von außerhalb verändert werden
könnte.


Gruß,
Bernhard

--
"Unix is the most user friendly system I know, the point is the it
is really selective about who is indeed its friend."
-- Luigi Genoni
 
"Thomas Pototschnig" <thomas.pototschnig@gmx.de> schrieb im Newsbeitrag
news:2or4j7FdobsjU1@uni-berlin.de...
mov cx,$ffff
repnz
Hier handelt es sich nur um eine einfache Warteschleife
Nein, hier handelt es sich um einen schlichten Programmierfehler.
Die Historie zeigt uns, das es absolut zu kurz gedacht ist,
anzunehmen, das man mit so etwas einen Prozessor aufhalten kann.
Prozessoren werden schneller und intelligenter, ein Pentium
optimiert das praktisch in Hardware weg, das faellt von aussen
gar nicht mehr auf. Der holt (wegen cache und branch prediction)
weder die Befehle mehrfach, noch macht er eine erkennbare Pause
zwischen den geholten Befehlen.

Solcher Code hat schon hundertfach zu den bekannten Hobbyprogrammen
gefuehrt 'ging doch bei mir' (und bei allen andern eben nicht).
Richtet euch nach Hardwarezeitgebern (gibt es auf dem Pentium
reichlich, schon der alte IBM-PC hatte einen), und vergesst
das untauglich krude Konzept der 'Warteschleifen' auf allem,
wo nicht der Prozessor fest vorgegeben ist (uC, aber selbst dort
tut man sich meist keinen Gefallen damit).
--
Manfred Winterhoff, reply-to invalid, use mawin at despammed.com
homepage: http://www.geocities.com/mwinterhoff/
de.sci.electronics FAQ: http://dse-faq.elektronik-kompendium.de/
Read 'Art of Electronics' Horowitz/Hill before you ask.
Lese 'Hohe Schule der Elektronik 1+2' bevor du fragst.
 
* Thomas Pototschnig <thomas.pototschnig@gmx.de> [2004-08-22 11:19]:
Tschuldigung für meine nachfolgende Wortwahl:

Gibt volatile unter der armseligen Programmiersprache Delphi? :)
das war ja meine Frage. Die Sprache ist meines Wissens ObjectPascal,
Delphi ist die IDE. Oder irre ich da?


Gruß,
Bernhard

--
Man soll Denken lehren, nicht Gedachtes.
-- C. Gurlitt
 
Du irrst nicht :)

Gruß

Thomas

"Bernhard Walle" <Bernhard.Walle@gmx.de> schrieb im Newsbeitrag
news:slrncigpnu.qr8.Bernhard.Walle@news.bwalle.de...
:
Tschuldigung für meine nachfolgende Wortwahl:

Gibt volatile unter der armseligen Programmiersprache Delphi? :)

das war ja meine Frage. Die Sprache ist meines Wissens ObjectPascal,
Delphi ist die IDE. Oder irre ich da?


Gruß,
Bernhard

--
Man soll Denken lehren, nicht Gedachtes.
-- C. Gurlitt
 
Ja,

das ist so richtig ... solche Sachen macht man auch nur auf langsamen
Prozessoren ... und mein Prozessor war vor 5 Jahren wirklich wirklich
langsam -

Gibt ja noch andere Tricks wie

asm
mov cx,$ffff
mov dx,$300
label1:
in al,dx
loop label1
end;

haha - ja - grausig :)

In unserer DOS-Firmensoftware wird auch heute so noch eine
halbwegsdefinierte Wartezeit erzeugt ...

Mir ist nichts anderes bekannt wie man unter BP7 Wartezeiten von <1ms
erzeugen hätte können...

Gruß

Thomas



"MaWin" <me@private.net> schrieb im Newsbeitrag
news:2or7sbFdndrrU1@uni-berlin.de...
"Thomas Pototschnig" <thomas.pototschnig@gmx.de> schrieb im Newsbeitrag
news:2or4j7FdobsjU1@uni-berlin.de...
mov cx,$ffff
repnz
Hier handelt es sich nur um eine einfache Warteschleife

Nein, hier handelt es sich um einen schlichten Programmierfehler.
Die Historie zeigt uns, das es absolut zu kurz gedacht ist,
anzunehmen, das man mit so etwas einen Prozessor aufhalten kann.
Prozessoren werden schneller und intelligenter, ein Pentium
optimiert das praktisch in Hardware weg, das faellt von aussen
gar nicht mehr auf. Der holt (wegen cache und branch prediction)
weder die Befehle mehrfach, noch macht er eine erkennbare Pause
zwischen den geholten Befehlen.

Solcher Code hat schon hundertfach zu den bekannten Hobbyprogrammen
gefuehrt 'ging doch bei mir' (und bei allen andern eben nicht).
Richtet euch nach Hardwarezeitgebern (gibt es auf dem Pentium
reichlich, schon der alte IBM-PC hatte einen), und vergesst
das untauglich krude Konzept der 'Warteschleifen' auf allem,
wo nicht der Prozessor fest vorgegeben ist (uC, aber selbst dort
tut man sich meist keinen Gefallen damit).
--
Manfred Winterhoff, reply-to invalid, use mawin at despammed.com
homepage: http://www.geocities.com/mwinterhoff/
de.sci.electronics FAQ: http://dse-faq.elektronik-kompendium.de/
Read 'Art of Electronics' Horowitz/Hill before you ask.
Lese 'Hohe Schule der Elektronik 1+2' bevor du fragst.
 
Dominik Schmidt wrote:
Nur an dem ISP beisse ich mir im Moment die Zähne aus. Genaugenommen geht es
um eine Funktion, die Daten zum AVR sendet und gleichzeitig empfängt. Davon
könnte man alles weitere ableiten.
Meine Software, die den Sercon2-Mini als Hardware verwendet, verwendet
diese Funktion (wichtig ist, dass man das Bit liest, *bevor* man den
Clockimpuls gibt - das hatte ich zuerst auch falsch gemacht). Ist in
Visual Basic geschrieben und verwendet die Port.dll:

Function Send(ByVal Data As Byte) As Byte
Dim R As Byte
R = 0 'R nimmt das gelesene Byte auf
For A = 7 To 0 Step -1 '8 Bit schreiben/lesen, MSB zuerst
R = R * 2 'R nach links schieben
DTR (Data And (2 ^ A)) \ (2 ^ A) 'Bit schreiben (DTR = MOSI)
R = R + CTS 'Bit lesen (CTS = MISO)
RTS 1 'Einen Puls auf Clock (RTS = SCK)
RTS 0
Next
Send = R
End Function

CTS gibt entweder 0 oder 1 zurück, also nicht True/False (-1/0)! CTS ist
eine Funktion aus der Port.dll, DTR und RTS sind Prozeduren aus der
Port.dll. Wenn man noch eine Wartezeit einbauen möchten, kann man
DELAYUS aus der Port.dll verwenden (wartet n Microsekunden).

Meine Software gibt es übrigens hier:
http://www.elektronik-kompendium.de/public/arnerossius/programm/windows/avrisp.htm
(ich habe sie geschrieben, weil ich AT-Prog nicht kaufen wollte ;-)).

Gruß,
Arne
 
Thomas Pototschnig wrote:
In unserer DOS-Firmensoftware wird auch heute so noch eine
halbwegsdefinierte Wartezeit erzeugt ...

Mir ist nichts anderes bekannt wie man unter BP7 Wartezeiten von <1ms
erzeugen hätte können...
Hardwaretimer von 18.2 Hz auf einen höhere Frequenz umprogrammieren, von
dort aus die alte Routine mit 18.2 Hz aufrufen. Oder erst die
Taktfrequenz kurz messen und dann per RDTSC die Wartezeit
dimensionieren. Den Zeilenrefresh der VGA Karte kann man theoretisch
auch für Wartezeiten missbauchen. Das ist zwar leicht zu programmieren,
dürfte aber auch zu den nicht unbedingt empfehlenswerten Tricks gehören.

Jan
 
"Thomas Pototschnig" <thomas.pototschnig@gmx.de> schrieb im Newsbeitrag
news:2or8l9Fd9p3eU1@uni-berlin.de...
Gibt ja noch andere Tricks wie
Weil der erste Ansatz falsch war, ist das kein Grund,
mit einem noch faelscheren Ansatz zu kommen.

Mir ist nichts anderes bekannt wie man unter BP7 Wartezeiten von <1ms
erzeugen hätte können...
Wie waere es, mal ein gutes Buch zu lesen `? Oder sonstwie mal etwas
hinzuzulernen ? Man muss ja nicht tmi unzureichenden Kenntnissen die
Welt mit schlechter Softwqre ueberfluten. Das tut ja Microsoft schon
zur Genuege, trotz Kenntnissen.

Nur mal als Denkansatz: Es gibt seit dem Original IBM-PC einen
Hardwaretimer, der mit 1.8432 MHz Takt zaehlt. Den kann man
auslesen, und warten, bis sich sein Zaehlerwert ausreichend veraendert
hat. Es gibt dabei einige Besonderheiten, z.B. zaehlt er zwei mal
rueckwaerts, macht bei 0 einen Sprung auf 65535, ist der Zugriff
unter NT nicht mehr ohne vorheriges Freischalten erlaubt,
aber dazu schreibt man sich eine halt Funktion oder sucht sich
eine fertige. Z.B. einen Timer aus Windows.

Unter DotNET bei C++ gibt es die Stopwatch-Klasse mit einer Aufloesung
des Prozessorttaktes, also bei mir hier 2.8GHz: -->

Operations timed using the system's high-resolution performance counter.
Timer frequency in ticks per second = 2798710000

Man muss halt bloss mal ein Buch lesen....
--
Manfred Winterhoff, reply-to invalid, use mawin at despammed.com
homepage: http://www.geocities.com/mwinterhoff/
de.sci.electronics FAQ: http://dse-faq.elektronik-kompendium.de/
Read 'Art of Electronics' Horowitz/Hill before you ask.
Lese 'Hohe Schule der Elektronik 1+2' bevor du fragst.
 
Man muss ja nicht tmi unzureichenden Kenntnissen die
Welt mit schlechter Softwqre ueberfluten. Das tut ja Microsoft schon
zur Genuege, trotz Kenntnissen.
Man muss halt bloss mal ein Buch lesen....
Problem ist, dass man die gewünschte funktionalität auch mit einfachen
Tricks erreichen kann ohne ein Buch lesen zu müssen ...

Mfg

Thomas
 
"Thomas Pototschnig" <thomas.pototschnig@gmx.de> schrieb im Newsbeitrag
news:2ore63Fcq3o8U1@uni-berlin.de...
Problem ist, dass man die gewünschte funktionalität auch mit einfachen
Tricks erreichen kann ohne ein Buch lesen zu müssen ...
Njet, eben nicht. An statt das man eine bestimmte Zeit abwartet,
halst man dem Prozessor Arbeit auf, und hofft, das er die notwendige
Zeit damit zubringt. Das ist mehr als bloss durch die Brust ins
Auge.
Benutzer mit langsameren Systemen kriegen die Krise, bei Benutzer mit
schnelleren System (also dein naechster Rechner) wartet es nicht lange
genug.
Warum Probleme nicht auf direktem Wege loesen ? Wenn ich eine ZEIT
verstreichen lassen will, frage ich nach irgendeiner ZEIT (Timer).

Es gibt wirklich schon genug schlechte Software.
--
Manfred Winterhoff, reply-to invalid, use mawin at despammed.com
homepage: http://www.geocities.com/mwinterhoff/
de.sci.electronics FAQ: http://dse-faq.elektronik-kompendium.de/
Read 'Art of Electronics' Horowitz/Hill before you ask.
Lese 'Hohe Schule der Elektronik 1+2' bevor du fragst.
 
"Arne Rossius" <ArneRossius@despammed.com> wrote

diese Funktion (wichtig ist, dass man das Bit liest, *bevor* man den
Clockimpuls gibt - das hatte ich zuerst auch falsch gemacht). Ist in
Das wars. Es funzt.

Wenn du meine Freundin wärst, dann würde ich dich jetzt zum Essen einladen
:)

VIELEN DANK!!!!

Grüße Dominik

PS: Wenn ich nochmal mit was Stress habe, kann ich dich dann nochmal
kontakten?
 

Welcome to EDABoard.com

Sponsor

Back
Top