Hallo,
Heb de picbasic cursus gevolgd, maar hier komt seriele communicatie niet in voor.
Nu heb ik het volgende probleem. Ik heb een apparaat wat continu seriele data verzend. Deze data bevat 2 woorden van elk 16bits. De data wordt verzonden met een baudrate van 19k2. Deze data wil ik gaan filteren en dan de waarde op een display zetten. In het protocol wat ik heb staat precies omschreven welke bit waarvoor is. Ook is het apparaat Uart. Heb al veel gezocht op het net, maar kom er totaal niet uit. Kan iemand mij vertellen of een link oid sturen hoe ik moet beginnen?
~Galaxy
In the beginning there was nothing.... and even that exploded...
Kijk eens in de helpfile van Proton+
Daar staat zat info over serieele communicatie.
Trefwoorden: Hrsin, Hrsouit, Rsin, Rsout, Serin, Serout.
Bedankt voor de info.
Nu wil ik onderstaand programma compilen, krijg ik een error dat ik een waarde moet invullen???
gaat fout bij de regel waar HRSERIN staat.
Wat doe ik nu fout??
' Receive values serially and timeout if no reception after 1 second (1000ms).
DEVICE 16F628A
XTAL = 4
HSERIAL_BAUD = 9600 ' Set baud rate to 9600
HSERIAL_RCSTA = %10010000 ' Enable serial port and continuous receive
HSERIAL_TXSTA = %00100000 ' Enable transmit and asynchronous mode
HSERIAL_CLEAR = ON ' Optionally clear the buffer before receiving
DIM VAR1 AS BYTE
Loop:
HSERIN , 1000 , Timeout , [VAR1] ' Receive a byte serially into VAR1
PRINT DEC VAR1 , " " ' Display the byte received
GOTO Loop ' Loop forever
Timeout:
CLS
PRINT "TIMED OUT" ' Display an error if HSERIN timed out
STOP
gaat niet werken, je baud rate staat niet goed
moet 19200 zijn geen 9600
en volgensmij werkt dat alleen met een 20 Mhz kristal.
zoek eens op het forum, ik er hele stukken en voorbeelden van gegeven, helaas nu geen tijd om alles opnieuw uitte typen
Waarom staat er een , net achter het commando HSERIN?
Laat maar, komt zo uit de manual, er is nog een optionele parameter.
HSERIN , 1000 , Timeout , [VAR1]
Waarom blokhaken gebruikt?
In de manual staat:
HSERIN , {1000 , Timeout}
En een heel verhaal over modifiers en variabelen.
Btw: Gebruik voor het posten van code de code-tags, zie de FAQ.
[Bericht gewijzigd door Henry S. op (18%)]
zo doen we dat in ASM:
;****************************************************************************
; program for making a standard hitachi lcd controllable by serial commands
;runs on a pic 16f628A on 4Mhz, comms is 19k2,8,n,1
; (c) M.A. Pals 2007
;****************************************************************************
; Revision : 0.06 Init LCD now works
; : 0.07 inproved lcd routines. no garbage on screen anymore!
; : 0.08 trying to be fasterrrr...
; : 0.09 faster! faster!
; : 0.10 trying 9600 baud and 19k2: pass!
; : 0.11 now implemement the interrupt handling of RX data: done!
;****************************************************************************
LIST P=16F628A,f=inhx8m,r=hex
INCLUDE ".\P16F628A.inc"
; Special symbolic names for this project
LCD_POS EQU 0x30 ;position on the LCD
LCD_CHR EQU 0x31 ;character or command to send to the LCD
LCD_PNT EQU 0x32 ;RS232/LCD memory pointer
LCD_DAT EQU 0x40 ;RS232/LCD memory start (20 bytes)
;data is on port B: 4 bit LCD data is on RB4 to 7
E EQU 0 ;PORTA, bit 0
RS EQU 1 ;PORTA, bit 1
RW EQU 2 ;PORTA, bit 2
;Configuration word setting
__CONFIG _BODEN_ON &_CP_OFF &_DATA_CP_OFF &_PWRTE_OFF &_WDT_OFF &_LVP_OFF &_MCLRE_ON &_HS_OSC
; Begin code at 0
org 0x00 ; origin
goto start ;goto start vector
org 0x04 ;this is the INT vector
goto inthnd ;this is the name of the inthandler subroutine
;---- initilisiation ----
start:
call initall ;initialize all PIC global settings
call LCDInit ;initialize LCD
call ActivateInt ;activate the interrupts
;---- main program ----
mainlp:
btfsc PORTB,3
goto dolo
bsf PORTB,3
goto mainlp
dolo bcf PORTB,3
goto mainlp
;---- init routines and subroutines go here ----
initall:
call bank0 ;be sure we're in bank 0
movlw H'007'
movwf CMCON ;comparators off
movlw b'00000000' ; set up portA
movwf PORTA
movlw b'00000100' ; RB2(TX)=1 others are 0
movwf PORTB
call bank1 ;set bank 1
movlw b'11110000' ; RA0-3 output, others input
movwf TRISA ; portA all pins input
movlw b'00000010' ; RB1(RX)=input, others output
movwf TRISB
movlw 0x0C ; 0C hex = 19200 baud / 19hex = 9600 baud / 33hex = 4800 baud
movwf SPBRG ; put in register
movlw b'00100100' ;BRGH=1 and TXEN=1
movwf TXSTA ;put in register
call bank0 ;set bank 0
movlw b'10010000' ;SPEN=1 and CREN=1
movwf RCSTA ;put in register
call longwt ;wait some
movf RCREG,W ;flush receive buffer
movf RCREG,W ;flush receive buffer
movf RCREG,W ;flush receive buffer
return
ActivateInt:
call bank0
clrf PIR1 ;make sure these interrupt flags are clear
movlw b'11000000' ;enable interrupt mask to peripheral interrupts & set interrupt enable
movwf INTCON
call bank1
movlw b'00100000'
movwf PIE1 ;enable serial RX interrupt
call bank0
return
;---- LCD init routines and subroutines go here ----
LCDInit:
call longwt ;wait for the LCD to become settled
movlw b'00100000' ;goto 4 bit mode
movwf LCD_CHR ;put in RAM
call LCD_SendCMD ;perform the command
movlw b'00100000' ;lcd data setup: font etc (only upper nibble is significant) : 1st part
movwf LCD_CHR ;put in RAM
call LCD_SendCMD ;perform the command
movlw b'10000000' ;lcd data setup: font etc (only upper nibble is significant) : 2nd part
movwf LCD_CHR ;put in RAM
call LCD_SendCMD ;perform the command
movlw b'00000000' ;lcd display on (only upper nibble is significant) : 1st part
movwf LCD_CHR ;put in RAM
call LCD_SendCMD ;perform the command
movlw b'11110000' ;lcd display on (only upper nibble is significant) : 2nd part
movwf LCD_CHR ;put in RAM
call LCD_SendCMD ;perform the command
movlw b'00000000' ;clear display (only upper nibble is significant) : 1st part
movwf LCD_CHR ;put in RAM
call LCD_SendCMD ;perform the command
movlw b'00010000' ;clear lcd display (only upper nibble is significant) : 2nd part
movwf LCD_CHR ;put in RAM
call LCD_SendCMD ;perform the command
movlw b'00000000' ;autoincrement display (only upper nibble is significant) : 1st part
movwf LCD_CHR ;put in RAM
call LCD_SendCMD ;perform the command
movlw b'01100000' ;autoincrement display (only upper nibble is significant) : 2nd part
movwf LCD_CHR ;put in RAM
call LCD_SendCMD ;perform the command
return
LCD_SendCMD:
;THIS ROUTINE DOES HALF A COMMAND! so it has to be run twice for each command (except goto 4 bit that is)
bcf PORTA,RS ; Set RS in command mode
bcf PORTA,RW ; Set RW in write mode
movlw b'00001111' ;set mask
andwf PORTB,SAME ; Clear the upper nibble on the port
movf LCD_CHR,W ; load the char to send in W (upper nibble)
andlw b'11110000' ; Get upper nibble of char
iorwf PORTB,SAME ; Send data to LCD
call ToggleE ;issue the command
call lcdwt ;wait some
return
LCD_SendCHR:
bsf PORTA,RS ; Set RS in char mode
bcf PORTA,RW ; Set RW in write mode
movlw b'00001111' ; set mask
andwf PORTB,SAME ; Clear the upper nibble on the port
movf LCD_CHR,W ; load the char to send in W (upper nibble)
andlw b'11110000' ; Get upper nibble of char in W only
iorwf PORTB,SAME ; Send data to LCD
call ToggleE ; issue the command
call lcdwt ; wait some
movlw b'00001111' ; set mask
andwf PORTB,SAME ; Clear the upper nibble on the port
swapf LCD_CHR,W ; load the char to send in W (lower nibble)
andlw b'11110000' ; Get upper nibble of char in W only
iorwf PORTB,SAME ; Send data to LCD
call ToggleE ; issue the command
call lcdwt ; wait some
return
ToggleE:
bsf PORTA,E ;put E high
call shrtwt ;wait some
bcf PORTA,E ;Put E low
return
;---- Interrupt handling routines and subroutines go here ----
inthnd:
btfss PIR1,RCIF ;check whether char was received
retfie ;it wasn't.....
movf RCREG,W ;store char in w
movwf LCD_CHR ; store the char in LCD_CHR RAM
movwf TXREG ;send away char in W
call LCD_SendCHR ;send to the LCD
clrf PIR1 ;reset the interrupt
retfie ;return from interrupt.
;---- wait routines and subroutines go here ----
;short wait loop
shrtwt movlw 0x3
movwf SR1
lusje decfsz SR1,SAME
goto lusje
return
;long wait loop
longwt movlw 0x20
movwf SR1
outer movlw 0xFF
movwf SR2
inner decfsz SR2,SAME
goto inner
decfsz SR1,SAME
goto outer
return
;lcd wait loop:
lcdwt movlw 0x05
movwf SR1
lusje2 decfsz SR1,SAME
goto lusje2
return
;---- bank switch routines go here ----
bank0 bcf STATUS,RP0
bcf STATUS,RP1
return
bank1 bsf STATUS,RP0
bcf STATUS,RP1
return
END
fripster
PS: SR1 tm SR2 zijn RAM locaties. (Scratch RAM...)
~Galaxy
In the beginning there was nothing.... and even that exploded...
dat hrsin heb ik nu werkend.
Ik heb het getest met proton IDE.
Ik krijg nu als ik via de uart in 't programma
een getal zend, een getal op mijn display.
Nu nog het protocol omzetten naar leesbare waardes.
bit |15|14| 13| 12| 11| 10|09|08|07|06|05|04|03|02|01|00
| | | | | | | | | | | | | | | |
wrd 0| 0| 1| 0| x | x | x | 1|A7| 0|A6|A5|A4|A3|A2|A1|A0
wrd 1| 0| 0|B12|B11|B10| B9|B8|B7| 0|B6|B5|B4|B3|B2|B1|B0
x zijn getallen die 1 of 0 kunnen zijn, maar waarmee ik niets hoef te doen
van word 0 zijn 15,13 en 7 altijd 0; bit 14 en 9 zijn 1
van word 1 zijn 15,14 en 7 altijd 0
A7 t/m A0 is een waarde
B12 t/m B0 is een waarde
Die 2 waarden gaan in een formule, en de uitkomst hiervan wil ik op een lcd hebben.
Hoe kan ik die waarden uit mijn seriele data krijgen?
Kan iemand mij dit aub uitleggen?
heeft er misschien iemand een idee of link die me hier naar toe verwijst. Heb al behoorlijk wat gegoogled maar kom er gewoon niet uit. Ook met proton kom ik er niet uit.
Picbasic voorbeelden??
[Bericht gewijzigd door Henry S. op (10%)]
Wat ik er uit opmaak: Je getallen komen steeds in twee delen binnen.
A0-A6 en B0-B6 zijn direkt klaar voor gebruik.
dit is een 7 bits getal.
A7 kan je testen of dit bit wel of niet gezet is, 0 dan is het uiteindelijke getal A A0-A6 binair. (0-127 decimaal)
Als A7 1 is dan moet je 128 er bij optellen (getal A is dan een 8- bits getal, 0-255 decimaal). Overige bits buiten beschouwing laten.
Voor getal B geldt hetzelfde, bits testen en optellen bij het eerste gedeelte.
Dit is het eenvoudigste te doen met bitwise operators, zie de PIC basic manual vanaf pagina 80.
heb mijn rs232 bron even aan de computer gehangen.
Heb een programma gebruikt waarin de seriele info hexadecimaal binnenkomt.
Nu krijg ik iedere x de volgende informatie
B2 82 53 13 03 41
B2 82 53 13 03 41
B2 82 53 13 03 41
B2 82 53 13 03 41
B2 82 53 13 03 41
B2 82 53 13 03 53
B2 82 53 13 03 53
B2 82 53 13 03 53
B2 82 53 13 03 53
B2 82 53 13 03 53
B2 82 53 13 03 5D
B2 82 53 13 03 5D
B2 82 53 13 03 5D
B2 82 53 13 03 5D
B2 82 53 13 03 5D
B2 82 53 13 03 6B
B2 82 53 13 03 6B
B2 82 53 13 03 6B
B2 82 53 13 03 6B
B2 82 53 13 03 6B
B2 82 53 13 03 75
dit natuurlijk achter elkaar. Zoals je ziet veranderd eigenlijk alleen de achterste data.
B2 82 53 13 is bijna altijd hetzelfde.
Hier hoef ik ook niets mee te doen.
Weet hier nu wel de betekenis van, maar dit heeft met de instelling van het apparaat te maken.
Voor mij zijn alleen de laatste vier belangrijk.
Als ik nu ga kijken in mijn protocol is dat het tweede word (word1).
Als ik dan de getallen in het protocol plaats, krijg ik het volgende
vb.
03 41 > 0000001101000001
hier wil ik deze >0< uithalen zodat
dit overblijft 111000001
Hoe kan ik dit het beste doen?
Heb al veel gelzen en geprobeerd, maar ik kom er niet uit
En welk commando kan ik gebruiken om het eerste getal(B2 82 53 13) niet te gebruiken? (is dit dan SKIP 6)?
Op 5 september 2007 19:25:20 schreef Henry S.:
Voor getal B geldt hetzelfde, bits testen en optellen bij het eerste gedeelte.
Dit is het eenvoudigste te doen met bitwise operators, zie de PIC basic manual vanaf pagina 80.
Ik zou het nog anders doen, schuif het eerste byte van B (die B7-B12 bevat) twee bits naar rechts. check of het carry-bit geset is, zo ja, dan was B7 een 1 en moet je bij het tweede byte 128 optellen.
nu doe je het tweede byte + 256* het eerste byte en je bent klaar, gaat sneller dan elke bit in het eerste byte testen en al dan niet 128, 256, 512, 1024, 2048 of 4096 optellen.
Ik zie nu net dat in picbasic ook met assembler codes gewerkt mag worden
Ik gebruik nu onderstaande:
' ontvang serieel en timeout als er geen informatie ontvangen word na 1 seconde (1000ms).
device 16f628
xtal = 4
hserial_baud = 19200 ' zet baudrate 19200
hserial_rcsta = %10010000 ' Enable serial port and continu ontvangen
hserial_txsta = %00100000 ' Enable zenden and asynchrone mode
hserial_clear = On ' clear buffer voor ontvangst
Dim lc1 As word 'moet 2 woorden ontvangen
begin:
lc1 = hrsin , {1000, timeout} ' ontvang word serieel in lc1
print AT 1,1, "waarde:" , hex lc1, " " ' zet ontvangen waarde op lcd
Goto begin ' ga naar begin
timeout:
cls
print "geen data" ' zet "geen data" op scherm als er niets ontvangen wordt
stop
geen idee hoe ik nu verder moet
kan iemand me helpen?
[Bericht gewijzigd door Henry S. op (5%)]
Fantomaz
Ik moet hier weer vaker komen... Wat kun je zo'n forum als deze gaan missen. :-)
Van lezen gesproken...
Valt geen K*t van te lezen wanneer het bijlange na niet op mijn scherm past... 
Op 7 september 2007 19:50:42 schreef Henry S.:
Manual al gelezen?
Heb alleen de proton help
Heb geen boek.
Waar is dat te halen?
Zit bij de volledige versie en is als pdf te downloaden:
http://www.circuitsonline.net/download/view/71
bedankt. hier heb ik wat aan.
nog een vraagje:
Heb al wel gelezen hoe je bijvoorbeeld de data achter een bepaalde code kunt binnenhalen met het commando wait.
Nu kan het voorkomen dat de data voor het gedeelte wat ik moet hebben niet continu hetzelfde is. Kan ik ook bepaalde bits (alleen de bits B0 t/m 12 in mijn voorbeeld) uit de seriele informatie halen?
Zo ja, hoe moet dit dan.
Kom er nog steeds niet uit hoe ik dit moet oplossen
als ik alles inlees krijg ik de volgende info: b2 82 43 13 03 41.
ipv 43 ook ooit 53.
het gaat mij alleen om 03 41. hoe haal ik dit eruit en zet dit op het display?
als dit nl. lukt kan ik het getal verder gaan bewerken met de instructies
alvast bedankt