More PIC goodness: reading from serial line


Now that I figured out serial communications, I can start to do more interesting things. One of those things is having the PIC read from the serial line and doing something with the data. I decided I would read in characters '0' through '9', and render them on a 7-segment led display.

This is the code:

#include "p16f627a.inc"

#define ARRAY 0x20 ; allocate a var in free space at location 0x20
__CONFIG _INTOSC_OSC_NOCLKOUT

; a macro to easily load data into memory
putdata: MACRO idx, val
MOVLW val
MOVWF (ARRAY + idx)
ENDM

; 7 segment led display:
; 0
; -----
; | |
; 5 | | 1
; | 6 |
; -----
; | |
; 4 | | 2
; | |
; -----
; 3

; store all 10 digits, starting at address ARRAY
putdata 0, 0x3F ;0011 1111
putdata 1, 0x06 ;0000 0110
putdata 2, 0x5B ;0101 1011
putdata 3, 0x4F ;0100 1111
putdata 4, 0x66 ;0110 0110
putdata 5, 0x6D ;0110 1101
putdata 6, 0x7D ;0111 1101
putdata 7, 0x07 ;0000 0111
putdata 8, 0x7F ;0111 1111
putdata 9, 0x6F ;0110 1111

BSF STATUS, 5 ;
; according to the datasheet, both the 1st and 2nd bit of TRISB need to be set to 1, which makes them both inputs
BSF TRISB, 1 ; set bit 1 on TRISB
BSF TRISB, 2 ; set bit 2 on TRISB
CLRF TRISA ; PORTA is all output
BCF STATUS, 5

; set baudrate to 9600baud. For a 20MHz Fosc, this is value 32 == 0x20
MOVLW 0x20
BSF STATUS, 5
MOVWF SPBRG
BCF STATUS, 5

BSF STATUS, 5
BCF TXSTA, SYNC ; clear SYNC
BCF STATUS, 5
BSF RCSTA, SPEN ; enable serial port
BSF RCSTA, CREN ; set CREN

wait: BTFSS PIR1, RCIF ; wait untill there is some input
GOTO wait

MOVF RCREG, 0 ; read the data byte
ADDLW 0xD0 ; index = data - 0x30 ('0') (ADDLW 0xD0 = DECLW 0x30)
ADDLW ARRAY ; pointer = ARRAY + index
MOVWF FSR ; set the pointer
MOVF INDF,0 ; w = *pointer
MOVWF PORTA ; porta = w -> lights up the 7seg leds

GOTO wait

END


compile with

gpasm -p 16f627a test.asm


And this is the gpsim startup commands file:

# load the gpsim modules library. For some reason I can't just load it from /usr/lib
# so to get this working, I had to issue a 'ln -s /usr/lib/libgpsim_modules.so.0 /tmp/libgpsim_modules.so'
module lib /tmp/libgpsim_modules.so

# creating an usart and connecting its TX pin to the PICs RX pin, allowing keyboard input
module load usart U1
node nc
attach nc pin(portb1) U1.TXPIN
U1.console = true

# creating a 7 segment led display and hooking it up to PORTA
module load led_7segments L7
node nl0 nl1 nl2 nl3 nl4 nl5 nl6
attach nl0 pin(porta0) L7.seg0
attach nl1 pin(porta1) L7.seg1
attach nl2 pin(porta2) L7.seg2
attach nl3 pin(porta3) L7.seg3
attach nl4 pin(porta4) L7.seg4
attach nl5 pin(porta5) L7.seg5
attach nl6 pin(porta6) L7.seg6

# tell the builtin scope in gpsim to monitor portb2
# (in gpsim: Windows -> Scope)
#scope.ch0="portb1"


Start gpsim with this command:

gpsim -c env.conf -s test.cod