ON 20030308@10:52:15 PM at page: http://www.piclist.commicrochip/pocketprog.htm JMN-EFP-786 James Newton Published and replied to post 37687.5263078704 |Insert 'Find a simular chip in the chip data file and make a new entry?' at: '' I have the thing together and it works great. However, I notice that 16F627 is not included in the device list. Any ideas? |Delete 'P-' before: '' but after: 'naresh_dd@yahoo.co.in asks:
i am new in PIC world ,i heard about resource CD for PICs, so please let me know about resources available on net,from where' ON 20030315@8:39:52 AM at page: http://www.piclist.commicrochip/pocketprog.htm JMN-EFP-786 James Newton published post 37692.263900463 rmorejr@yahoo.com asks:
i can start, all kind of suggestions are wel comed
thanks, ;)
Does anyone have a working chipdat segment for the 16F627 or 16F628? I tried to write one but am having trouble getting the fuse configuration to program properly. Any help would be appreciated. Thanks in advance.|Delete 'P-' before: '' but after: ' http://www.asm51.eng.br/forum ' ON 20030316@7:07:58 PM at page: http://techref.massmind.org/techref/microchip/ibuttonsearch.htm JMN-EFP-786 James Newton edited the page. Difference: http://techref.massmind.org/techref/diff.asp?url=H:\techref\microchip\ibuttonsearch.htm&version=0 ON 20030316@7:08:14 PM at page: http://techref.massmind.org/techref/microchip/ibuttonsearch.htm JMN-EFP-786 James Newton Code:
;---------------------------------------------------------------------------------------------
; HEADER:
;---------------------------------------------------------------------------------------------
LIST P=16f84a
RADIX DEC
INCLUDE "p16f84a.inc"
__CONFIG _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_ON
;---------------------------------------------------------------------------------------------
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
;---------------------------------------------------------------------------------------------
; This program and the code/routines contained within are Copyright 2001,2003 by michael brown. It may
; not be used for commercial purposes without written consent from the Copyright holder (me). It
; is free for personal use as long as this Copyright message is kept intact. If commercial
; usage is desired, please contact michael brown via e-mail at n5qmg@amsat.org to make licensing
; arrangements. I'm not trying to be a greedy jerk, but I have to eat too. ;-)
;
; 73's de N5QMG
;---------------------------------------------------------------------------------------------
#define Clock_Freq 4000000
#include "wait.mac"
;---------------------------------------------------------------------------------------------
; EQUATES:
;---------------------------------------------------------------------------------------------
RS equ 0 ;LCD's pin 4 should be connected to PORTB.0
RW equ 1 ;LCD's pin 5 should be connected to PORTB.1
EN equ 2 ;LCD's pin 6 should be connected to PORTB.2
#define LCD_PORT PORTB ;LCD_PORT implies use of bits 4-7 for data lines to LCD
#define LCD_RS LCD_PORT, RS
#define LCD_RW LCD_PORT, RW
#define LCD_EN LCD_PORT, EN
#define LCD_DAT7 LCD_PORT, 7
#define LCD_DAT6 LCD_PORT, 6
#define LCD_DAT5 LCD_PORT, 5
#define LCD_DAT4 LCD_PORT, 4
#define YEL_LED PORTA, 0
#define RED_LED PORTA, 1
#define INTSCOPE PORTA, 2
#define MAIN_SCOPE PORTA, 3
#define ONE_WIRE PORTA, 4 ;Dallas 1-wire bus
MAX_DEVICES equ 4 ;Maximum number of 1-wire devices to find
STARTOFRAM equ 0x0C ;First Usable RAM Location for 16f84
ENDOFRAM equ 0x4F ;Last Usable RAM Location for 16f84
;
; General Purpose Temp Storage
;
cblock STARTOFRAM
OneWireByte
SOURCE
DEST
TEMP0
TEMP1
TEMP2
tempone
temptwo
;
; ISR Register Save Areas
;
;INT_FLAGS
;W_TEMP
;STATUS_TEMP
;FSR_TEMP
;
; ISR Loop Control
;
;LoopCntH
;LoopCntL
;
; Variables Relating to LCD Control
;
CursorRow ; Current Cursor Position
CursorCol
AbsAddr ; Absolute cursor position (start address of CursorRow + CursorCol)
SrcRowNum ; Source Row Number
DestRowNum ; Destination Row Number
SrcCharAddr ; DDRAM address in LCD
DestCharAddr ; DDRAM address in LCD
RowLoopCtr ; For Scrolling the screen
CharLoopCtr ; Same as above
LCD_Data
TEMPX
;
; Work areas
;
rombit_idx
bits
ctr_1wire
curr_discrep
last_discrep
done_flag
return_value
; One-Wire work area
work0 ; CRC (8 bits)
work1 ; Serial # (48 bits)
work2 ; "
work3 ; "
work4 ; "
work5 ; "
work6 ; "
work7 ; Family Code (8 bits)
;Sensor 0 Storage
ts00
ts01
ts02
ts03
ts04
ts05
ts06
ts07
;Sensor 1 Storage
ts10
ts11
ts12
ts13
ts14
ts15
ts16
ts17
;Sensor 2 Storage
ts20
ts21
ts22
ts23
ts24
ts25
ts26
ts27
;Sensor 3 Storage
ts30
ts31
ts32
ts33
ts34
ts35
ts36
ts37
endc
;---------------------------------------------------------------------------------------------
; START:
;---------------------------------------------------------------------------------------------
org 0x000
goto Start
org 0x004
; movwf W_TEMP ;Save everything
; swapf STATUS, W
; movwf STATUS_TEMP
; movfw FSR
; movwf FSR_TEMP
;
; Interrupt handler right here
;
; bsf INTSCOPE ;Mark start of interrupt routine
; bcf INTSCOPE ;Mark end of interrupt routine (for timing)
;
; Restore everything and return
;
;IntExit
; movfw FSR_TEMP
; movwf FSR
; swapf STATUS_TEMP, W
; movwf STATUS
; swapf W_TEMP, F
; swapf W_TEMP, W
retfie
;-------------------------------------------------------------
;Store_Bit -- take bit A (bits.1) and store into work0..work7
; at bit offset rombit_idx (1 relative)
; Entry:
; bits - contains 2 bits read from 1 wire bus bits.1 is the one to store
; rombit_idx - contains one relative bit offset from rom work area (work0..work7)
; of bit to store
; Exit:
; bits.1 -> work0..work7(rombit_idx)
;-------------------------------------------------------------
Store_Bit
call SetupFSR ;convert rombit_idx to something we can use
;Determine if we need to set a bit (1) or clear a bit (0)
movlw HIGH SetWorkBit
movwf PCLATH
rrf bits, W ;get bit.1 value right justified into W
andlw b'00000001' ;maintain sanity
addwf PCL, F ;quick test for 0 or 1
goto ClrWorkBit ;must be 0 (clr bit)
SetWorkBit ;must be 1 (set bit)
clrc
rlf TEMP2, W ;get bit position * 2 (0, 2, 4 .. 14)
addwf PCL, F ;bump PC, turn bit on then return
bsf INDF, 7
return
bsf INDF, 6
return
bsf INDF, 5
return
bsf INDF, 4
return
bsf INDF, 3
return
bsf INDF, 2
return
bsf INDF, 1
return
bsf INDF, 0
return
ClrWorkBit
movlw HIGH ClrWorkBit
movwf PCLATH
clrc
rlf TEMP2, W ;get bit position * 2 (0, 2, 4 .. 14)
addwf PCL, F ;bump PC and turn it off then return
bcf INDF, 7
return
bcf INDF, 6
return
bcf INDF, 5
return
bcf INDF, 4
return
bcf INDF, 3
return
bcf INDF, 2
return
bcf INDF, 1
return
bcf INDF, 0
return
;-------------------------------------------------------------
;GetWorkBit --
; at bit offset rombit_idx (1 relative)
; Entry:
; rombit_idx - contains one relative bit offset from rom work area (work0..work7)
; of bit to retrieve value of
; Exit:
; work0..work7(rombit_idx) -> W
;--------------------------------------------------------------
GetWorkBit
call SetupFSR ;point to the bit in question
movlw HIGH GetWorkBit
movwf PCLATH
clrc
rlf TEMP2, W ;get bit position * 2 into w
addwf TEMP2, W ;compute w = bit offset * 3 (0, 3, 6 ...)
addwf PCL, F ;bump PC to jump to appropriate test
;Bit 0
btfss INDF, 7 ;Is bit set(1)
retlw d'0' ; No, return 0
retlw d'1' ; Yes, return 1
;Bit 1
btfss INDF, 6 ;Is bit set(1)
retlw d'0' ; No, return 0
retlw d'1' ; Yes, return 1
;Bit 2
btfss INDF, 5 ;Is bit set(1)
retlw d'0' ; No, return 0
retlw d'1' ; Yes, return 1
;Bit 3
btfss INDF, 4 ;Is bit set(1)
retlw d'0' ; No, return 0
retlw d'1' ; Yes, return 1
;Bit 4
btfss INDF, 3 ;Is bit set(1)
retlw d'0' ; No, return 0
retlw d'1' ; Yes, return 1
;Bit 5
btfss INDF, 2 ;Is bit set(1)
retlw d'0' ; No, return 0
retlw d'1' ; Yes, return 1
;Bit 6
btfss INDF, 1 ;Is bit set(1)
retlw d'0' ; No, return 0
retlw d'1' ; Yes, return 1
;Bit 7
btfss INDF, 0 ;Is bit set(1)
retlw d'0' ; No, return 0
retlw d'1' ; Yes, return 1
;---------------------------------------------------------------------
;Lookup_TS -- Return address of start of 8 byte entry within TS table
; Entry:
; W contains slot number within TS table (0,1,2, or 3)
; Exit:
; W contains address of beginning of slot pointed to by W
;---------------------------------------------------------------------
Lookup_TS
andlw b'00000011'
addwf PCL, F
retlw ts00
retlw ts10
retlw ts20
retlw ts30
;---------------------------------------------------------------------------------------------
;
; lookup_row - Lookup ddram address of beginning of row for LCD
;
;---------------------------------------------------------------------------------------------
lookup_row addwf PCL, F ; bump PC by zero relative row number
retlw 0x00 ; start of row 0
retlw 0x40 ; row 1
retlw 0x14 ; row 2
retlw 0x54 ; row 3
;----------------------------------------------------------------------------------------
; SetupFSR -- Point FSR at byte within work area determined by rombit_idx
; Entry:
; rombit_idx contians bit number (one relative) we need to get to
; Exit:
; FSR - pointing at byte within work0..work7
; TEMP1 - zero relative byte offset (0,1,..7)
; TEMP2 - zero relative(0,1,..7) bit offset within byte
;----------------------------------------------------------------------------------------
SetupFSR ;Setup FSR, TEMP1(byte offset), and TEMP2(bit offset)
decf rombit_idx, W ;convert index to 0 relative
sublw d'63' ;form compliment of rombit_idw 0-63->63-0
movwf TEMP1 ; and temp byte offset area
andlw b'00000111' ;strip off byte offset leaving bit offset only
movwf TEMP2 ; and save into temp bit offset area
clrc ;right justify the byte offset in TEMP1
rrf TEMP1, F ; by right shifting
clrc ; and stripping 3 LSB's
rrf TEMP1, F
clrc
rrf TEMP1, F
;Get FSR pointing at appropriate byte in work area (work0, work1 ...)
movlw work0 ;Point FSR at beginning of work area
movwf FSR
movfw TEMP1 ;get byte offset (0 relative)
addwf FSR, F ; point FSR straight at it
return
;---------------------------------------------------------------------------------------------
;
; Main level code begins here
;
;---------------------------------------------------------------------------------------------
Start
bsf STATUS, RP0 ;Switch to Bank 1
movlw b'00000000' ;Define I/O on Port B (all outputs)
movwf TRISB & 0x07F
movlw b'00000' ;Define I/O on Port A (all outputs)
movwf TRISA & 0x07F
bcf STATUS, RP0 ;Back to Bank 0
clrf PORTA
clrf PORTB
Main
; Waste a couple of seconds between itterations
Wait 100 Millisecs, 0
Wait 100 Millisecs, 0
Wait 100 Millisecs, 0
Wait 100 Millisecs, 0
Wait 100 Millisecs, 0
Wait 100 Millisecs, 0
Wait 100 Millisecs, 0
Wait 100 Millisecs, 0
Wait 100 Millisecs, 0
Wait 100 Millisecs, 0
Wait 100 Millisecs, 0
Wait 100 Millisecs, 0
Wait 100 Millisecs, 0
Wait 100 Millisecs, 0
Wait 100 Millisecs, 0
Wait 100 Millisecs, 0
Wait 100 Millisecs, 0
Wait 100 Millisecs, 0
Wait 100 Millisecs, 0
Wait 100 Millisecs, 0
call LCD_Init ;Initialize the LCD
movlw 'I' ;Display Init message
call LCD_Txt
movlw 'n'
call LCD_Txt
movlw 'i'
call LCD_Txt
movlw 't'
call LCD_Txt
movlw 'i'
call LCD_Txt
movlw 'a'
call LCD_Txt
movlw 'l'
call LCD_Txt
movlw 'i'
call LCD_Txt
movlw 'z'
call LCD_Txt
movlw 'e'
call LCD_Txt
movlw 'd'
call LCD_Txt
movlw ' ' ;Display Version
call LCD_Txt
movlw 'V'
call LCD_Txt
movlw 'e'
call LCD_Txt
movlw 'r'
call LCD_Txt
movlw '.'
call LCD_Txt
movlw ' '
call LCD_Txt
movlw '0'
call LCD_Txt
movlw '.'
call LCD_Txt
movlw '1'
call LCD_Txt
movlw 0x03 ;position to bottem row
movwf CursorRow
movlw 0x13 ;position to last column
movwf CursorCol
call Search_1Wire_init
_search_next
; movlw 'a'
; call LCD_Print
call Search_1Wire ;Initiate a search
; movlw 'b'
; call LCD_Print
btfss return_value, 0 ;See if we found anything
goto _search_done ;Nope, we are done
; movlw 'c'
; call LCD_Print
movlw work0 ;get address of work area
movwf SOURCE ;make it the source for block move
movlw HIGH Lookup_TS
movwf PCLATH
movfw ctr_1wire ;get device count
call Lookup_TS ;get address of its entry
movwf DEST ;set as destination for block move
call Block_Move ;copy the work area off to storage
call Print_Work_Area
incf ctr_1wire, F ;count the one just found
movlw MAX_DEVICES
xorwf ctr_1wire, W
btfss STATUS, Z ;is it 4 devices found yet
goto _search_next ; No, try for another
_search_done
; movlw 'X'
; call LCD_Print
goto Main
Print_Work_Area
movfw work0
call LCD_Hex
movlw ':'
call LCD_Print
movfw work1
call LCD_Hex
movfw work2
call LCD_Hex
movfw work3
call LCD_Hex
movfw work4
call LCD_Hex
movfw work5
call LCD_Hex
movfw work6
call LCD_Hex
movlw ':'
call LCD_Print
movfw work7
call LCD_Hex
movlw 0x13 ;position to last column so next byte starts on new line
movwf CursorCol
return
;-------------------------------------------------------------------
;
; Search the Dallas 1-Wire Bus
;
;-------------------------------------------------------------------
Search_1Wire_init
clrf ctr_1wire ;init device counter(effectively clears table)
clrf work0 ;clear the work area to zeros
clrf work1
clrf work2
clrf work3
clrf work4
clrf work5
clrf work6
clrf work7
clrf last_discrep ;init the bit position of last descrepancy
clrf done_flag ;set status to not done
return
Search_1Wire
clrf return_value ;set return flag to false
btfss done_flag,0 ;Are we done yet?
goto Do_reset ; No, start a search
clrf done_flag ; Yes, init this for next time???
goto Wrapup ; and get on out of here
Do_reset
call Reset_1wire
clrf rombit_idx ;set rom bit index to 1
incf rombit_idx, F
clrf curr_discrep ;set descrepancy marker to 0
movlw h'f0' ;send search rom
movwf OneWireByte
call Sendbyte_1wire ; command to devices
bsf MAIN_SCOPE
bcf MAIN_SCOPE
Get_2bits
call Readbit_1wire ;read bit a from bus and
movwf bits ; save it
clrc ;clear the carry flag
rlf bits, F ;shift bit A over to the left
call Readbit_1wire ;read bit B from bus and
iorwf bits, F ; save it
movlw HIGH lookup_1x
movwf PCLATH
movfw bits
lookup_1x
addwf PCL, F ;decode the bits read
goto bits_00 ;collision detected
goto bits_01 ;0 read
goto bits_10 ;1 read
goto bits_11 ;nobody there
bits_00 ;collision detected
;Does rombit_idx = last_discrep
; movlw '0'
; call LCD_Print
movfw rombit_idx
xorwf last_discrep, W
btfss STATUS, Z ;Does rombit_idx = last_discrep
goto _chknxt ; No, check other stuff
movlw b'10' ; Yes, pretend we read a 1
movwf bits
call Store_Bit ;Store a 1 into work area
goto ack_bus
_chknxt
movfw last_discrep ;get current bit position
subwf rombit_idx, W ;compare to last discrepancy position
;is rombit_idx > last_discrep
btfss STATUS, C
goto _chknx2 ; No,
movlw b'01' ; Yes, pretend we read a 0
movwf bits
call Store_Bit
;set discrepancy marker to rombit_idx
movfw rombit_idx
movwf curr_discrep
goto ack_bus
_chknx2
;does rombits(rombit_idx) = 0 ?
call GetWorkBit ;get bit located at work(rombit_idx)
movwf TEMP0 ; and save
movlw HIGH lookup_2x
movwf PCLATH
movfw TEMP0
lookup_2x
addwf PCL, F ;quik test for 0 or 1
goto _zero ; was 0
_one ; was 1
movlw b'10' ; Pretend we read a 1
movwf bits
goto ack_bus
_zero
movlw b'01' ; Pretend we read a 0
movwf bits
;set discrepancy marker to rombit_idx
movfw rombit_idx
movwf curr_discrep
goto ack_bus
bits_01 ;0 received
; movlw '1'
; call LCD_Print
goto _storit
bits_10 ;1 received
; movlw '2'
; call LCD_Print
_storit
call Store_Bit ;Save it into work area at rombit_idx offset
; Send rombit(rombit_idx) to 1-wire bus
ack_bus
; call GetWorkBit
clrc ;clear the carry flag and
rrf bits, W ; get bit A into W
call Sendbit_1wire ;send bit A to wire
; Increment rombit_idx
incf rombit_idx, F ;bump pointer to next location
; Is rombit_idx > 64?
movfw rombit_idx ;see if index > 64
sublw d'65' ; (i.e. = 65)
btfss STATUS, Z
goto Get_2bits ;if not, loop back for more
;set last discrepancy to descrepancy marker
movfw curr_discrep
movwf last_discrep
;is last discrepancy = 0?
btfsc STATUS, Z
incf done_flag, F ;yes, set done flag
movlw d'1' ;either way, set return value to true
movwf return_value
goto Wrapup
bits_11 ;nothing answered on the bus
movlw 'D'
call LCD_Print
movlw 'e'
call LCD_Print
movlw 'a'
call LCD_Print
movlw 'd'
call LCD_Print
movlw 'B'
call LCD_Print
movlw 'e'
call LCD_Print
movlw 'e'
call LCD_Print
movlw 'f'
call LCD_Print
clrf last_discrep
goto Wrapup
Wrapup
return
;---------------------------------------------------------------------
;Reset the one wire bus
;---------------------------------------------------------------------
Reset_1wire
bcf ONE_WIRE ;Pull it low
Wait 480 Microsecs, 0 ;Hold it till they are reset
bsf ONE_WIRE ;Let it idle back up
;
;*** suppose to check for ack from devices here, but why?? I'm leaving it out for now
;
Wait 500 Microsecs, 0
return
;---------------------------------------------------------------------
;Send bytes and bits on the one wire bus
; BYTE -- Send a byte from OneWireByte to the one wire bus
; bit -- Send bits, 1 to the one wire bus
;---------------------------------------------------------------------
Sendbyte_1wire
movlw d'8'
movwf TEMP0
; bsf MAIN_SCOPE
; bcf MAIN_SCOPE
_send_1w_lp
clrf TEMP1 ;Clear work area
bcf TEMP1, 0 ;Assume sending 0
clrc ;Fill new bits with 0
rrf OneWireByte, F ;Load CARRY with bit to send
btfsc STATUS, C ;See what we are sending
bsf TEMP1, 0 ; must be a 1
movfw TEMP1 ;Load up the bit and
call Sendbit_1wire ; send it out
decfsz TEMP0, F ;Is it 8 bits yet
goto _send_1w_lp ; not yet
return
Sendbit_1wire
movwf TEMP1
bcf ONE_WIRE ;Pull it low
btfsc TEMP1, 0
bsf ONE_WIRE ;end of low pulse if bit was a 1
Wait 58 Microsecs,0 ; (Tslot + Trec) - Tlow1
bsf ONE_WIRE ;end of low pulse if 0 (1 no change)
Wait 1 Microsecs,4 ; Trec
return
;---------------------------------------------------------------------
;Receive bytes and bits from the one wire bus
; BYTE -- Read a byte from the one wire and stick into OneWireByte
; bit -- Read a bit sticking it into bits, 1
;---------------------------------------------------------------------
Readbyte_1wire
movlw d'8'
movwf TEMP0
_read_1w_lp
call Readbit_1wire
movwf TEMP1 ;Save the bit read
clrc ;Assume bit is 0
btfsc TEMP1, 0 ;Check bit
setc ; its a 1
rrf OneWireByte, F ;Rotate bit into IO area
decfsz TEMP0, F ;Is it 8 bits yet
goto _read_1w_lp ; not yet
movfw OneWireByte ; yes, return with byte read in W
return ;
Readbit_1wire
bcf ONE_WIRE ;Pull it low and
nop
bsf ONE_WIRE ; release for a clock pulse
clrf TEMP1 ;Assume incomming bit is 0
Wait 12 Microsecs, 0 ;Give device time to respond
btfsc ONE_WIRE ;What are we receiving?
bsf TEMP1, 0 ; must be a 1
Wait 47 Microsecs, 0 ;Wait out the rest of the cycle
movfw TEMP1
return
;---------------------------------------------------------------------
;Block_Move -- Move 8 Bytes from SOURCE to DEST
; Entry:
; SOURCE should be pointing at place to move from
; DEST should be pointing at destination place to store block
; Exit:
; SOURCE ,DEST, TEMP0, TEMP1, FSR will be destroyed. However,
; the data will be moved ;-D
;---------------------------------------------------------------------
Block_Move
movlw d'8'
movwf TEMP0
_move_lp
movfw SOURCE ;Set up source pointer
movwf FSR
movfw INDF ;get the byte
movwf TEMP1 ; and save it
movfw DEST ;Set up destination pointer
movwf FSR
movfw TEMP1 ;pick up saved byte
movwf INDF ; and store it (now it is moved to destination)
incf SOURCE, F ;adjust pointers
incf DEST, F
decfsz TEMP0, F
goto _move_lp
return
;---------------------------------------------------------------------------------------------
;
; LCD_Print - Print a character to the LCD w/proper scrolling and wrapping
; Code is setup for a 4 * 20 LCD Display
;
;---------------------------------------------------------------------------------------------
LCD_Print
movwf TEMPX
incf CursorCol, F ;Bump the cursor
movfw CursorCol ;Load it
xorlw 0x14 ;Is it running off the right side of the screen
btfss STATUS, Z
goto noscroll ;No, go on and print it
; bsf MAIN_SCOPE
call scroll_scr ;Yes, scroll the display
clrf CursorCol ;Set cursor to beginning of line
; bcf MAIN_SCOPE
noscroll
movlw HIGH lookup_row
movwf PCLATH
movfw CursorRow ;Get current row into W
call lookup_row ;Convert to start address of row
addwf CursorCol, W ;Add in the column position
movwf AbsAddr ;Store absolute address
iorlw b'10000000' ; convert ABS Address to lcd command to set DDRAM address
call LCD_Cmd ;Set DDRAM address
movfw TEMPX ;Load the character received and
goto LCD_Txt ; display it
;---------------------------------------------------------------------------------------------
;
; scroll_scr - Scroll Screen by moving data up a line at a time and then
; filling the bottom row with blanks.
;
;---------------------------------------------------------------------------------------------
scroll_scr
movlw 0x03 ; Move three rows total 1->0, 2->1, 3->2
movwf RowLoopCtr ;
clrf DestRowNum ; Destination starts at row 0
movlw 0x01 ; Source row starts at row 1
movwf SrcRowNum
move_row
movlw HIGH lookup_row
movwf PCLATH
movf DestRowNum, W ; Get destination row number and
call lookup_row ; convert to a char address
movwf DestCharAddr ; and save it
movlw HIGH lookup_row
movwf PCLATH
movf SrcRowNum, W ; Get source row number and
call lookup_row ; convert to a char address
movwf SrcCharAddr ; and save it
movlw 0x14 ; twenty chars per line
movwf CharLoopCtr
move_chars
; read the source character
movf SrcCharAddr, W ; Load DDRAM address into W
; call LCD_ReadRam ; Fetch the character stored there
iorlw b'10000000' ;Turn on the high bit (Set DDRAM Address)
call LCD_Cmd ;Write the command to set the address
call LCD_In ;Read the DDRAM value at current position
movwf LCD_Data ; and save it
;if bottom row move a space to it while we are here
movf SrcRowNum,W ; See which row we are on
xorlw 0x03 ; Is it the bottom one
btfss STATUS, Z
goto wrtdest ; No, just write the destination location
;have to reposition the cursor since it insists on moving itself after a read
movf SrcCharAddr, W ; Load DDRAM address into W
iorlw b'10000000' ; make into a command to set address
call LCD_Cmd ; issue the command
movlw ' ' ; Load up a space character
call LCD_Txt ; and clear the character in the bottom row
;write to destination address
wrtdest
movf DestCharAddr, W ; Load Destination DDRAM address
iorlw b'10000000' ; make into a command to set address
call LCD_Cmd ; issue the command
movf LCD_Data, W ; Get the saved character
call LCD_Txt ; Write character to destination address
incf SrcCharAddr, F
incf DestCharAddr, F
decfsz CharLoopCtr, F
goto move_chars
row_done
incf DestRowNum, F ; Point to next row
incf SrcRowNum, F ; Same thing
decfsz RowLoopCtr, F ; Decrement loop counter and
goto move_row ; move next row
return
;---------------------------------------------------------------------------------------------
;
; LCD_ReadRam - Return character stored at LCD DDRAM Location
;
;---------------------------------------------------------------------------------------------
LCD_ReadRam
; movwf TEMP3 ;Save the address
iorlw b'10000000' ;Turn on the high bit (Set DDRAM Address)
call LCD_Cmd ;Write the command to set the address
call LCD_In ;Read the DDRAM value at current position
return
;---------------------------------------------------------------------------------------------
; LCD_Txt - Write ASCII byte in W to LCD
;
;---------------------------------------------------------------------------------------------
LCD_Txt
movwf TEMP1 ;Store w for LCD_Out
call LCD_BF ;Get the busy flag
andlw b'10000000'
btfss STATUS, Z ;Is busy flag set?
goto $ - 3 ; yes. Re-test busy flag.
bsf LCD_RS ;This is DATA.
goto LCD_Out ;Execute part of LCD_Cmd
;---------------------------------------------------------------------------------------------
; LCD_Cmd ROM: 12 words RAM: TEMP0, TEMP1
;---------------------------------------------------------------------------------------------
LCD_Cmd
movwf TEMP1 ;Store w
call LCD_BF ;Get the busy flag
andlw b'10000000'
btfss STATUS, Z ;Is busy flag set?
goto $ - 3 ; Yes. Re-test busy flag.
bcf LCD_RS ;This is a COMMAND.
LCD_Out bcf LCD_RW ;This is a WRITE.
movf TEMP1, w ;Restore w.
call LCD_Nbl ;Output the upper four bits of W.
swapf TEMP1, w ;Swap nybbles (and put result in W).
call LCD_Nbl ;Output the lower four bits of W.
return ;Done--Return.
;----------------------------------------------------------------------------------------------
;
; LCD_In - Return byte stored in CGRAM at currently addressed location (cursor position)
;
;----------------------------------------------------------------------------------------------
LCD_In
call LCD_BF ;Get the busy flag
andlw b'10000000'
btfss STATUS, Z ;Is busy flag set?
goto LCD_In ; Yes. Re-test busy flag.
bsf LCD_RS ;This is DATA operation.
bsf LCD_RW ;This is a READ.
bsf STATUS, RP0 ;Select Bank 1.
bsf TRISB & 0x07F, 4 ;Make ports input
bsf TRISB & 0x07F, 5
bsf TRISB & 0x07F, 6
bsf TRISB & 0x07F, 7
bcf STATUS, RP0 ;Bank 0 please
bsf LCD_EN ;Clock out the RS and RW bits.
movf LCD_PORT, w ;Get,
andlw b'11110000' ; mask, and
movwf TEMP0 ; store the upper nybble into a temp area
bcf LCD_EN ;Clock in the upper nybble
bsf LCD_EN ;Clock in the lower nybble
movf LCD_PORT, w ;Get and
andlw b'11110000' ; mask the lower nybble
bcf LCD_EN
swapf TEMP0, f ;Flip the temp area around backwards and
iorwf TEMP0, f ; OR in the lower nybble to the upper half of temp
swapf TEMP0, w ;Repair and load the byte into w.
return ;Done -- return.
;---------------------------------------------------------------------------------------------
;
; LCD_Hex - Take byte in W and LCD_Print it in HEX
;
;---------------------------------------------------------------------------------------------
LCD_Hex
movwf TEMP2 ;Store w
swapf TEMP2, w ;Get upper nybble of w
andlw b'00001111'
call LCD_Hex1 ;Convert upper nybble to ASCII
call LCD_Print ;Output ASCII on LCD display
movf TEMP2, w ;Get lower nybble of w
andlw b'00001111'
call LCD_Hex1 ;Conver lower nybble to ASCII
call LCD_Print ;Output ASCII on LCD display
return ;Done--return.
LCD_Hex1
addlw 0xF6 ;This routine converts a number in w to an
btfsc STATUS, C ;ASCII hex number. Result in w.
addlw 0x07
addlw 0x3A
return
;---------------------------------------------------------------------------------------------
;
; LCD_Nbl - Writes one nibble contained in upper half of W to LCD
;
;---------------------------------------------------------------------------------------------
LCD_Nbl
bsf STATUS, RP0 ;Make LCD_PORT.4-7 Outputs
bcf TRISB & 0x07F, 4
bcf TRISB & 0x07F, 5
bcf TRISB & 0x07F, 6
bcf TRISB & 0x07F, 7
bcf STATUS, RP0
bcf LCD_RW ;This is a WRITE command.
bsf LCD_EN ;Clock out RS and RW.
iorlw b'00001111' ;Write the upper four bits in W to the upper
andwf LCD_PORT, f ; four bits in LCD_PORT.
andlw b'11110000'
iorwf LCD_PORT, f
bcf LCD_EN ;Clock out the four data bits.
return ;Done--Return.
;---------------------------------------------------------------------------------------------
;
; LCD_BF - Do a busy flag read of the LCD returning in W': BF A6 A5 A4 A3 A2 A1 A0
;
;---------------------------------------------------------------------------------------------
LCD_BF
bcf LCD_RS ;This is a DATA operation.
bsf LCD_RW ;This is a READ command.
bsf STATUS, RP0 ;Select Bank 1.
bsf TRISB & 0x07F, 4 ;Make ports input
bsf TRISB & 0x07F, 5
bsf TRISB & 0x07F, 6
bsf TRISB & 0x07F, 7
bcf STATUS, RP0
bsf LCD_EN ;Clock out the RS and RW bits.
movf LCD_PORT, w ;Get,
andlw b'11110000' ; mask, and
movwf TEMP0 ; store the upper nybble into a temp area
bcf LCD_EN ;Bring enable pin low after getting data
bsf LCD_EN ;Clock in the lower nybble
movf LCD_PORT, w ;Get and
andlw b'11110000' ; mask the lower nybble
bcf LCD_EN
swapf TEMP0, f ;Flip the temp area around backwards and
iorwf TEMP0, f ; OR in the lower nybble to the upper half of temp
swapf TEMP0, w ;Repair and load the byte into w.
return ;Done -- return.
;---------------------------------------------------------------------------------------------
;
; LCD_Init - That pretty much says it all
;
;---------------------------------------------------------------------------------------------
LCD_Init
bcf LCD_RS ;The following will write to the HD44780's IR.
Wait 10 Millisecs, 0
;
;Grab display per recommended way by setting to eight bit mode 3 times
;
movlw b'00111000' ;Function set
call LCD_Nbl
Wait 50 Microsecs, 0 ;Wait 50us
movlw b'00111000' ;Function set
call LCD_Nbl
Wait 50 Microsecs, 0 ;Wait 50us
movlw b'00111000' ;Function set
call LCD_Nbl
Wait 50 Microsecs, 0 ;Wait 50us
;
;Now that we have its attention, set it to nibble mode and initialize
;
movlw b'00101000' ;Function Set -- 0 0 1 DL N F X X (nibble mode, 2lines, 5x7 font)
call LCD_Cmd
movlw b'00000001' ;Clear Display -- 0 0 0 0 0 0 0 1
call LCD_Cmd
Wait 1650 Microsecs, 0 ;Wait 1.65ms
movlw b'00000110' ;Entry Mode Set -- 0 0 0 0 0 1 ID S (increment, no shifting)
call LCD_Cmd
movlw b'00001100' ;Display Control -- 0 0 0 0 1 D C B (display on, no cursor, no blink)
call LCD_Cmd
return
#include "delay.asm"
end
ON 20030316@7:11:24 PM at page:
http://techref.massmind.org/techref/microchip/ios.htm
JMN-EFP-786 James Newton edited the page. Difference:
http://techref.massmind.org/techref/diff.asp?url=H:\techref\microchip\ios.htm&version=4
ON 20030317@12:13:12 PM at page:
http://www.piclist.commicrochip/i2c-eeprom.htm
JMN-EFP-786 James Newton published post 37697.2265162037
kissg@sztaki.hu refers to
http://gatling.ikk.sztaki.hu/~kissg/pd/pic/pic12ce51x-eeprom.html
|Delete 'P-' before: '' but after: 'chazmankelow@aol.com asks: "
i need to program a chip that takes a parallel signal from an ADC and converts it to serial to transmit via a fibre optic link. any ideas?"
|Delete 'P-' before: '' but after: '4x4 Keypad and LCD in 1 port"
ON 20030320@8:02:36 AM at page:
http://www.piclist.commicrochip/routines.htm
JMN-EFP-786 James Newton published post 37700.3225347222
just excellent
|Delete 'P-' before: '' but after: 'chris@jazzysystems.com asks: Can the Yap-II program the PIC16F627 chip used in Myke Predko's Programming Robot Controllers. The Yap-II is conspicuously not mentioned and nothing is mentioned in the Errata or on the Internet that I could find.' ON 20030324@4:34:35 PM at page: http://www.piclist.commicrochip/devprogs.htm JMN-EFP-786 James Newton published post 37704.6181365741 chris@jazzysystems.com asks:
Can the Yap-II program the PIC16F627 chip used in Myke Predko's Programming|Delete 'P-' before: '' but after: ' http://www.microchip.com/1000/suppdoc/appnote/all/an715/index.htm Answer to question concerning ADXL calibration:
Robot Controllers. The Yap-II is conspicuously not mentioned and nothing is
mentioned in the Errata or on the Internet that I could find.