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?

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

Klopt, maar dit heb ik als testprogramma gebruikt. Zelfs dit kan ik niet compilen

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...)

Probeer het eens met Hrsin. Dat werkt wat vriendelijker.

dat asm voorbeeld snap ik echt niets van helaas!!
Zal eens proberen met Hrsin
bedankt voor reacties

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.

bedankt voor de info.
Hier kan ik morgen weer mee verder.

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 moet nog een hoop leren zie ik wel.
Maar hoe gaat dat in picbasic?
weet je dat toevallig ook?

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%)]

iemand misschien een voorbeeldje??

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

Eerst alles inlezen, daarna filteren.

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