Sida 1 av 2

PIC -> PIC via RS232 nya frågor..

Postat: 1 mars 2012, 20:24:32
av Variosboy
I ett av mina projekt använder jag mig av en PIC16F628A för att samla in data som jag presenterar på en display.
Nu tänkte jag ta detta ett steg längre genom att samla in data som jag gör idag, men istället för att skicka det direkt till displayen så vill jag skicka data via RS232 i ett tiotal meter kabel för att sedan tas emot av en annan PIC som i sin tur presenterar data på displayen.

Har fått ordning på koden i den sändande enheten så att jag kan se resultatet på min PC ett terminalfönster.

Det var lite bakgrund det, nu till min fråga:

Den data jag vill skicka består av värdet hos 14 bitar.
Jag får alltså skicka detta i två byte.

Vad jag inte är med på och inte har hittat något svar på (då jag inte riktigt vet vad jag ska söka på) är hur man ska skicka för att mottagande enhet ska kunna hålla reda på vad som är vad!? Vilken byte som är vilken alltså..

Först tänkte jag skicka 7 bitar i ena byten och 7 i den andra och låta den sista biten som blir över i varje byte vara antingen 1 eller 0 beroende på vilken byte det är. Då kan man ju med lätthet urskilja i mottagaren vilken som är vilken.
Men om jag vill skicka tre eller fler byte framöver så funkar ju inte detta..

Vad säger expertisen? Vart ska jag läsa mig till hur man gör och hur man bör tänka?
Har sökt här och googlat lite planlöst, men vet som sagt inte vad jag ska söka på riktigt, så en liten knuff i rätt riktning är vad jag efterfrågar.

Tack på förhand

EDIT: Ämnesraden.. (2012-03-11)

Re: PIC -> PIC via RS232 en enkel fråga..

Postat: 1 mars 2012, 21:00:05
av jesse
Det finns ett antal olika sätt att göra detta på, och jag tror inte det finns 'den perfekta lösningen' utan man får anpassa efter hur dina data ser ut , hur ofta det sänds osv...

Din lösning med två bytes var ju smart, så om du inte behöver fler bytes kan du ju göra så till en början.

Annars finns lite varianter som sagt: Enklast är om du alltid har bara 7 bitar i all data. Då kan första byten alltid ha bit7 = etta, och följande bytes har bit7 = nolla. Då är det bara att köra på sen. så länge datan har bit7= nolla så är det bara att räkna bytes.

Om du absolut vill ha åtta-bitars data blir det svårare:

1) tidskritiska: man har en paus på en viss tid (t.ex 1 ms) mellan meddelandena. När meddelandet sedan kommer kan man t.ex skicka ett i förväg bestämt antal bytes (4, 8, 16 ,32 64 eller 128 bytes t.ex beroende på behov) . Mellan dessa får inte gå lägre tid än 0.5 ms.... På så vis vet mottagaren att om det gått mer än 0.75 ms så börjar en ny serie.

2) start-och stopp-bytes med checksumma. Du inleder med en eller två standard-bytes, följt av en byte där antalet databytes anges - sedan kommer data (i rätt antal) och avslutas sedan med en checksummebyte och eventuellt en stoppbyte. Det kan krävas lite klurighet för att få det att fungera. T.ex. kan man köra med 'bytestuffing': Om startbytena är t.ex. tecknen AA så får inte datan innehålla två A i rad. Ett A måste då alltid följas av ett extra byte som inte är ett A och som bara fungerar som utfyllnad.

Enklast är nog att sända allt i ascii-kod. Låt bara vissa tecken vara godkända, t.ex. '0'-'9' samt 'A'-'Z' och kanske komma, kolon, punkt. Då kan man använda ett start-tecken och ett slut-tecken so är unika. Ofta används $-tecknet som start-tecken och 0x0d (carriage return) som stopptecken.

Mottagaren väntar då tills ett $-tecken kommer in. Hur mycket data det än strömmar in före det så ignoreras det.
Men efter $-tecknet läser man in all data ända tills man får in ett 0x0d. Då har man fått in en 'sträng' som sedan kan bearbetas. Fördelen med ascii och 0x0d är ju att man kan kommunicera manuellt via terminal och få 'return'-tangenten att fungera som 'sänd'. Sedan är det fritt valt om man vill skicka siffror som hex-code eller decimalt eller på annat vis. Vill man verifiera att rätt data kommit fram beräknar man en checksumma på alla tecken och skickar med den före return-tecknet i hexadecimal form (två tecken) med en stärna ('*') före. Stjärnan och dollartecknet får då inte förekomma någon annanstans i strängen.

exempel:

$TMP:23:220*A6<cr>

=> sätt temperatur i punkt 23 till 220 grader.
(Checksumman (A6) påhittad - orkade inte räkna ut)

$BATT:3410:3440:3415:3425*D6<cr>

=> skickar spänningsnivåer på fyra battericeller.

Re: PIC -> PIC via RS232 en enkel fråga..

Postat: 1 mars 2012, 21:19:56
av Variosboy
Tack för ett mycket bra svar!

Tror att lösningen med en startbyte stoppbyte och checksumma med ett förutbestämt antal byte kan bli rätt bra i mitt fall Dels för att det verkar enkelt att lägga till en byte om det blir så att jag vill skicka mer data, plus att det blir en säkrare överföring än den jag själv först tänkte..

Återkommer när jag kodat och kört huvudet i väggen ett par gånger! :wink:

Re: PIC -> PIC via RS232 en enkel fråga..

Postat: 1 mars 2012, 21:24:31
av sodjan
> Enklast är nog att sända allt i ascii-kod.

Det är ett väldigt bra tips!
Det hela blir så jäkla mycklet enklare att felsöka, en vanlig
terminalemulator kan enkelt användas för att både lyssna på
sändaren och för att testa mottagaren...

Re: PIC -> PIC via RS232 en enkel fråga..

Postat: 1 mars 2012, 21:42:44
av jesse
Ja. När jag var nybörjare på det här så var jag fast bestämd att sända binärt, åtta bitar per byte, för att spara in överförings-tid. Men när jag hållt på ett tag undviker jag det om det inte är helt nödvändigt. Precis som Sodjan säger - det är väldigt bekvämt med ascii! Särskilt om man följer några enkla regler (som mina exempel ovan).

Re: PIC -> PIC via RS232 en enkel fråga..

Postat: 4 mars 2012, 17:33:22
av Variosboy
Nu har testats lite men jag gör något fel...

Har kopplat upp följande:

En 16F628A med en kod i som räknar ner en räknare från 100 till 0 och sen börjar om. Den räknare ner med några sekunders mellanrum och varje gång den räknat ner ett snäpp så skickar den ut detta som seriell data..

Utgången har jag kopplat till en trådlös sändare ER400TS och en bit bort på samma platta sitter en ER400RS, och en MAX232 + en transistor som agerar nivåomvandlare då utgången på ER400RS ger 3,3V som hög.
MAX232:an är i sin tur kopplad till en RS232-port (Eller ja, en RS232 -> USB).

Med programmet Terminal v1,9b kan jag nu se på skärmen att det kommer data och att sändningen av data är korrekt. Den räknar ner från 100 till 0 och börjar sen om på 100 igen...

Men, nu kommer mitt men..

Har ett LOW PIN COUNT DEMO BOARD kopplat till en LCD där jag vill pressentera data. Inkopplingen av detta är gjord så att GND på ER400RS och LOW PIN COUNT kortet är gemensam, sen är datalinjen kopplad parallellt med data in på ER400RS till RB5 på LOW PIN COUNT kortet..

Och det är här mitt problem kommer in.

Har klippt och klistrat ihop Sodjans kod med en kod från piclist.org för att skriva ut datan på en LCD.
Visningen fungerar så tillvida att att jag får ett värde utskrivet på displayen, men det är inte det förväntade värdet (alltså det värde som skickas och som visas på min PC) plus att det inte skrivs ut ett nytt värde varje gång sändaren skickar, utan det kommer ett lite då och då)

Skickar i 19200 BAUD, 8 databitar, 1 stopbit utan paritet.
Allt enligt följande kodsnutt i 16F628A:an

Kod: Markera allt

; ------------------------------------ 
; SET BAUD RATE TO COMMUNICATE WITH PC 
; ------------------------------------ 
; Boot Baud Rate = 19200, No Parity, 1 Stop Bit 
; 
        movlw 0x0C              ; (0x19=9600 bps) 0x0C=19200 bps
        movwf SPBRG 
        movlw b'00100100'       ; brgh = high (2) 
        movwf TXSTA             ; enable Async Transmission, set brgh

        bcf STATUS,RP0          ; RAM PAGE 0

        movlw b'10010000'       ; enable Async Reception 
        movwf RCSTA 

Mottagande kod är som sagt lite klipp och klistra mellan två koder så det är ju skrivet på lika olika vis, men ändå, här kommer ett klipp ur koden för mottagning av data:

Kod: Markera allt

; ------------------------------------ 
; SET BAUD RATE TO COMMUNICATE WITH PC 
; ------------------------------------ 
; Boot Baud Rate = 19200, No Parity, 1 Stop Bit 
; 
        movlw 0x0C              ;( 0x19=9600 bps) 0x0C=19200 bps 
        movwf SPBRG 
        movlw 0x00
	movwf SPBRGH
	bcf BAUDCTL,BRG16		; Clear BRG16 = 8 BIT mode
        bcf STATUS,RP0          ; RAM PAGE 0

        movlw b'10010000'       ; enable Async Reception 
        movwf RCSTA 
Sen delen av koden där mottagningen sker:

Kod: Markera allt

receive
		nop
		btfss PIR1,RCIF         ; (5) check for received data 
                goto receive
                movfw 	RCREG            ; save received data in W 
		movwf	räknare           ; Sparar mottaget värde i "räknare" som sen i nästa rutin skickas till displayen..
		
        return 
Har testat att lägga in följande två rader efter "movwf räknare":

Kod: Markera allt

movlw 0xFF
movwf räknare
Och då blir utskriften 255 på displayen. (Har även testat med andra värden)
Utskriftstutinen gör om binära tal till BCD och skickar först hundratal, sen tiotal och sist ental till displayen..
Så den delen fungerar också som tänkt.


Gör jag en enkel tankevurpa, eller har jag helt missförstått hur det ska gå till när det gäller att ta emot data??


OSB, mottagaren är en PIC16F690..

Re: PIC -> PIC via RS232 en enkel fråga..

Postat: 4 mars 2012, 19:05:44
av Icecap
Mitt tips är att i mottagningsdelen inte använda "goto Recieve" men istället "call Recieve"...

Re: PIC -> PIC via RS232 en enkel fråga..

Postat: 4 mars 2012, 19:17:47
av Variosboy
blir inte det helt fel??

"Receive" är ju en subbrutin som anropas från huvudprogramloopen, och för att slippa lägga in en "loop" raden under receive som man i kontrollen av RCIF kör goto till så antar jaga att författaren (inte jag) tänkt..

Jag tänker att om jag skriver call receive där så kommer det ju att fylla stacken tillslut eftersom man kommer tillbaka till call receive hela tiden om man kör call istället för som nu goto så länge ingen mottagning skett. Eller!?

Det är ju tänkt som en evighetsloop tills dess att data kommer in via serielänken.

Re: PIC -> PIC via RS232 en enkel fråga..

Postat: 4 mars 2012, 19:26:43
av Icecap
Sorry, my bad. Läste lite slarvigt och du har rätt.

Men det är ganska bra klarat att du har svenska tecken i variabelnamnen, det har jag aldrig lyckats med...
Vilken felhantering har du? Ett standardfel är att man inte börjar med att sätta TX-pinnen till '1' och sedan startar UART'en, står den på '0' kommer första tecknet att bli bortkastat pga. att startbit'en missas.

Re: PIC -> PIC via RS232 en enkel fråga..

Postat: 4 mars 2012, 19:30:12
av Variosboy
För övrigt är det modulerna jag köpte av dig som jag kopplat in, funkade perfekt på en gång! :)

Sänder förvisso ungefär 10cm bara nu, men som du skrev när jag köpte dom så är det ju bara att "Bryta" upp signalen mellan sändare och mottagare och stoppa in modulerna istället. plus transistorn då för nivån ut ut mottagaren. Men otroligt smidigt som sagt och nu när jag kollade igenom loggen i terminalprogrammet kan jag konstatera att sändningen varit utan avbrott eller felaktigheter i ungefär 4 timmar nu.. Känns också bra!

Re: PIC -> PIC via RS232 en enkel fråga..

Postat: 11 mars 2012, 19:58:02
av Variosboy
Nu har jag grejat lite mer med min mottagarkod, men får det inte att fungera som jag vill.

Nedan finns hela mottagarkoden..

Förväntat resultat är att den byte som läses in på RB5 (RX) ska konverteras (via rutin BIN2BCD) och skrivas ut på en LCD.

Sändande enheten är som jag skrev tidigare i tråden en 16F628A, TX på denna är kopplad både till en MAX232 och även till den 16F690 som displayen är kopplad till.

Koden i 16F628A syns i ett av inläggen ovan, och vad den gör är alltså att räkna ner en räknare från 100 till 0 och sen börja om, och för varje gång den räknat ner ett snäpp så skickas denna byten ut via serieinterfacet.
Har denna inkopplad till min PC där jag via terminalfönstret kan verifiera att "rätt/förväntad" data kommer som den ska..

Nu till problemet.

På min display får jag endast dessa utskrifter i decimal form:
252 (skrivs ut när jag i terminalfönstret ser exvis. 7 eller 3 decimalt)
192 (skrivs ut när jag i terminalfönstret ser exvis. 10, 6 eller 2 decimalt)
060 (skrivs ut när jag i terminalfönstret ser exvis. 9, 5 eller 1 decimalt)
000 (skrivs ut när jag i terminalfönstret ser exvis. 8, 4 eller 0 decimalt)

Data sänds med 3 sekunders intervall och först står det alltså 252 på displayen, sen 192, 060, 000 och sen börjar det om med 252..
Samma data in ger alltid samma resultat på displayen, men den alternerar alltså enbart mellan dessa fyra kombinationer..

Terminalprogramet är inställt för att ta emot i 19200 BAUD, 8 bitar, ingen paritet och med en stopp bit. Ingen handskakning..

Och här kommer koden:

Kod: Markera allt

;**********************************************************************
;                                                                     *
;    Filnamn:     trådlös display.asm
;    Datum:          2012-03-01
;    Fil Version:  1.0
;
;    Skapad av:        Morgan
;
;**********************************************************************
;
;    Filer som krävs:  	P16F690.INC
;                   	16F690.LKR
;
;**********************************************************************
;
;   Diverse:
;   Använder intosc på 4 Mhz.
;
;   E : RC3
;   RS: RC2
;   D4-D7 : RC4-RC7
;   R/W kopplad till GND (d.v.s ingen läsning av Busy-signalen).
;	Serielina in : RB5	
;**********************************************************************
;
;
; 
 list      p=16f690; 
 #include <P16F690.INC>
; 
 __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)
;
    errorlevel -302 
;
    #define     LCD_E       PORTC,3
    #define     LCD_RS      PORTC,2
    #define     LCD_PORT    PORTC
;   
;**********************************************************************
RESET_VECTOR    CODE    0x000       
     goto    start            	    
;
INT_VECTOR      CODE    0x004       
        retfie                      
;        
;
;**********************************************************************
; Macro för att skicka en text till LCD.
;
lcd_text   	macro   text_label
        banksel eeadr               ; byt till rätt bank...
        movlw   high text_label     ; bit 8-15 av adressen till texten
        movwf   eeadrh
        movlw   low text_label      ; bit 0-7 av adressen till texten
        movwf   eeadr
;
; Nu är de två adressregistren laddade med rätt adress.
; Anropa subrutinen för att hämta texten och skriva ut den.
;
        call    lcd_send_text
        banksel porta               ; Lämna rutinen i bank 0.
;
        endm
;
;**********************************************************************
; Huvudkoden.
; Här hamnar vi vid reset eller power-on (från RESET_VECTOR)
;
;
MAIN    CODE
start
;
; Först normal uppstart ej specifik för LCD
;
        banksel ansel               ; Stäng av alla analoga funktioner
        clrf    ansel
        clrf    anselh
        banksel trisa               ; Alla pinnar utgångar...
        clrf    trisa				 
        clrf    trisb				
		movlw b'00100000' 			; RB5 = ingång (RX = ingång)
		movwf	trisb
        clrf    trisc
;        
        banksel intcon
        clrf    intcon
        banksel porta               ; se till att vi är på bank 0.
		movlw	0x01				; Sätter räknare till 1 (decimalt)
		movwf	räknare
;**********************************************************************
; Inställning av baudrate
;**********************************************************************
; Baud rate = 19200, ingen paritetsbit, 1 stopp Bit 
; 
        movlw 0x0C              ;( 0x19=9600 bps) 0x0C=19200 bps 
        movwf SPBRG 
		movlw 0x00
		movwf SPBRGH
		bcf BAUDCTL,BRG16		; Nollar BRG16 = 8 BIT:s läge
        bcf STATUS,RP0          ; RAM PAGE 0
        movlw b'10010000'       ; enable Async Reception 
        movwf RCSTA 
; 
;**********************************************************************
; PROVIDE A SETTLING TIME FOR START UP 
;**********************************************************************
; 
        clrf dataL 
settle  decfsz dataL,F 
        goto settle

        movf RCREG,W 
        movf RCREG,W 
        movf RCREG,W            ; rensar mottagningsbufferten
;**********************************************************************
;
; Så då var grundinställningen av processorn klar.
; Nu går vi vidare med LCD hanteringen...
;
        call        lcd_init_hd44780    ; Ställ in LCD'n.
;
;Här kommer programloopen:
		call 	standardtext
		call	print_räknare
program	
		call	ta_emot
		call	print_räknare		
		goto	program
;
ta_emot
        movf    RCREG,W 
        movf    RCREG,W 
        movf    RCREG,W            ; rensa mottagarbufferten
ta_emot_loop
;		clrf	räknare
		nop
;		btfss	RCSTA,1			; Overflow?
;		bsf		RCSTA,4			; om ja nollställer vi 
		btfss   PIR1,RCIF         ; Kommit någon data? Om ja hoppar vi över nästa rad
        goto    ta_emot_loop
        movfw 	RCREG           ; Flyttar mottagen data till W
		movwf	räknare			; W till räknare...
;		movlw	0xFF			; Test för att se om rutinen för utskrift skriver ut på rätt sätt från "räknare"
;		movwf	räknare			; Resultat = Ja, testade värden, Ox00, Ox00, Ox0F, Ox1F och OxFF..
        return 

;-------------------------------------------
;Standardtext
;
;Skriver ut standardtexten på displayen:
;**********************************************************************
;(tre mellanslag) och sen ett %-tecken på översta raden på LCD:en
;------------------------------------------- 
standardtext	
		lcd_text	lcd_text1
		lcd_text	lcd_text2
	return

;-----------------------------------------------------
;Skriver ut värdet på räknare med början på possition ett rad ett
;-----------------------------------------------------
Print_Räknare
		movfw	Räknare			; värdet på räknare till W.
		movwf	BIN				; Vidare till variabeln BIN.
		call	BIN2BCD			; Anropar subrutin BIN2BCD som gör om
		movlw	0x80			; värdet i BIN till en byte för vardera hundratal, tiotal och ental.
		call	lcd_send_cmd	; Kommando till displayen för att sätta markören på rätt ställe
		movfw	huns			
		call	lcd_send_data	; Överför hundratal
		movfw	tens
		call	lcd_send_data	; Överför tiotal
		movfw	ones			
		call	lcd_send_data	; Överför ental
		call	delay_1s		; vänta lite...
	return

;**********************************************************************
; Variabler
;
; Nägra temp variabler som används av LCD rutinerna.
; Lägger dom i "shared memory" så slipper vi banksel...
;
LCD_VARS        UDATA_SHR
LCD_TMP1        RES 1
LCD_TMP2        RES 1
BIN				RES 1
huns			RES 1
tens			RES 1
ones			RES 1
COUNT			RES	1
Räknare			RES 1
datal			RES 1
;
;**********************************************************************
;
LCD_CODE        CODE
;
lcd_init_hd44780
;
        call    delay_1s        ; Ge LCD'n tid att starta...
        bcf     LCD_E           ; Se till att E och RS är
        bcf     LCD_RS          ; nollade...
;
; Skicka initkoder enligt manual för HD44780.
; För detaljer, se manual för HD44780 eller datablad för en LCD.
;
        movlw   h'30'
        call    lcd_send_4_bit
        call    delay_5ms
        movlw   h'30'
        call    lcd_send_4_bit
        call    delay_5ms
        movlw   h'30'
        call    lcd_send_4_bit
        call    delay_100us
        movlw   h'20'           ; Byt till 4-bitars interface !
;       
        call    lcd_send_4_bit
        call    delay_100us
;
; Allt härefter sänds som två
; 4-bittars "nibbles". Först
; den höga delen (bit 4-7) sedan
; den låga (bot 0-3).
; Se lcd_send_cmd och lcd_send_data för detaljer.
;
        movlw   b'00101000'     ; Function set
        call    lcd_send_cmd
        movlw   b'00010100'     ; Display/curs shift
        call    lcd_send_cmd
        movlw   b'00001100'     ; Display/curs on/off
        call    lcd_send_cmd
        movlw   b'00000110'     ; Entry mode set
        call    lcd_send_cmd
        movlw   b'00000010'     ; Display/curs home
        call    lcd_send_cmd
        movlw   b'00000001'     ; Display clear
        call    lcd_send_cmd
;
; För detaljer kring varje kommando oven hänvisas till
; manual för HD44780 eller ett datablad för en LCD.
;
        return
;
lcd_toggle_E
;
; Toggla E p LCD'n så att data på D4-D7 läses in.
;
        banksel lcd_port
        bsf     lcd_e
        nop
        bcf     lcd_e
        nop
        return
;
lcd_send_4_bit
; Data i W-reg bit 4-7 överförs till LCD_PORT bit 4-7.
; LCD_PORT bit 0-3 lämnas som de är.
;
        banksel lcd_port
        movwf   lcd_tmp1        ; Spara LCD data...
        movlw   b'00001111'     ; "Mask" för LCD_PORT
        andwf   lcd_port, w     ; Läs av LCD_PORT bit 0-3
        iorwf   lcd_tmp1, w     ; Kombinare med LCD data bit 4-7
        movwf   lcd_port        ; Skriv tillbaka till LCD_PORT.
        call    lcd_toggle_e    ; Och överför till LCD.
        return
;
lcd_send_cmd
; Data i W överförs till LCD som ett "kommando".
;
        banksel lcd_port
        bcf     LCD_RS          ; RS = "0" för kommando.
        call    lcd_send_byte   ; Skicka
        call    delay_5ms       ; Vänta 5 ms efter ett kommando.
        return
;
lcd_send_data
; Data i W överförs till LCD som "data".
;
        banksel lcd_port
        bsf     LCD_RS          ; RS = "1" för data
        call    lcd_send_byte   ; Skicka
        call    delay_100us     ; Ge LCD'n tid att bearbeta datat.
        return
;
lcd_send_byte
; Data i W överförs till LCD som två 4-bitars bitar.
;
        movwf   lcd_tmp2        ; Spara W tillfälligt
        movlw   B'11110000'     ; Mask för bit 4-7
        andwf   lcd_tmp2, w     ; Nolla bit 0-3
        call    lcd_send_4_bit  ; Skicka bit 4-7
        swapf   lcd_tmp2, f     ; Byt plats på 0-3 <-> 4-7
        movlw   B'11110000'     ; Mask för bit 4-7 (nu 0-3 !!)
        andwf   lcd_tmp2, w     ; Nolla bit 0-3 (nu 4-7 !!)
        call    lcd_send_4_bit  ; Skicka bit 4-7 (nu 0-3 !!)
        return
;
lcd_send_text
; Sänd en fast text till LCD.
; När rutinen anropas ska EEADR och EEADRH vara initierade
; med adressen i flash till text-bufferten. T.ex genom det
; lcd_text macro som finns i detta program.
; Beräkningen av rad/kol -> LCD-pos är just nu anpassad
; till 16x2 LCD'er. Får justeras för att passa andra...
;
; Läs första positionen i texten ("LCD-rad")
;
        call read_flash
        movwf   lcd_tmp1        ; Lagra (radnummer på LCD)
;
; Hämta nästa pos i textraden (pos på LCD raden...)
;
        call    inc_eeadr
        call    read_flash
        movwf   lcd_tmp2        ; Lagra (position på raden på LCD)
;
; Justering av rad/pos väden
;
        decf    lcd_tmp1, f     ; Rad 1-2 => 0-1
        bcf     status, c
        rrf     lcd_tmp1, f
        rrf     lcd_tmp1, f
        rrf     lcd_tmp1, f     ; Nu är lcd_tmp1 h'00' eller h'40'...
        decf    lcd_tmp2, f     ; Pos 1-40 => 0-39
;
; Nu är rad och pos färdiga att addera ihop och skicka till LCD'n...
;
        movlw   h'80'           ; Bas-kommandot för LCD-position.
        addwf   lcd_tmp1, w     ; Lägg till rad (h'00' eller h'40')
        addwf   lcd_tmp2, w     ; Lägg till pos.
        call    lcd_send_cmd    ; Skicka kommandot (i W-reg)
;
; Nu läser vi resten av texten fram till h'00' och skickar
; till LCD'n.
;
send_text_loop
;
; Läs nästa position ("LCD-text") och skicka.
; Avsluta om datat/tecknet = h'00'
;
        call    inc_eeadr
        call    read_flash
        btfsc   status, z       ; Var det h'00' (slut på text) ?
        goto    send_text_end   ; Ja, avsluta.
                                ; Nej, fortsätt...      
        call    lcd_send_data   ; Skicka tecken med data i W-reg.
        goto    send_text_loop  ; Om igen...
;
send_text_end
; Slut på text...
;
        return
;
read_flash
;
; Läs en byte från flash
; EEADR och EEADRH ska redan vara initierade.
;
        banksel eecon1
        bsf     eecon1, eepgd   ; Läs från flash...
        bsf     eecon1, rd      ; Sätt läs-flaggan...
        nop                     ; Vänta på att läsning
        nop                     ; ska gå klart... 
        banksel eedat
        movf    eedat, w        ; Nu har vi värdet i W-reg.
        return
;
; Räkna fram eeadr/eeadrh till nästa position
;
inc_eeadr
        banksel eeadr
        incf    eeadrh, f       ; öka först eeadrh
        incfsz  eeadr, f        ; öka eeadr, = 0 ?
        decf    eeadrh, f       ; eeadr <> 0, återställ eeadrh...
        return
;
;        
;**********************************************************************
; Diverse delay rutiner.
; Alla delay rutiner generade med kodgeneratorn här :
; http://www.piclist.com/techref/piclist/codegen/delay.htm
; OBS generatade för 4 Mhz processorhastighet. 
;
DLY_VAR      UDATA_SHR
d1           RES 1
d2           RES 1
d3           RES 1
;
DLY_CODE        CODE
;----------------------------------------------------
; Delay = 0.001 seconds
; Clock frequency = 4 MHz
; korrekt
; Actual delay = 0.001 seconds = 10000 cycles
; Error = 0 %
;----------------------------------------------------
Delay_1ms
			;993 cycles
	movlw	0xC6
	movwf	d1
	movlw	0x01
	movwf	d2
Delay_1ms_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	Delay_1ms_0

			;3 cycles
	goto	$+1
	nop

			;4 cycles (including call)
	return

;----------------------------------------------------
; Delay = 1 sekund
; Clock frequency = 4 MHz
; korrekt
; Actual delay = 1 seconds = 1000000 cycles
; Error = 0 %
;----------------------------------------------------
delay_1s
	 	movlw 0x08
	 	movwf d1
	 	movlw 0x2F
	 	movwf d2
 		movlw 0x03
	 	movwf d3
Delay_1s_0
	 	decfsz d1, f
	 	goto $+2
	 	decfsz d2, f
 		goto $+2
	 	decfsz d3, f
 		goto Delay_1s_0
	 	goto $+1
 		nop
	return
;----------------------------------------------------
; Delay 5 millesekunder
; Delay = 0.005 seconds
; Clock frequency = 4 MHz
; korrekt
; Actual delay = 0.005 seconds = 500000 cycles
; Error = 0 %
;----------------------------------------------------
delay_5ms
       	movlw 0xE7
     	movwf d1
     	movlw 0x04
     	movwf d2
Delay_5ms_0
     	decfsz d1, f
     	goto $+2
     	decfsz d2, f
     	goto Delay_5ms_0
    	goto $+1
	return
;-------------------------------------------------
; Delay 100 mikrosekunder
; Delay = 0.0001 seconds
; Clock frequency = 4 MHz
; korrekt
; Actual delay = 0.0001 seconds = 100 cycles
; Error = 0 %
;-------------------------------------------------
delay_100us
     	movlw 0x21
     	movwf d1
Delay_100us_0
     	decfsz d1, f
     	goto Delay_100us_0
	return

;--------------------------------------------------
; Delay 40 millisekunder
; Delay = 0.04 seconds
; Clock frequency = 4 MHz
; korrekt
; Actual delay = 0.04 seconds = 40000 cycles
; Error = 0 %
;-------------------------------------------------
Delay_40ms
			;39993 cycles
		movlw	0x3E
		movwf	d1
		movlw	0x20
		movwf	d2
Delay_40ms_0
		decfsz	d1, f
		goto	$+2
		decfsz	d2, f
		goto	Delay_40ms_0

				;3 cycles
		goto	$+1
		nop

			;4 cycles (including call)
	return
;--------------------------------------------------
BIN2BCD	
;		Rutin för att göra om från binärt till tre bitar
;		med hundratal, tiotal och ental.	

;---------------------
;in: BIN
;out huns. tens, ones
;uses ADD-3 algoerthm

	movlw 8
	movwf count
	clrf huns
	clrf tens
	clrf ones

BCDADD3

	movlw 5
	subwf huns, 0
	btfsc STATUS, C
	CALL ADD3HUNS
	
	movlw 5
	subwf tens, 0
	btfsc STATUS, C
	CALL ADD3TENS
	
	movlw 5
	subwf ones, 0
	btfsc STATUS, C
	CALL ADD3ONES
	
	decf count, 1
	bcf STATUS, C
	rlf BIN, 1
	rlf ones, 1
	btfsc ones,4 ; 
	CALL CARRYONES
	rlf tens, 1
	
	btfsc tens,4 ; 
	CALL CARRYTENS
	rlf huns,1
	bcf STATUS, C
	
	movf count, 0
	btfss STATUS, Z
	GOTO BCDADD3
	
	
	movf huns, 0 ; add ASCII Offset
	addlw h'30'
	movwf huns
	
	movf tens, 0 ; add ASCII Offset
	addlw h'30'
	movwf tens
	
	movf ones, 0 ; add ASCII Offset
	addlw h'30'
	movwf ones

	RETURN

ADD3HUNS
	
	movlw 3
	addwf huns,1

	RETURN

ADD3TENS
	
	movlw 3
	addwf tens,1

	RETURN

ADD3ONES
	
	movlw 3
	addwf ones,1

	RETURN

CARRYONES
	bcf ones, 4
	bsf STATUS, C
	RETURN

CARRYTENS
	bcf tens, 4
	bsf STATUS, C
	RETURN
;**********************************************************************
LCD_texts   CODE
; Fasta texter för LCDn.
; Två första värderna i varje text är rad (1,2,3 eller 4)
; och position (1-40). Resten är text fram till h'00'. 
;
lcd_text1   data    d'1', d'1', ' ',' ',' ','%',' ',' ',' ',' ',' ', h'00'
lcd_text2   data    d'1', d'10', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', ' ', h'00'


;*********************************************************************
    end
Så, har ni några förslag?

Re: PIC -> PIC via RS232 nya frågor..

Postat: 11 mars 2012, 21:00:54
av sodjan
Uppenbart har du något fel i din konvertering mellan det mottagna och det presenterade.

Gör ett litet test-program där du i princip enbart har din konverteringsrutin som du kan
köra med fasta/hårdkodade värden. Sen så kör du detta i MPLAB/SIM och studerar
vad som händer. Sannolikt händer inte det du tror. Jag har inte kollat koden, det
finns ingen större anledning innan du har felsökt lite själv med hjälp av
tillgängliga verktyg och ändå kört fast.

Jag menar, har du ens verifierat att USART'en i din mottagnade PIC över huvudtaget
levererar samma tecken ut som du sänder från den första PIC'en?
Eller har du enbart "verifierat" via det som visas på LCD'n?
Det saknas generellt information om vilken felsökning du redan har gjort.
De delar som är verifierade behöver vi ju inte kolla en gång till på, eller i
alla fall inte börja att kolla på. :-)

> ; Skapad av: Morgan

Inte för att det har någon jättestor betydelse, men en stor del av koden är "skapad" av mig.

Re: PIC -> PIC via RS232 nya frågor..

Postat: 11 mars 2012, 21:10:34
av Variosboy
Vad det gäller koden så här du såklart helt rätt i att det mesta är ditt verk! Och det skriver jag ju i ett av mina inlägg i tråden. :-) Varför jag valt att skriva mitt namn nu är att jag ändrat en del, och jag vill givetvis inte att någon annan ska få skit för mina fel!

Utskriftsrutinen och omvandlingen av en byte till tre byte med vardera hundra, tio och ental fungerar perfekt. Har, som syns i koden, testat med fasta värden i den variabel som normalt skrivs till efter mottagning, och då blir utskriften rätt.

Re: PIC -> PIC via RS232 nya frågor..

Postat: 11 mars 2012, 23:52:11
av sodjan
Va bra ! :-)
Då kan vi alltså vara ganska säkra på att konverteringen och visningen på
LCD'n fungerar OK, bara de har korrekta invärden att jobba med, så att säga.

Har du på något sätt verifierat vad som kommer från USART'en i PIC nr 2?

Du kan t.ex loopa det du mottar till sänd-delen på PIC nr 2 och skicka det
till samma terminalfönster där du verifierade att PIC nr 1 sänder korrekt.

Om jag inte minns fel så har 16F628A resp 16F690 USART av olika "generation".
AUSART resp EUSART med en del skillnader. Jag är inte säker på att man kan
plocka init koden rakt av mellan dom, därmed inte sagt att du har gjort det,
så klart, bara en notering... :-)

Det "luktar" baud-rate fel...

Re: PIC -> PIC via RS232 nya frågor..

Postat: 12 mars 2012, 07:47:53
av Variosboy
Det där får jag ju helt klart testa. Att jag inte tänkte på det!! Att loopa det som kommer in alltså.
Då serj ag ju rätt snart vad som kommer in -förhoppningsvis-.

En annan fråga när det gäller terminalprogram i allmänhet, om det nu går att fråga allmänt om det..

Första gången jag testade programmet i 16F628A:an så var det inställt för 9600 baud och detsamma var porten inställd på i enhetshanteraren. Så långt allt bra, men så ändrade jag baudrate i sändaren för att det skulle passa med inställningen som var i de trådlösa modulerna, vilket är 19200 baud.

För att det då skulle fungera i PC:n så ändrade jag i terminalprogrammet till 19200 baud, och då fungerade mottagningen som det var tänkt. Men kollar jag i enhetshanteraren så spelar det ingen roll om jag sätter 9600 eller 19200 baud där. Det blir rätt i terminalprogrammet i alla fall..

Så frågan är, överrider inställningen i terminalprogrammet de inställningar som är gjorda i enhetshanteraren, eller hur fungerar det generellt?