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?