Control a PIC 16F628 using a serial 4800 baud terminal

Here is some code to allow you to use a serial terminal to read and write to the PIC's registers and EEPROM.

Examples of this being used

Example used to explore IIC on PIC16F819 ( rs232 @ 4800 on PA3 )
Solar light logger experiment ( rs232 @ 4800 on PA0 )
A Demo of an LCD Epson EA-X24017AR modules based on a SED1300 controller ( rs232 @ 4800 on PA0 )

Please sign my guestbook if you find this page useful. Please sign my guest book


Introduction

Connect the 4800 baud serial terminal using the circuit below:-

 ; 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
 
 
Some 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.

Run the code below into a PC 16F628 chip: The PIC serial routines are simplex so you might as well use the same pin for TX and RX.

On 29/09/2008, it was found that the performance of a PIC16F88 or 16F675's AtoD is much worse if the RS232 is connected to PA0. The voltage on PA0 is pulled down to -0.65 volts when there is a space on the TX pin and this makes the AtoD converter very sensitive to series resistence on the ANx pins e.g. AN4,AN5,AN6

I have found this circuit really enjoyable to use to experiment with PIC chips. You can add functionality and explore it with ease. I have used it on a number of projects now.

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
 

Code

Pic Pinouts ( bitmaps )

;**************************************************************************
 ; 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!