Soros port (rs232)
Hibás az elmélet....
A gyorsabb/lassabb küldés egyedül a soros sebességtől függ...
A buffer arra van, hogy a prg ne várj meg, mig az _osszes_ adat lmegy, hanem a bufferbe tegye be. Es ha az adoresz kiurult, a bufferbol feltolti a kovetkezot...
A elso byte az dorekeszbe kerul, a masodik megy csak a bufferbe....
Mintaprogi, ez mindent elmond:
A gyorsabb/lassabb küldés egyedül a soros sebességtől függ...
A buffer arra van, hogy a prg ne várj meg, mig az _osszes_ adat lmegy, hanem a bufferbe tegye be. Es ha az adoresz kiurult, a bufferbol feltolti a kovetkezot...
A elso byte az dorekeszbe kerul, a masodik megy csak a bufferbe....
Mintaprogi, ez mindent elmond:
Kód: Egész kijelölése
' This program demonstrate the Serial problem
$crystal = 16000000 'orajel
$regfile = "m168def.dat" 'chip
$baud = 300
Config Serialout = Buffered , Size = 254
Dim Temp1b As Byte
Led Alias Portb.5
Config Led = Output
Reset Led
Speaker Alias Portb.2
Config Speaker = Output 'Hangszoro
Reset Speaker
Enable Interrupts
Do
Toggle Led
Sound Speaker , 100 , 700 'make some noice
For Temp1b = 33 To 122
Print Chr(temp1b);
Next Temp1b
Sound Speaker , 100 , 1400 'make some noice
Wait 1
Loop
- nobody_hun
- Bitfaragó
- Hozzászólások: 425
- Csatlakozott: 2005. november 14. hétfő, 7:00
Sokszor olvasom itt a fórumon, hogy problémát okoz a soros kapcsolat megvalósítása és az azzal kapcsolatos programok megírása.
Az alábbiakban ebből a témakörből dokumentáltam egy megvalósítást.
Soros-párhuzamos átalakító AVR-rel, PC-hez
Nem régen egy olyan probléma megoldására kaptam felkérést, hogy készítsek olyan átalakítót, amellyel a PC meglehetősen szűkös ki- és bemeneteinek számát lehet kibővíteni.
Feltettem a kérdést, hogy „De hát ott az LPT port, miért nem azt használjátok?”. Természetesen az indoklástól rügyet fakasztottam: az ok meglehetősen prózai, ki- és bekapcsoláskor az LPT port teljesen véletlenszerű állapotba áll be mindaddig, míg az oprendszer vagy a saját alkalmazás be nem állítja. Ez a jelenség pedig meglehetősen kellemetlen egy 24/7 üzemmódra tervezett rendszer esetén.
Több kérdésem nem is volt, neki láttam a megvalósításnak.
Hardver:
Minimalista tervezéssel sikerült a hardver részt letudni egy MAX232 szintillesztővel és egy Attiny2313-mal. Az áramkör egyoldalas, részben felületszerelt kivitelű, külső mérete pedig körülbelül 30x30 mm lett.
A csatlakozókat úgy alakítottam ki, hogy az áramkör közvetlenül az alaplapra dugaszolható legyen, valamint a ki- és bemenetei egy 10 pólusú IDC csatlakozón keresztül elérhetők legyenek.
A panelen helyet kapott egy állapotjelző LED is.
Az AVR soros kommunikációjának hibamentes működéséhez 7,3728MHz-es kvarc időalapot használtam.
A fenti kialakítás miatt le kellett mondanom a szabványos programozó portról, azonban ez a hátrány könnyen áthidalható néhány vezetékkel, programozni amúgy sem minden nap programozza a processzort.
Uploaded with ImageShack.us
Uploaded with ImageShack.us
Szoftver:
A panel működését a soros porton kiadott parancsokkal lehet befolyásolni, akár egy terminál emulátor alól is. Az általam készített PC-s tesztprogramot feltöltöttem a „File csere-bere” rovatba, ser_2_par.zip néven, forrással együtt. Letöltés
Úgy gondoltam, hogy ha már lúd, legyen kövér és a témából hozzuk ki a lehető legtöbb lehetőséget.
Bekapcsoláskor a program 10-szer felvillantja a LED-et, aminek a valóságban semmi értelme sincs, csupán jelzi, hogy az AVR életképes és fut a programja.
A szűkös programmemória miatt az alábbi utasításokat sikerült a szoftver oldalon megvalósítani:
brd
A panel a "SPC V1" választ adja.
rpd
Beolvassa a port állapotát és azt decimális értékben visszaadja.
rpb
Beolvassa a port állapotát és azt bináris értékben visszaadja.
rph
Beolvassa a port állapotát és azt hexadecimális értékben visszaadja.
aon
A port minden bitjét 1-re állítja.
aof
A port minden bitjét 0-re állítja.
cdd{paraméter}
A DDR regiszter segítségével a paraméterként megadott bináris értékek alapján beállítja a port egyes bitjeinek irányát (ki- vagy bemenet legyen az adott láb)
out{paraméter}
A paraméterként megadott bináris értéket kiírja a PORTB-re.
oon{paraméter}
A paraméterként megadott 0-7 számnak megfelelő lábat 1-re állítja.
oof{paraméter}
A paraméterként megadott 0-7 számnak megfelelő lábat 0-ra állítja.
Ha parancsként a fentiektől eltérő utasítást adunk meg, akkor a panel egy egyszerű „ERROR” üzenetet ad vissza.
A soros porti kommunikáció visszajelzésére a LED felvillan.
Bővítési lehetőségek:
Jelen állapotban a hardver nincs felkészítve az AVR bemeneteinek védelmére. Különböző, főleg a hosszú kábelezésen érkező nem kívánatos tranziensek gyakorta a processzor halálát okozzák, így ne feledkezzünk meg a felhasználásnál ezek kiszűrésére.
Szoftver oldalon a soros kommunikációban nincs beépítve ellenőrző algoritmus. Ennek két oka van, az egyik, hogy egy normális ellenőrzés viszonylag sok helyet foglal (most 1426 byte-ot lőttünk el a 2048-ból), másrészt az áramkörre szánt időbe ez már nem fért bele.
Kód:
Az alábbiakban ebből a témakörből dokumentáltam egy megvalósítást.
Soros-párhuzamos átalakító AVR-rel, PC-hez
Nem régen egy olyan probléma megoldására kaptam felkérést, hogy készítsek olyan átalakítót, amellyel a PC meglehetősen szűkös ki- és bemeneteinek számát lehet kibővíteni.
Feltettem a kérdést, hogy „De hát ott az LPT port, miért nem azt használjátok?”. Természetesen az indoklástól rügyet fakasztottam: az ok meglehetősen prózai, ki- és bekapcsoláskor az LPT port teljesen véletlenszerű állapotba áll be mindaddig, míg az oprendszer vagy a saját alkalmazás be nem állítja. Ez a jelenség pedig meglehetősen kellemetlen egy 24/7 üzemmódra tervezett rendszer esetén.
Több kérdésem nem is volt, neki láttam a megvalósításnak.
Hardver:
Minimalista tervezéssel sikerült a hardver részt letudni egy MAX232 szintillesztővel és egy Attiny2313-mal. Az áramkör egyoldalas, részben felületszerelt kivitelű, külső mérete pedig körülbelül 30x30 mm lett.
A csatlakozókat úgy alakítottam ki, hogy az áramkör közvetlenül az alaplapra dugaszolható legyen, valamint a ki- és bemenetei egy 10 pólusú IDC csatlakozón keresztül elérhetők legyenek.
A panelen helyet kapott egy állapotjelző LED is.
Az AVR soros kommunikációjának hibamentes működéséhez 7,3728MHz-es kvarc időalapot használtam.
A fenti kialakítás miatt le kellett mondanom a szabványos programozó portról, azonban ez a hátrány könnyen áthidalható néhány vezetékkel, programozni amúgy sem minden nap programozza a processzort.
Uploaded with ImageShack.us
Uploaded with ImageShack.us
Szoftver:
A panel működését a soros porton kiadott parancsokkal lehet befolyásolni, akár egy terminál emulátor alól is. Az általam készített PC-s tesztprogramot feltöltöttem a „File csere-bere” rovatba, ser_2_par.zip néven, forrással együtt. Letöltés
Úgy gondoltam, hogy ha már lúd, legyen kövér és a témából hozzuk ki a lehető legtöbb lehetőséget.
Bekapcsoláskor a program 10-szer felvillantja a LED-et, aminek a valóságban semmi értelme sincs, csupán jelzi, hogy az AVR életképes és fut a programja.
A szűkös programmemória miatt az alábbi utasításokat sikerült a szoftver oldalon megvalósítani:
brd
A panel a "SPC V1" választ adja.
rpd
Beolvassa a port állapotát és azt decimális értékben visszaadja.
rpb
Beolvassa a port állapotát és azt bináris értékben visszaadja.
rph
Beolvassa a port állapotát és azt hexadecimális értékben visszaadja.
aon
A port minden bitjét 1-re állítja.
aof
A port minden bitjét 0-re állítja.
cdd{paraméter}
A DDR regiszter segítségével a paraméterként megadott bináris értékek alapján beállítja a port egyes bitjeinek irányát (ki- vagy bemenet legyen az adott láb)
out{paraméter}
A paraméterként megadott bináris értéket kiírja a PORTB-re.
oon{paraméter}
A paraméterként megadott 0-7 számnak megfelelő lábat 1-re állítja.
oof{paraméter}
A paraméterként megadott 0-7 számnak megfelelő lábat 0-ra állítja.
Ha parancsként a fentiektől eltérő utasítást adunk meg, akkor a panel egy egyszerű „ERROR” üzenetet ad vissza.
A soros porti kommunikáció visszajelzésére a LED felvillan.
Bővítési lehetőségek:
Jelen állapotban a hardver nincs felkészítve az AVR bemeneteinek védelmére. Különböző, főleg a hosszú kábelezésen érkező nem kívánatos tranziensek gyakorta a processzor halálát okozzák, így ne feledkezzünk meg a felhasználásnál ezek kiszűrésére.
Szoftver oldalon a soros kommunikációban nincs beépítve ellenőrző algoritmus. Ennek két oka van, az egyik, hogy egy normális ellenőrzés viszonylag sok helyet foglal (most 1426 byte-ot lőttünk el a 2048-ból), másrészt az áramkörre szánt időbe ez már nem fért bele.
Kód:
Kód: Egész kijelölése
'------------------------------------------------------------------------------
' CHIP AND COMPILER CONFIG
'------------------------------------------------------------------------------
$regfile = "Attiny2313.dat"
$crystal = 7372800
$baud = 9600
'------------------------------------------------------------------------------
' PORT AND PIN CONFIGURATION
'------------------------------------------------------------------------------
Config Com1 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Portb = &B11111111
Config Portb = Output
Relay_dataport Alias Portb
Config Portd.5 = Output
Comm_led Alias Portd.5
'Universal variables
Dim Cntr As Byte
Dim Cmd As String * 3
Dim Error As Bit
'Used for: Communication
Dim Rcv_string As String * 20
'------------------------------------------------------------------------------
' MAIN
'------------------------------------------------------------------------------
Relay_dataport = 0 'Switch off all
Set Error
Enable Interrupts
For Cntr = 1 To 10
Reset Comm_led
Waitms 200
Set Comm_led
Waitms 200
Next
Do
Set Error
Set Comm_led
Input Rcv_string Noecho
Cmd = Left(rcv_string , 3)
Select Case Cmd
Case "brd":
Print "SPC V1"
Gosub Noerror
Case "rpd": 'read port in dec
Cntr = Relay_dataport
Print Cntr
Gosub Noerror
Case "rpb": 'read port in bin
Cntr = Relay_dataport
Print Bin(cntr)
Gosub Noerror
Case "rph": 'read port in hex
Cntr = Relay_dataport
Print Hex(cntr)
Gosub Noerror
Case "aon": 'all bit on
Relay_dataport = 255
Gosub Noerror
Case "aof": 'all bit off
Relay_dataport = 0
Gosub Noerror
Case "cdd": 'change DDR register
Cmd = Mid(rcv_string , 4 , 8)
Cntr = Val(cmd)
Ddrb = Cntr
Gosub Noerror
Case "out": 'write port
Cmd = Mid(rcv_string , 4 , 8)
Cntr = Val(cmd)
Relay_dataport = Cntr
Gosub Noerror
Case "oon": 'pin set to 1
Cmd = Mid(rcv_string , 4 , 1)
Cntr = Val(cmd)
Select Case Cntr
Case 0 To 7:
Set Relay_dataport.cntr
Gosub Noerror
End Select
Case "oof": 'pin set to 0
Cmd = Mid(rcv_string , 4 , 1)
Cntr = Val(cmd)
Select Case Cntr
Case 0 To 7:
Reset Relay_dataport.cntr
Gosub Noerror
End Select
End Select
If Error = 1 Then
Print "ERROR"
End If
Reset Comm_led
Waitms 200
Loop
'------------------------------------------------------------------------------
Noerror:
Reset Error
Return
"Az IC-k füsttel működnek. Ha kijön belőlük a füst, nem működnek tovább." - ismeretlen szerző
"Az ID:FFFFFF egyenlő az Atmel még nem kiadott processzorával."
"Az ID:FFFFFF egyenlő az Atmel még nem kiadott processzorával."
Sziasztok!
Egy projekt kapcsán próbálgatom a soros kommunikációt bascomban. A programban egy enkóderrel lehet változtatni egy változó értékét, ami ha változik küldésre kerül a soros porton keresztül. Eddig nincs is gond, de van hogy az üzenet nem jelenik meg teljes egészében a terminal emulator-ban, majd látszólag az AVR is megáll. Nem küld több üzenetet a soros porton és az egyéb I/O lábak sem reagálnak.
Uploaded with ImageShack.us
Itt látható róla kép.
Bár nem tudom hogy mennyire számítanak a következők, de kezdőként ezekre tudok gondolni hibaforrásként:
-Nem kvarcot hanem a belső oszc.-ort használom 4MHz-en
-Majd ezt osztom hogy 9600 legyen a baudrate, ez ügye bascom szerint is 0,16% hibalehetőséget hordoz.
Végül a kód:
Egy projekt kapcsán próbálgatom a soros kommunikációt bascomban. A programban egy enkóderrel lehet változtatni egy változó értékét, ami ha változik küldésre kerül a soros porton keresztül. Eddig nincs is gond, de van hogy az üzenet nem jelenik meg teljes egészében a terminal emulator-ban, majd látszólag az AVR is megáll. Nem küld több üzenetet a soros porton és az egyéb I/O lábak sem reagálnak.
Uploaded with ImageShack.us
Itt látható róla kép.
Bár nem tudom hogy mennyire számítanak a következők, de kezdőként ezekre tudok gondolni hibaforrásként:
-Nem kvarcot hanem a belső oszc.-ort használom 4MHz-en
-Majd ezt osztom hogy 9600 legyen a baudrate, ez ügye bascom szerint is 0,16% hibalehetőséget hordoz.
Végül a kód:
Kód: Egész kijelölése
$crystal = 4000000 'Sebesseg
$regfile = "M8def.dat" 'Chip
$baud = 9600
Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Cha Alias Pind.2
Chb Alias Pind.3
Led1 Alias Portb.3 'kimenetnek a pinb.3 helyett csak portb.3-ként fogadja el
Led2 Alias Portb.2
Led3 Alias Portb.1
Config Cha = Input
Config Chb = Input
Config Led1 = Output
Config Led2 = Output
Config Led3 = Output
Config Serialout = Buffered , Size = 20
Config Int0 = Change
Const Debouncetime = 800 'prellegés kivárás ideje
Const Wtime = 1
Dim Encounter As Byte 'enkóder által vezérelt változó
Dim Encounter_check As Byte
Set Chb 'felhúzó ellenállás bekapcsolva
Set Cha
On Int0 Getencoder1 'INT0 megszakításra ugorjon a "Getencoder" alprogramba
Encounter = 0
Enable Interrupts
Enable Int0
Waitms 100
Print "Encounter: " ; Encounter
Do
Select Case Encounter
Case 1 : Set Led1
Waitms Wtime
Reset Led1
Case 2 : Set Led2
Waitms Wtime
Reset Led2
Case 3 : Set Led3
Waitms Wtime
Reset Led3
End Select
Loop
End
Getencoder1:
Waitus Debouncetime
If Cha = 0 Then
If Chb = 1 Then
If Encounter < 127 Then
Incr Encounter
End If
Else
If Encounter > 0 Then
Decr Encounter
End If
End If
Else
If Chb = 0 Then
If Encounter < 127 Then
Incr Encounter
End If
Else
If Encounter > 0 Then
Decr Encounter
End If
End If
End If
If Encounter_check = Encounter Then
Else
Disable Int0
Print "Encounter: " ; Encounter
Enable Int0
Encounter_check = Encounter
End If
Gifr = 64 'törli a prellegés miatt mentett megszakításokat
Return
Ez itt több helyen is vérzik...
Egy meglévő applikációmból:
Tanulság: Interrupt kezelő szubrutinban nem írjuk le a Háború és Békét, mert megy a drága processzor idő!
Amikor visszatér , majd kiszámolgatod az értéket! Encoder esetében vagy felfutó, vagy lefutó élt figyelj. Ez úgy általában is igaz:) Lásd Config.
Íme egy működő szoftveres soros port egy tiny13-as progamból:
Ne aggódj, mindenki beleszaladt ezekbe a hibákba!
Amúgy, ha nem kritikus nem kell a hardwares interruptot használni! Mondjuk itt kifejezetten megéri!:)
Prellegésre, meg ott a debounce "parancs"!
üdv
KN
Egy meglévő applikációmból:
Kód: Egész kijelölése
Config Int0 = Falling
On Int0 Getencoder
Getencoder:
If Cha = 0 Then Decr Encounter Else Incr Encounter
Return
Amikor visszatér , majd kiszámolgatod az értéket! Encoder esetében vagy felfutó, vagy lefutó élt figyelj. Ez úgy általában is igaz:) Lásd Config.
Íme egy működő szoftveres soros port egy tiny13-as progamból:
Kód: Egész kijelölése
Open "comb.4:9600,8,n,1,inverted" For Output As #1
Open "comb.2:9600,8,n,1,inverted" For Input As #2
Amúgy, ha nem kritikus nem kell a hardwares interruptot használni! Mondjuk itt kifejezetten megéri!:)
Prellegésre, meg ott a debounce "parancs"!
üdv
KN
Köszönöm a segítséget. Próbáltam csak a felfutó élt figyelni, de úgy csak minden második pozícióban reagált a forgatásra. Mindenesetre majd rendbe szedem a programot.
Van viszont egy újabb problémám. Vettem 4MHz-es kvarcot mert a végleges baudrate-el így lehet majd maradék nélkül osztani. Betűzdeltem a próbapanelba, az XTAL1 és 2 láb közé, a két végét pedig 33pF-os kondenzátorral a földre kötöttem. Ezután a manual program ablakban a fuse biteknél átállítottam az órajel forrását külső 4Mhz-esre és rákattintottam a write fusebits gombra. Azóta nem fut a program, és a programozón keresztül sem sikerül megnyítni a fusebiteket, vagy új programot égetni. A fuse biteknél egész pontosan a "readlb entry not found" üzenetet küldi, amire rákerestem itt a fórumon, de az alapján én nem tudtam mihez kezdeni.
Üdvözlettel:
SzA
Van viszont egy újabb problémám. Vettem 4MHz-es kvarcot mert a végleges baudrate-el így lehet majd maradék nélkül osztani. Betűzdeltem a próbapanelba, az XTAL1 és 2 láb közé, a két végét pedig 33pF-os kondenzátorral a földre kötöttem. Ezután a manual program ablakban a fuse biteknél átállítottam az órajel forrását külső 4Mhz-esre és rákattintottam a write fusebits gombra. Azóta nem fut a program, és a programozón keresztül sem sikerül megnyítni a fusebiteket, vagy új programot égetni. A fuse biteknél egész pontosan a "readlb entry not found" üzenetet küldi, amire rákerestem itt a fórumon, de az alapján én nem tudtam mihez kezdeni.
Üdvözlettel:
SzA
Lehet, véletlenül External Clock-ra állítottad, akkor kavics ki, külső oszcikocka rá és újraprog. Rosszabb esetben (mint én) a belső 128kHz-re állítottad, akkor csak nagyfesz programozó hozza vissza.
(vagy még az szokott lenni, hogy nem oda dugom a kavicsot a próbapanelen, kontakthibás, de végső esetben pár leejtés után lehet hibás is a kvarc).
(vagy még az szokott lenni, hogy nem oda dugom a kavicsot a próbapanelen, kontakthibás, de végső esetben pár leejtés után lehet hibás is a kvarc).