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 .org 0000 rjmp main_prog ; 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: main_prog: ldi r17,25 ; 9600 baud bei 4.000.000 Hz out ubrr,r17 ldi r17,0xFF ; hab da noch nen paar LEDs hängen out ddrb,r17 out portb,r17 ; Timer initialisieren ldi r18,0x00 ; kein pwm und kein output-pin out tccr1a,r18 ldi r18,0b00000101 ; /1024 out tccr1b,r18 ldi r18,240 ; Werte für 1 Sekunde verzögerung out tcnt1h,r18 ldi r18,190 out tcnt1l,r18 ldi r18,0b10000000 ; Interrupt freigeben out timsk,r18 sei ; Allgemeine Interruptfreigabe rjmp loop check: in r25,sreg ; Status-Reg sichern ldi r18,0x00 ; kann grad nicht auswendig sagen, was das soll out tifr,r18 ldi r18,240 ; Timer wieder updaten out tcnt1h,r18 ldi r18,190 out tcnt1l,r18 out portb,r17 ; Zählerstand auf den Port geben inc r17 ; selbsterklärend rs_send: ;Hab ich aus nem anderen UART-Projekt rausgenommen sbi ucr,txen ;set sender bit sbis usr,udre ;wait till register is cleared rjmp rs_send out udr,r17 ;send the variable cbi ucr,txen ;clear sender bit out sreg,r25 ;Status-Reg wiederherstellen sei loop: nop rjmp loop
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.