

Here is some code to allow you to use a serial terminal to read and write to the PIC's registers and EEPROM.
Please sign my guestbook if you find this page useful. Please sign my guest book
; SERIAL PORT CONTROL: ; ; PORT A0 is Serial input ; PORT A0 is serial output ; ; usb gmus-03 USB Serial Adapter ; ; TX D9 Pin 3 -[4k7]----+-----PA0 ; RX D9 Pin 2 ----------/ ; ; GND D9 Pin 5 ---------------- 0VSome Commands: - you can add more if you wish
; File Registers ;wAADD; write DD to register AA ; rAA; read AA and output to serial port ; ; EEPROM ; pAADD; write DD to EEPROM register AA ; gAA; read EEPROM register AA and output to serial port ; ; ; The ; executes the command. ; There needs to be a delay between each character sent to allow the PIC to process the commands. ; Do not use spaces and the command letter must be in column1 ;
The PIC buffers the characters, and uses the last buffered characters. The buffer length is checked
Connect the 4800 baud serial terminal using the circuit below:-

The PIC serial routines are simplex so you might as well use the same pin for TX and RX.
I have found that a PIC will output a voltage that my PC seems happy with, without the need to resort to an MAXIM rs 232 chip.
When the PIC wants to send a character to the terminal, it makes RA0 an output and sends the character. It then makes the pin an input and the main loop polls for a start bit.
You can configure the PWM module with the f; command


Run the code below into a PC 16F628 chip:
Updated 31/01/2007
:020000000628D0 :0800080009001929DF20F22094 :1000100009281A20121828200C08031909280C187E :10002000222009280D088E0005088D000D090E05F7 :100030008F040800100891000508900011091005B0 :10004000920408000C1017086F2008000F13080016 :10005000121030280B1D08000B110C141220080080 :10006000632061200830950005080139FF3E970C98 :100070006320950B342897090C1408000F39063EAD :100080008318073E2A3E98004528940094090510DD :1000900083160510831205106320051463200830B1 :1000A0009500940C03080139003E050601398506C8 :1000B0006320950B512805106320831605148312C5 :1000C00008001D306528000040309600960B662819 :1000D000640008009700171E093E0F3908009700BA :1000E000F33E031D76281A3099000800D23E031D06 :1000F0007A2888281908840017088000990F1908A1 :10010000E03E031DDE281A3099000D30452008001E :100110001A3099001B081B1E093E0F399700970ED5 :100120001C081C1E093E0F391707A0001D081D1EC4 :10013000093E0F399700970E1E081E1E093E0F3903 :100140001707A10089301A07031DAD282008840075 :10015000210880002A304520DA2890301A07031D34 :10016000BB282008052183122108082121088000CE :100170002A304520DA288E301A07031DCA282008A5 :100180008400000897003D304520170E3E201708D8 :100190003E20DA2899301A07031DD2282008FF20B4 :1001A0009700C3289A301A07031DDA2818212A302D :1001B0004520DA280D3045200A304520080000305F :1001C0008B0085018316F0308600051483121A30E7 :1001D0009900640083160230810083128C018F0124 :1001E000920108000D3045200A304520533045204B :1001F000523045200D3045200A304520080083123A :100200008900081408088312080083128900080076 :10021000831288008B130812081555308900AA3004 :1002200089008814081188181229081283120800FE :0402300008000900B9 :084000000000000008000400AC :02400E00F13F80 :044200006400320024 :00000001FF


;**************************************************************************
; SR001.ASM
;
; PROGRAM: Simple Serial Project
;
; DESCRIPTION:
; simple serial project that receives serial commands
; spaces are important
;
; File Regiters
; <CR>wAADD; write DD to register AA
; <CR>rAA; read AA and output to serial port
;
; EEPROM
; <CR>pAADD; write DD to EEPROM register AA
; <CR>gAA; read EEPROM register AA and output to serial port
;
; PRIPHERALS
; <CR>f; init PWM
; ; sets up PWM module
; W92FF; - PR2 - set PWM period max
; W1532; - CCPR1L - Duty Cycle / ON period
; W8600; - TRISB - All Outputs
; W1204; - T2CON - Set up Tmr 2
; W173C; - CCP1CON - Set up as PWM module.
; W9265; - PR2 - set PWM period for 10Khz if 4Mhz crystal.
;
;
; SERIAL PORT CONTROL:
;
; PORT A0 is Serial input
; PORT A0 is serial output
;
; usb gmus-03 USB Serial Adapter
;
; TX D9 Pin 3 -[4k7]----+-----PA0
; RX D9 Pin 2 ----------/
;
; GND D9 Pin 5 ---------------- 0V
;
; AUTHOR: Douglas Rice
; Copyright 2004
;
; Crystal: 4MHz
;
; I/O used:-
;
; ; Port B is used for the LCD
;
;
;**************************************************************************
;#define pic16F84 1
#define pic16F628 1
ifdef pic16F84
INCLUDE "p16F84.inc"
LIST P=16F84, R=DEC
__idlocs 0x0084
__config _XT_OSC&_PWRTE_ON & _WDT_OFF
cblock 0x0c
endc
endif
ifdef pic16F628
INCLUDE "p16F628.inc"
LIST P=16F628, R=DEC
__idlocs 0x0628
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _INTRC_OSC_CLKOUT & _MCLRE_OFF & _LVP_OFF
cblock 0x20
endc
endif
;--------------------------------------------------------------------------
; Sec 1. Equates and Constants
;--------------------------------------------------------------------------
; The General Purpose Registers start at the end of the
; Special Purpose Registers.
; IPMentState values
; in normal running or in time setting modes
;
; DoTimeSlice bits
; these bits are set to schedule a timer chain event
DTsS4event EQU 0 ;
RUN_BUFF EQU 0 ;
; IPtrigMenu
DTSFast EQU 0
;--------------------------------------------------------------------------
; Sec 1.1 Button and LED
;--------------------------------------------------------------------------
BUTTON_RS232 EQU 0 ; EDG - Bottom Buttom
BUTTON_DOWN EQU 6 ; EDG - Bottom Buttom
;--------------------------------------------------------------------------
; Sec 2.0 Variables
;--------------------------------------------------------------------------
; Variables start 0x0C
;
; DoTimeSlice Bits, to schedule, set bit
cblock
DoTimeSlice
IPnew
IPlast
IPbuttonEvent
IPnewFast
IPlastFast
IPbuttonEventUp
IPtrigMenu
; variables used by Serial input and output routines
RStxTemp
RSloopCnt
RSdelayCnt
RSin
RSout
; Serial input buffer
RSipBuffCnt ; input buffer counter
; start of buffer
RScmd
RSAa ;
RSaA ;
RSDd ;
RSdD ;
RSterminator
; end of buffer
; temporary variables
RSaddr
RSdata
;
ENDC
; *********** I/O EQUATES **************
PORTA EQU 5 ; 5 BITS
PA0 EQU 0 ; Serial Out
PA1 EQU 1 ; Serial In
PORTB EQU 6
RS232tx EQU PA0 ; Serial Out
RS232rx EQU PA0 ; Serial In needs to be equal to BUTTON_RS232
;--------------------------------------------------------------------------
; Sec 3. MACROS
;--------------------------------------------------------------------------
TEST_STRADDLE MACRO START
if high( $ ) != high( START )
Error "Table straddles Page Boundary " + Start
endif
endm
;--------------------------------------------------------------------------
; Sec 4. Program Code
;--------------------------------------------------------------------------
ORG 0
GOTO Start
ORG 4
RETFIE
GOTO Intrtn
;--------------------------------------------------------------------------
; Sec 4.1 Main Program Init Code
;--------------------------------------------------------------------------
Start
CALL INinit
CALL INsayHello
GOTO MainLoop
;--------------------------------------------------------------------------
; Sec 4.2 Main Program
;--------------------------------------------------------------------------
MainLoop
CALL IPtimesliceFast
; test for rising edge
BTFSC IPbuttonEventUp,BUTTON_RS232 ; RS232 input start
CALL IPrs232
MOVF DoTimeSlice,w
Bz MainLoop
BTFSC DoTimeSlice,RUN_BUFF
CALL DLrunBuff
GOTO MainLoop
;--------------------------------------------------------------------------
; Sec 5. Subroutines, procedures and functions
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; Sec 5.1 Button Poll Routine
;--------------------------------------------------------------------------
IPtimeslice
; --_____ button press
; ----___
; __----- /IPnew
; ----___ IPlast
; __--___
;
;
;
; This reads all Port A inputs and looks for Press
MOVFW IPnew
MOVWF IPlast
MOVFW PORTA
MOVWF IPnew
; IP last contains new setting, IPlast contains previous
; look for falling edges
COMF IPnew,W
ANDWF IPlast,W
; now force IPbuttonEvent bits to high for new pressed button
; the service routine should reset the bit to clear the event.
IORWF IPbuttonEvent,F
RETURN
IPtimesliceFast
; Look for rising edges
MOVFW IPnewFast
MOVWF IPlastFast
MOVFW PORTA
MOVWF IPnewFast
COMF IPlastFast,W
ANDWF IPnewFast,W
IORWF IPbuttonEventUp,F
RETURN
;--------------------------------------------------------------------------
; Sec 5.2
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; Sec 5.2 .1 run process on request
;--------------------------------------------------------------------------
DLrunBuff
BCF DoTimeSlice,RUN_BUFF
MOVFW RSin
CALL RSbuffInput
return
;--------------------------------------------------------------------------
; Sec 5.3 Button Input functions
;--------------------------------------------------------------------------
IPdownPressed
BCF IPbuttonEvent,BUTTON_DOWN
return
IPrs232
BCF IPbuttonEventUp,BUTTON_RS232
GOTO RSrs232in
;--------------------------------------------------------------------------
; Sec 5.4 Clock Chain Routine
;--------------------------------------------------------------------------
CLtimeslice
;
BTFSS INTCON,T0IF
RETURN
; TMR0 timeout
BCF INTCON,T0IF
BSF DoTimeSlice,DTsS4event
CALL IPtimeslice
RETURN
;--------------------------------------------------------------------------
; Sec 5.5 Serial Input Routine
;--------------------------------------------------------------------------
;**************************************************
RSrs232in
; Test is in main loop or uncomment code below to
; spin for a start bit
; CLRWDT
; BTFSS PORTA,RS232rx
; GOTO RSrs232in
CALL RSdelayBit ; delay through Stop Bit
CALL RSdelayHalfBit ; delay halfway into first bit
movlw 8
movwf RSloopCnt
RSrs232inL0
MOVFW PORTA
ANDLW 1<< RS232rx ; mask off bit
ADDLW -1<< RS232rx ; use ripple carry to move into C
RRF RSin,F
CALL RSdelayBit
DECFSZ RSloopCnt,f
goto RSrs232inL0
; test for Stop bit
COMF RSin,f
BSF DoTimeSlice,RUN_BUFF
RETURN
;--------------------------------------------------------------------------
; Sec 5.6 Serial Output Routines
;--------------------------------------------------------------------------
RSwrtHexNibble ; currently only displays 0..9, A..F
ANDLW 0x0F
ADDLW 0x06 ; is it A..F, if so trigger a digit overflow
SKPNDC
ADDLW 7; subtract 10, then add 'A'-'0'
ADDLW 0x30-6 ; Subtract extra 6 added to cause DC
MOVWF RSout
GOTO RStxChar
RStxChar
;
; Output Start Bit
; Start bit is low, data bits are inverted
;
movwf RStxTemp
comf RStxTemp,f
BCF PORTA,RS232tx
MOVLW ~( 1 << RS232tx )
; Make RS232 pin an ouput while transmitting character
BSF STATUS, RP0
MOVWF TRISA
BCF STATUS, RP0
; 4800 baud output
; move the char into RStxtemp, it is destroyed.
; ADDED 31/01/2007
; zzz_-xxxxxxxx__
;
; Do one more stop bit for luck
;
; This was needed on my XP machine
; but has not been needed before.
;
;
BCF PORT_RS232,RS232tx
call RSdelayBit
; END of code ADDED 31/01/2007
;
; move the char into RStxtemp, it is destroyed.
;Start Bit
BSF PORTA,RS232tx
call RSdelayBit
movlw 8
movwf RSloopCnt
RStxCharLp1
; After start bit, which is 1, then test each bit
; I need to set PA:0 to same as LSB RStxTemp
; this compares PA:0 with RStxTemp so see if it needs toggling
; The xorwf PORTA,f causes the bit to be toggled if required.
RRF RStxTemp,f
movfw STATUS
andlw 1 << C ; mask off bit
addlw ( 1 << RS232tx) -1 ; shift bit by using a ripple carry
xorwf PORTA,W ; Doeas output need toggling ?
andlw 1 << RS232tx ; Mask off output pin
xorwf PORTA,f ; Toggle output pin if needed
call RSdelayBit ; delay bit
decfsz RSloopCnt
goto RStxCharLp1
; apply stop bit
BCF PORTA,RS232tx
call RSdelayBit
call RSdelayBit
; Make RS232 pin an input so that main loop can test for start bit
BSF STATUS, RP0
BSF TRISA, RS232tx
BCF STATUS, RP0
RETURN
; timing functions to delay serial routines for a bit or half bit.
RSdelayHalfBit
MOVLW 0x1D ; shorten delay as edge detector takes about 22 us for 4800 baud
GOTO RSdelayBit0
RSdelayBit
NOP
MOVLW 0x40 ; for 4800 baud
RSdelayBit0
MOVWF RSdelayCnt
RSdelayBit1 DECFSZ RSdelayCnt ; 1
GOTO RSdelayBit1 ; 2 clk
CLRWDT
RETURN
;--------------------------------------------------------------------------
; Sec 5.7 Serial Output Format Routines
;--------------------------------------------------------------------------
RSasciiToNibble
MOVWF RSin
; if 0..1 then 0x30 to 0x39
; if A..F then 0x41 to 0x46
; if a..f then 0x61 to 0x66
; test if bit 4 set and assume a letter or number
BTFSS RSin,4
ADDLW 0x09 ; letter so add 9
ANDLW 0x0F ; mask of nibble
return
;--------------------------------------------------------------------------
; Sec 5.8 Serial Input Buffer Routine
;--------------------------------------------------------------------------
; take serial input CAADD and put into buffer
; if char id ; the do command
; if char is CR reset buffer pointer
; if buff end then reset buff pointer
RSipbuffStart EQU RScmd
RSipbuffEnd EQU RSterminator
RSbuffInput
MOVWF RSin
; look for line feed and reset buff cnt
ADDLW -0x0D
BNZ RSbuffInput1
MOVLW RSipbuffStart
MOVWF RSipBuffCnt
RETURN
RSbuffInput1
; end of line command - do command
ADDLW -';'+0x0D
BNZ RSbuffInput2
GOTO RSbuffInputProcess
RSbuffInput2
; Store the current time into the next register.
MOVFW RSipBuffCnt
MOVWF FSR
MOVFW RSin
MOVWF INDF
INCFSZ RSipBuffCnt,f
MOVFW RSipBuffCnt
ADDLW -(RSipbuffEnd+1)
; Check if the end of memory
SKPZ
GOTO RSbuffInputEnd1
MOVLW RSipbuffStart
MOVWF RSipBuffCnt
; reset cursor
MOVLW 0x0D
CALL RStxChar
RETURN
RSbuffInputProcess
MOVLW RSipbuffStart
MOVWF RSipBuffCnt
MOVFW RSAa
; if 0..1 then 0x30 to 0x39
; if A..F then 0x41 to 0x46
; if a..f then 0x61 to 0x66
; test if bit 4 set and assume a letter or number
BTFSS RSAa,4
ADDLW 0x09 ; letter so add 9
ANDLW 0x0F ; mask of nibble
MOVWF RSin
SWAPF RSin,F
MOVFW RSaA
BTFSS RSaA,4
ADDLW 0x09 ; letter so add 9
ANDLW 0x0F ; mask of nibble
ADDWF RSin,w
MOVWF RSaddr
MOVFW RSDd
BTFSS RSDd,4
ADDLW 0x09 ; letter so add 9
ANDLW 0x0F ; mask of nibble
MOVWF RSin
SWAPF RSin,F
MOVFW RSdD
BTFSS RSdD,4
ADDLW 0x09 ; letter so add 9
ANDLW 0x0F ; mask of nibble
ADDWF RSin,w
MOVWF RSdata
; CALL RStxChar
; got to end of buffer so process. does not allow for backspace
; Write to file register
MOVLW -'w'
ADDWF RScmd,w ; test to see if command is s, if so save into register.
bnz RSbuffInput3
MOVFW RSaddr
MOVWF FSR
MOVFW RSdata
MOVWF INDF
MOVLW '*'
CALL RStxChar
GOTO RSbuffInputEnd
RSbuffInput3
; put octet in EEPROM
MOVLW -'p'
ADDWF RScmd,w ; test to see if command is s, if so save into register.
bnz RSbuffInput4
MOVFW RSaddr
CALL EEsetAddr
BANKSEL RSdata
MOVFW RSdata
CALL EEwrt
MOVFW RSdata
MOVWF INDF
MOVLW '*'
CALL RStxChar
GOTO RSbuffInputEnd
RSbuffInput4
; read from file register
MOVLW -'r'
ADDWF RScmd,w ; test to see if command is s, if so save into register.
bnz RSbuffInput5
MOVFW RSaddr
MOVWF FSR
MOVFW INDF
MOVWF RSin
RSbuffInput4display
MOVLW '='
CALL RStxChar
SWAPF RSin,w
CALL RSwrtHexNibble
MOVFW RSin
CALL RSwrtHexNibble
GOTO RSbuffInputEnd
RSbuffInput5
; get from EEPROM register
MOVLW -'g'
ADDWF RScmd,w ; test to see if command is s, if so save into register.
bnz RSbuffInput6
MOVFW RSaddr
CALL EEread
MOVWF RSin
GOTO RSbuffInput4display
RSbuffInput6
; Initilize PWM
MOVLW -'f'
ADDWF RScmd,w ; test to see if command is s, if so save into register.
bnz RSbuffInput7
CALL PWinit;
MOVLW '*'
CALL RStxChar
GOTO RSbuffInputEnd
RSbuffInput7
RSbuffInputEnd
MOVLW 0x0D
CALL RStxChar
MOVLW 0x0A
CALL RStxChar
RSbuffInputEnd1
return
;--------------------------------------------------------------------------
; Sec 5.9 Initilization code -
;--------------------------------------------------------------------------
INinit
; Enable Interupts
MOVLW H'00'
MOVWF INTCON
CLRF PORTA ;Initialize PORTA by setting
;output data latches
BANKSEL CMCON
MOVLW 0X07 ;Turn comparators off and
MOVWF CMCON ;enable pins for I/O
banksel TRISB
MOVLW 0XF0
MOVWF TRISB
MOVLW ~( 1 << RS232tx ) ; Make PORTA 3:0 INPUTS.
MOVWF TRISA
banksel 0
; reset input buffer
MOVLW RSipbuffStart
MOVWF RSipBuffCnt
; Change Prescaler
CLRWDT
; Configure Tmr 0
BSF STATUS,RP0
; Set up prescaller for 8192 / 16 = 512 ticks perseconds.
MOVLW 0x0 + 2 ; For Tmr0 0=/2, 1=/4, 2=/8,3=/16
MOVWF OPTION_REG
BCF STATUS,RP0
; Configure Tmr 1
MOVLW 0x0 | 1<<TMR1ON | 3 <<T1CKPS0
MOVWF T1CON
CLRF DoTimeSlice
CLRF IPbuttonEvent
CLRF IPbuttonEventUp
INsayHello
; print out power on message
MOVLW 0x0D
CALL RStxChar
MOVLW 0x0A
CALL RStxChar
MOVLW 'S'
CALL RStxChar
MOVLW 'R'
CALL RStxChar
MOVLW 0x0D
CALL RStxChar
MOVLW 0x0A
CALL RStxChar
return
;--------------------------------------------------------------------------
; Sec 5.10 EEprom Routines for 16F628
;--------------------------------------------------------------------------
EEread
; w contains address
banksel EEADR
MOVWF EEADR
BSF EECON1,RD
MOVFW EEDATA
banksel 0
RETURN
EEsetAddr
banksel EEADR
MOVWF EEADR
RETURN
EEwrt ; blocking, EEADR and EEDATA set up.
; BSF STATUS,RP0
banksel EEDATA
MOVWF EEDATA
BCF INTCON,GIE
BCF EECON1,EEIF
BSF EECON1,WREN
MOVLW 0x55
MOVWF EECON2
MOVLW 0xAA
MOVWF EECON2
BSF EECON1,WR
; Now wait for EEwrt to finish write
EEwaitForWrt ; block until EEPROM write has finished.
BCF EECON1,WREN ; disable EROM
;
;NOTE: On some chips, this loop prevents the EEPROM write from working.
; Comment out this loop.
;
BTFSC EECON1,WR
GOTO EEwaitForWrt
BCF EECON1,EEIF ; EEPROM finished
; BCF STATUS,RP0
banksel 0
RETURN
;--------------------------------------------------------------------------
; Sec 5.11 Routines to set up PWM on 16F628
;--------------------------------------------------------------------------
PWinit ; set up the PWM
; Move the PWM period into PR2
MOVLW 0
CALL EEread
BANKSEL PR2
MOVWF PR2
MOVLW 0
MOVWF TRISB
MOVLW 1
CALL EEread
BANKSEL CCPR1L
MOVWF CCPR1L
MOVLW 1 << TMR2ON
MOVWF T2CON
BANKSEL CCP1CON
MOVLW 1<< CCP1X | 1<< CCP1Y | ( .12 << CCP1M0 )
MOVWF CCP1CON
RETURN
;--------------------------------------------------------------------------
; Sec 6.0 Interrupt Routines
;--------------------------------------------------------------------------
Intrtn
; Which Interupt ?
; No Context Save in these routines.
; BTFSC INTCON,2
; GOTO IntTmr0
; BTFSC INTCON,1
; GOTO Intfint
; BTFSC INTCON,0
; GOTO IntRbport
IntTmr0
; BCF INTCON,2
RETFIE
Intfint
; BCF INTCON,1
; RETFIE
IntRbport
; BCF INTCON,0
RETFIE
;--------------------------------------------------------------------------
; Program End
;--------------------------------------------------------------------------
LastProgWord
;--------------------------------------------------------------------------
; Sec 7.0 EEPROM data
;--------------------------------------------------------------------------
ORG 0x2100
; first 2 on and off are general ones
DE .100,.50 ; 4
cblock
LastVar
endc
END

This is one of my mosted visited pages!