Hi
Kann mir irgendjemand für eine AVR-PC-Verbindung die Sourcecodes für AVR
und PC schicken oder einen Link angeben. Am besten wäre es für Delphi,
alles andere geht aber auch.
Ich versuche gerade die Verbindung hintukriegen und schicke alle Zahlen
von 0-255 im Sekundentakt zum PC bekomme aber nur komische Zeichen, die
nicht dem geschickten Entsprechen.
Schonmal vielen Dank
Binomie
Hallo,
> Ich versuche gerade die Verbindung hintukriegen und schicke> alle Zahlen von 0-255 im Sekundentakt zum PC bekomme aber nur> komische Zeichen, die nicht dem geschickten Entsprechen.
kannst du mal das Programm posten? Ich kann mir vorstellen woran's
liegen könnte...
MfG
Andreas
Hi,
Das ganze läuft auf einem AT90s2333 und die Datenübertragung läuft noch
über Optokoppler. Den Code zum Übertragen hab ich von jemand anderen,
bin nicht sicher ob der so richtig ist. Beim durchlesen ist mir gerade
aufgefallen, dass das Ändern der Funktion des Txd-Pins stören könnte,
hab ich noch nicht gecheckt.
Binomie
1
.org 0000
2
3
rjmp main_prog ; RESET =$001 ;Reset
4
RETI ; INT0addr=$001 ;External Interrupt0 Vector Address
5
RETI ; INT1addr=$002 ;External Interrupt1 Vector Address
6
RETI ; ICP1addr=$003 ;Input Capture1 Interrupt Vector Address
7
RETI ; OC1Aaddr=$004 ;Output Compare1A Interrupt Vector Address
Moin...
Mit dem uC Programm kann dir sicherlich der Andreas besser helfen als
ich (siehe posting weiter unten). Unter Delphi habe ich die
ComPort-Komponente benutzt. (weiß jetzt nicht genau wie sie heißt)
Wenn du möchtest kann ich sie dir zumailen. (ist kostenlos)
Du benötigst dann zum senden nur noch einen Befehl wie:
comport1.write(buffer,1);
(buffer : integer oder char)
mit comport1.writestr(text,1);
kannst du sogar ganze Strings versenden. Das ganze gilt natürlich auch
zum empfangen.
Gruß Oliver
wäre sehr nett, wenn du mir die Komponente schicken könntest.
Ich hab jetzt auch mal den Code vom Tutorial ausprobiert, er funktioiert
bei mir aber erst teilweise, das erste bit fehlt noch und man muss alle
bits invertieren. das erste bit verschläft der pc wahrscheinlich, aber
das liegt sicher an meiner Verdrahtung.
Deshalb kauf ich mir die Woche endlich mal einen max232 und dann läuft
die sache sicher besser, bis jetzt noch alles mit optokopplern, bzw.
direkt an den PC.
Vielen Dank
Binomie
binomie schrieb:
>> wäre sehr nett, wenn du mir die Komponente schicken> könntest.
Ich hab es hochgeladen:
www.superchecker.net/projekt/comport.zip (159k)
> Ich hab jetzt auch mal den Code vom Tutorial ausprobiert, er> funktioiert bei mir aber erst teilweise, das erste bit fehlt> noch und man muss alle bits invertieren. das erste bit> verschläft der pc wahrscheinlich, aber das liegt sicher an> meiner Verdrahtung.>> Deshalb kauf ich mir die Woche endlich mal einen max232 und> dann läuft die sache sicher besser, bis jetzt noch alles mit> optokopplern, bzw. direkt an den PC.
Ähm.... und da liegt das Problem würd ich sagen. Der Mikrocontroller
gibt an seinen Pins (RXD/TXD) Pegel zwischen 0 und 5 Volt aus. (0V = low
; 5V = high)
Die serielle Schnittstelle des Computer (RS232) erwartet aber gemäß
Standart einen Pegel zwischen 3 und -12 V (3V = low ; -12 = high)
Das dein PC überhaupt etwas empfängt liegt nur daran, dass die
"Empfangsbausteine" im PC eine extrem gute Fehlerkorrektur haben.
Allerdings hast du ja selbst gesagt, dass du alle Bits invertieren mußt.
Das kommt daher, dass der Empfangsbaustein vom PC den 0V Lowpegel des
Mikrocontrollers als "sehr" geschädigten -12V High Pegel erkennt.
Das das erste Bit Fehlt liegt daran, dass das RS232 Protokoll einen
Highpegel als Startbit erwartet. Da du deine Bits aber "falsch" sendest
und der PC diese nur invertiert empfangen kann, erkennt er den ersten
Highpegel nicht, und interpretiert das erste Lowsignal (vom
Mikrocontroller aus gesehen) als Startbit.
Also, erst nach der Schaltung im Tutorial den MAX232 einbauen.
Dann sollte es wesentlich besser gehen.... :-)
Gruß Oliver
Hallo,
die Binärwerte von 0 bis 255, die du mit dem Programm an deinen PC
sendest, werden im Terminal nicht als Zahlen, sondern als <font
color="green">ASCII-Zeichen</font> dargestellt (eine Übersicht gibt's
hier). Wenn du also z.B. die Zahl 82 sendest, stellt dies das Terminal
als ein "R" dar (probiers mal aus!).
Um eine Zahl von 0 bis 9 anzuzeigen, musst du 48 dazu addieren: 0+48
wird im Terminal als eine "0" dargestellt, 9+48 als eine "9" (siehe
Tabelle). Bei mehrstelligen Zahlen wird die Sache schon komplizierter:
dann musst du die Zahlen in das BCD-Format umrechnen. BCD ist die
Abkürzung für "Binary Coded Decimal". In diesem Format werden 4 Bits für
jede Dezimalziffer benutzt. Normalerweise werden 2 Ziffern in ein Byte =
8 Bits "gepackt", in diesem Programm aber werden von jedem der beiden
BCD-Register nur 4 Bits verwendet.
In einer gepackten BCD-Zahl wird die Zahl 25 z.B. so dargestellt:
<pre>
1 Byte 0 0 1 0 0 1 0 1
|_____| |_____|
2 5 =25
</pre>
<br>
Wenn man die beiden Ziffern in getrennten Bytes abspeichert, sieht es so
aus:
<pre>
2 Bytes 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1
|_____| |_____|
2 5 = 25
</pre>
<br>
Das hat den Vorteil, dass man zu jedem der Register einfach 48
addieren muss, und schon hat man die ASCII-Werte der beiden
Ziffern, die man direkt ans Terminal-Programm senden kann.
Ich habe dein Programm mal ein bisschen modifiziert ;-)
Schreib einfach nochmal wenn du noch irgendwelche Fragen hast!
MfG
Andreas
<hr>
<pre>
.include "tutorial/uart/2313def.inc" ;Pfad zur Include-Datei ggf.
anpassen
.def temp = r18
.def counter = r17
.def fbin = r19 ;Ausgangswert
.def tBCDL = r19 ;Obere Dezimalstelle
.def tBCDH = r20 ;Untere Dezimalstelle
.org 0000
rjmp reset ; RESET =$001 ;Reset
RETI ; INT0addr=$001 ;External Interrupt0 Vector Address
RETI ; INT1addr=$002 ;External Interrupt1 Vector Address
RETI ; ICP1addr=$003 ;Input Capture1 Interrupt Vector Address
RETI ; OC1Aaddr=$004 ;Output Compare1A Interrupt Vector Address
rjmp check ; OVF1addr=$005 ;Overflow1 Interrupt Vector Address
RETI ; OVF0addr=$006 ;Overflow0 Interrupt Vector Address
RETI ; SPIaddr =$007 ;SPI Interrupt Vector Address
RETI ; URXCaddr=$008 ;UART Receive Complete Interrupt Vector Address
RETI ; UDREaddr=$009 ;UART Data Register Empty Interrupt Vector Address
RETI ; UTXCaddr=$00a ;UART Transmit Complete Interrupt Vector Address
RETI ; ADCCaddr =$00b ;ADC Interrupt Vector Address
RETI ; ERDYaddr =$00c ;EEPROM Interrupt Vector Address
RETI ; ACIaddr =$00d ;Analog Comparator Interrupt Vector Address
reset:
;Stackpointer initialisieren
ldi temp, RAMEND
out SPL, temp
ldi temp, 25 ;9600 baud bei 4.000.000 Hz
out UBRR, temp
ldi temp, 0xFF ;hab da noch nen paar LEDs hängen
out DDRB, temp
out PORTB, temp
ldi counter, 0 ;Counter auf 0 setzen
; Timer initialisieren
ldi temp, 0x00 ;kein pwm und kein output-pin
out tccr1a, temp
ldi temp, 0b00000101 ;/1024
out tccr1b, temp
ldi temp, 240 ;Werte für 1 Sekunde verzögerung
out tcnt1h, temp
ldi temp, 190
out tcnt1l, temp
ldi temp, 0b10000000 ;Interrupt freigeben
out timsk, temp
sei ;Allgemeine Interruptfreigabe
loop:
rjmp loop
check:
in r25,sreg ;Status-Reg sichern
ldi temp, 240 ;Timer wieder updaten
out TCNT1H, temp
ldi temp, 190
out tcnt1l, temp
mov fbin, counter ;counter nach fbin kopieren
rcall bin2bcd8 ;fbin in tBCDL und tBCDH aufteilen
mov temp, tBCDH ;obere Dezimalstelle
subi temp, -48 ;48 addieren um in ASCII umzuwandeln
;die AVRs haben keinen Befehl zum Addieren von
;Konstanten, deshalb -48 abziehe.
rcall serout ;Byte senden
mov temp, tBCDL ;untere Dezimalstelle
subi temp, -48 ;48 addieren um in ASCII umzuwandeln
rcall serout ;Byte senden
ldi temp, 10 ;ASCII-Wert für "Neue Zeile"
rcall serout ;Byte senden
ldi temp, 13 ;ASCII-Wert für "Cursor zurück"
rcall serout ;Byte senden
out PORTB, counter ;Zählerstand auf den Port geben
inc counter ;counter += 1
cpi counter, 100 ;Zähler bei 100?
brne weiter ;wenn nicht, dann zu "weiter" springen
ldi counter, 0 ;andernfalls counter zurück auf 0 setzen
weiter:
out sreg,r25 ;Status-Reg wiederherstellen
reti
bin2bcd8:
clr tBCDH ;clear result MSD
bBCD8_1:subi fbin,10 ;input = input - 10
brcs bBCD8_2 ;abort if carry set
inc tBCDH ;inc MSD
rjmp bBCD8_1 ;loop again
bBCD8_2:subi fbin,-10 ;compensate extra subtraction
ret
serout:
sbi ucr,txen ;set sender bit
sbis usr,udre ;wait till register is cleared
rjmp serout
out udr,temp ;send the variable
cbi ucr,txen ;clear sender bit
ret
</pre>