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 | 
| 8 | rjmp check ; OVF1addr=$005 ;Overflow1 Interrupt Vector Address | 
| 9 | RETI ; OVF0addr=$006 ;Overflow0 Interrupt Vector Address | 
| 10 | RETI ; SPIaddr =$007 ;SPI Interrupt Vector Address | 
| 11 | RETI ; URXCaddr=$008 ;UART Receive Complete Interrupt Vector Address | 
| 12 | RETI ; UDREaddr=$009 ;UART Data Register Empty Interrupt Vector Address | 
| 13 | RETI ; UTXCaddr=$00a ;UART Transmit Complete Interrupt Vector Address | 
| 14 | RETI ; ADCCaddr =$00b ;ADC Interrupt Vector Address | 
| 15 | RETI ; ERDYaddr =$00c ;EEPROM Interrupt Vector Address | 
| 16 | RETI ; ACIaddr =$00d ;Analog Comparator Interrupt Vector Address | 
| 17 | |
| 18 | reset: | 
| 19 | |
| 20 | |
| 21 | main_prog: | 
| 22 | ldi r17,25 ; 9600 baud bei 4.000.000 Hz | 
| 23 | out ubrr,r17 | 
| 24 | ldi r17,0xFF ; hab da noch nen paar LEDs hängen | 
| 25 | out ddrb,r17 | 
| 26 | out portb,r17 | 
| 27 | |
| 28 | ; Timer initialisieren | 
| 29 | |
| 30 | ldi r18,0x00 ; kein pwm und kein output-pin | 
| 31 | out tccr1a,r18 | 
| 32 | ldi r18,0b00000101 ; /1024 | 
| 33 | out tccr1b,r18 | 
| 34 | ldi r18,240 ; Werte für 1 Sekunde verzögerung | 
| 35 | out tcnt1h,r18 | 
| 36 | ldi r18,190 | 
| 37 | out tcnt1l,r18 | 
| 38 | ldi r18,0b10000000 ; Interrupt freigeben | 
| 39 | out timsk,r18 | 
| 40 | sei ; Allgemeine Interruptfreigabe | 
| 41 | rjmp loop | 
| 42 | |
| 43 | check: | 
| 44 | in r25,sreg ; Status-Reg sichern | 
| 45 | |
| 46 | ldi r18,0x00 ; kann grad nicht auswendig sagen, was das soll | 
| 47 | out tifr,r18 | 
| 48 | |
| 49 | ldi r18,240 ; Timer wieder updaten | 
| 50 | out tcnt1h,r18 | 
| 51 | ldi r18,190 | 
| 52 | out tcnt1l,r18 | 
| 53 | |
| 54 | out portb,r17 ; Zählerstand auf den Port geben | 
| 55 | inc r17 ; selbsterklärend | 
| 56 | |
| 57 | rs_send: | 
| 58 | ;Hab ich aus nem anderen UART-Projekt rausgenommen | 
| 59 | |
| 60 | sbi ucr,txen ;set sender bit | 
| 61 | sbis usr,udre ;wait till register is cleared | 
| 62 | rjmp rs_send | 
| 63 | out udr,r17 ;send the variable | 
| 64 | cbi ucr,txen ;clear sender bit | 
| 65 | |
| 66 | out sreg,r25 ;Status-Reg wiederherstellen | 
| 67 | sei | 
| 68 | |
| 69 | loop: nop | 
| 70 | rjmp loop | 
:
    Bearbeitet durch Admin
  
  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
Danke für die Komponente! Den Max werd ich bald verbauen, war bisher erst mal die Billiglösung zum rumspielen.
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>
  Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
  
  Bestehender Account
  
  
  
  Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
  Noch kein Account? Hier anmelden.

 Thread beobachten
 Thread beobachten Seitenaufteilung abschalten
 Seitenaufteilung abschalten