It can, but you need to control it.You said:of course it won't, Basic can't do negative numbers...
I have indicators written in Oshon and I provide the logic glue..
Last edited:
Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
It can, but you need to control it.You said:of course it won't, Basic can't do negative numbers...
Thanks Mike, yes default is decimal (although I tend to mix and match depending on what part of the program I'm writing).Edit, I assumed the default radix is decimal, if not I can produce the table anyway you like.
I think I might have a near enough solution:1. get your ADC value.
2. if above 491 calculate ADC-492 - this allows for the dead zone.
3. if below 483 calculate 482-ADC
4. if neither 2 or 3 true then calculated value=0
5. if not zero then lookup value in a table.
radix dec
errorlevel -207 ;Skip found label after column 1
errorlevel -302 ;Skip out of bank nuisance messages
errorlevel -303 ;Skip program word too large. Truncated to core size
;
; *******************************************************************************
; * Configuration fuse information for 16F1827: *
; *******************************************************************************
;
include <P16LF1827.INC>
__CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_LO & _LVP_OFF
CBLOCK 0x20
tempADC:2
flags
ENDC
CBLOCK 0x70
acc:2 ;in common memory so can be accessed from bank 3 (where flash registers are)
ENDC
ORG 0x0000
goto start
ORG 0x0004
;--------------------------------------------------------------------------------
start
banksel OSCCON
movlw b'01101000'
movwf OSCCON
banksel 0
call getValue
goto $
#define valueADC 35
#define center 487
getValue
;first do ADC-487 to discover direction
bcf flags,0 ;clear the negative flag
movlw low(valueADC)
movwf acc
movlw high(valueADC)
movwf acc+1
movlw high(center)
subwf acc+1,f
movlw low(center)
subwf acc,f
btfss STATUS,C
decf acc+1,f
btfss acc+1,7 ;is it negative
goto notNeg
;need to negate acc
bsf flags,0 ;set the negative flag
movlw 0xff
xorwf acc,f
xorwf acc+1,f
incf acc,f
btfsc STATUS,Z
incf acc+1,f
notNeg
; have now got a valid lookup value
;and a flag to tell us if above or below 487
banksel EEADRL ;Select Bank for EEPROM registers
movfw acc ;
movwf EEADRL
movfw acc+1
addlw 0x0e
movwf EEADRH
bcf EECON1,CFGS ;Do not select Configuration Space
bsf EECON1,EEPGD ;Select Program Memory
bsf EECON1,RD ;Initiate read
NOP ;required 2 x NOPs
NOP
;EEDAT will now contain 0 - 2500
;and flags,0 will be set if below center
goto $
org 0xe00
;note, dead band incorporated into table
DW 0,0,0,0,0,5,11,16,22,27,33,39,44,50,55,61,67,72,78,83,89
DW 95,100,106,111,117,123,128,134,139,145,151,156,162,167,173,178
DW 184,190,195,201,206,212,218,223,229,234,240,246,251,257,262,268
DW 274,279,285,290,296,302,307,313,318,324,329,335,341,346,352,357
DW 363,369,374,380,385,391,397,402,408,413,419,425,430,436,441,447
DW 453,458,464,469,475,480,486,492,497,503,508,514,520,525,531,536
DW 542,548,553,559,564,570,576,581,587,592,598,604,609,615,620,626
DW 631,637,643,648,654,659,665,671,676,682,687,693,699,704,710,715
DW 721,727,732,738,743,749,755,760,766,771,777,782,788,794,799,805
DW 810,816,822,827,833,838,844,850,855,861,866,872,878,883,889,894
DW 900,906,911,917,922,928,934,939,945,950,956,961,967,973,978,984
DW 989,995,1001,1006,1012,1017,1023,1029,1034,1040,1045,1051,1057,1062,1068,1073
DW 1079,1085,1090,1096,1101,1107,1112,1118,1124,1129,1135,1140,1146,1152,1157,1163
DW 1168,1174,1180,1185,1191,1196,1202,1208,1213,1219,1224,1230,1236,1241,1247,1252
DW 1258,1263,1269,1275,1280,1286,1291,1297,1303,1308,1314,1319,1325,1331,1336,1342
DW 1347,1353,1359,1364,1370,1375,1381,1387,1392,1398,1403,1409,1414,1420,1426,1431
DW 1437,1442,1448,1454,1459,1465,1470,1476,1482,1487,1493,1498,1504,1510,1515,1521
DW 1526,1532,1538,1543,1549,1554,1560,1565,1571,1577,1582,1588,1593,1599,1605,1610
DW 1616,1621,1627,1633,1638,1644,1649,1655,1661,1666,1672,1677,1683,1689,1694,1700
DW 1705,1711,1717,1722,1728,1733,1739,1744,1750,1756,1761,1767,1772,1778,1784,1789
DW 1795,1800,1806,1812,1817,1823,1828,1834,1840,1845,1851,1856,1862,1868,1873,1879
DW 1884,1890,1895,1901,1907,1912,1918,1923,1929,1935,1940,1946,1951,1957,1963,1968
DW 1974,1979,1985,1991,1996,2002,2007,2013,2019,2024,2030,2035,2041,2046,2052,2058
DW 2063,2069,2074,2080,2086,2091,2097,2102,2108,2114,2119,2125,2130,2136,2142,2147
DW 2153,2158,2164,2170,2175,2181,2186,2192,2197,2203,2209,2214,2220,2225,2231,2237
DW 2242,2248,2253,2259,2265,2270,2276,2281,2287,2293,2298,2304,2309,2315,2321,2326
DW 2332,2337,2343,2348,2354,2360,2365,2371,2376,2382,2388,2393,2399,2404,2410,2416
DW 2421,2427,2432,2438,2444,2449,2455,2460,2466,2472,2477,2483,2488,2494,2500,2500
DW 2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500
DW 2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500
DW 2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500
DW 2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500
end
;
;********************************************************************************
;
; Target Controller PIC16F1827
; __________
; ADC-IN-----RA2 |1 18| RA1---------
; -----------RA3 |2 17| RA0---------
; -----------RA4 |3 16| RA7---------
; -----------RA5 |4 15| RA6---------
; Ground----------Vss |5 14| VDD---------+5 V
; LCD D4----------RB0 |6 13| RB7---------
; LCD D5----------RB1 |7 12| RB6---------LCD_rs (LCD Pin 4)
; LCD D6----------RB2 |8 11| RB5---------LCD_rw (LCD Pin 5)
; LCD D7----------RB3 |9 10| RB4---------LCD_e (LCD Pin 6)
; ----------
;
; *******************************************************************************
; * Device type and options *
; *******************************************************************************
;
processor 16F1827
radix dec
errorlevel -207 ; Skip found label after column 1
errorlevel -302 ; Skip out of bank nuisance messages
errorlevel -303 ; Skip program word too large. Truncated to core size
;
; *******************************************************************************
; * Configuration fuse information for 16F1827: *
; *******************************************************************************
;
include <P16F1827.INC>
__CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_LO & _LVP_OFF
;
; *******************************************************************************
; Info for power-up display. Why was it done this way instead of with a table -
; because it is easier for beginners to visualise where the characters will
; appear on the LCD.
SIGN_ON_1 equ ' ' ; Position 1 on LCD - left most position
SIGN_ON_2 equ 'V'
SIGN_ON_3 equ 'K'
SIGN_ON_4 equ '5'
SIGN_ON_5 equ 'T'
SIGN_ON_6 equ 'M'
SIGN_ON_7 equ ' '
SIGN_ON_8 equ 'A'
SIGN_ON_9 equ 'D'
SIGN_ON_10 equ 'C'
SIGN_ON_11 equ ' '
SIGN_ON_12 equ 'T'
SIGN_ON_13 equ 'E'
SIGN_ON_14 equ 'S'
SIGN_ON_15 equ 'T'
SIGN_ON_16 equ ' ' ; Position 16 on LCD - right most position
;
; *******************************************************************************
; * General equates. *
; *******************************************************************************
;
#define center 487
;
; *******************************************************************************
; * Assign names to IO pins. *
; *******************************************************************************
;
LCD_busy equ 0x03 ; LCD busy bit
LCD_e equ 0x04 ; 0=disable, 1=enable
LCD_rw equ 0x05 ; 0=write, 1=read
LCD_rs equ 0x06 ; 0=instruction, 1=data
;
;
; 16F1827 Oscillator setup
; OSCCON - Oscillator control reg.
; ---------------------------------
; SPLLEN b7 enable PLL x4
; 1 = enabled 0 = disabled
; IRCF | b6-3 frequency selection
; 1111 = 16MHz HF
; 1110 = 8 or 32MHz HF
; 1101 = 4MHz HF
; 1100 = 2MHz HF
; 1011 = 1MHz HF
; 1010 = 500kHz HF
; 1001 = 250kHz HF
; 1000 = 125kHz HF
; 0111 = 500kHz MF (default)
; 0110 = 250kHz MF
; 0101 = 125kHz MF
; 0100 = 62.5kHz MF
; 0011 = 31.25kHz HF
; 0010 = 31.25kHz MF
; 000x = 31.25kHz LF
; Reserved B2 reserved, 0
; SCS B1 0-: 1x = int. OSC.
; 01 = Timer1 oscillator
; 00 = determined by FOSC <2:0> in Configuratio
; POR default 00111-00 500 kHz (POR = Power On Reset)
OSCCONVAL EQU b'01101000' ; 4MhZ CLOCK
;
; *******************************************************************************
; * Allocate variables in general purpose register space *
; *******************************************************************************
;
CBLOCK 0x20 ; Start Data Block
TenK
Thou
Hund
Tens
Ones
freq_0
freq_1
freq_2
freq_3
byte2send ;
LCD_char ; Character being sent to the LCD
rs_value ; The LCD rs line flag value
timer1 ; Used in delay routines
timer2 ; "
count ; loop counter (gets reused)
temp ; General reusable register
CounterA
CounterB
CounterC
CounterD
CounterE
flags
ENDC ; End of Data Block
CBLOCK 0x70
acc:2
valueADC:2
NumH
NumL
ENDC ; End of Data Block
;
; *******************************************************************************
; * The 16F1827 resets to 0x00. *
; * The Interrupt vector is at 0x04. *
; *******************************************************************************
;
ORG 0x0000
goto start ; Jump to main program
ORG 0x0004
goto start ; Jump to main program
;
; *******************************************************************************
; * *
; * Purpose: This is the start of the program. *
; * *
; *******************************************************************************
;
start
BANKSEL PORTA
clrf PORTA
clrf PORTB
; Set PIC oscillator frequency
banksel OSCCON ; Select OSCCON
movlw OSCCONVAL ;
movwf OSCCON ; Loads the wanted value
banksel PORTA
; Configures all I / O as digital
Banksel ANSELA
bsf ANSELA,ANSA2 ; set ra2 to analog
clrf ANSELB
; Disable all wakeup pull-ups
Banksel WPUA
clrf WPUA
clrf WPUB
BANKSEL OPTION_REG
clrf OPTION_REG ;
;
movlw b'00110111' ; PORTA (RA0:2,4:5 inputs, RA3,6:7 outputs)
movwf TRISA ;
clrf TRISB ; Set port B to all outputs
; BANKSEL ADCON1 ;
movlw b'11000000' ; right justify, FOSC/4 vdd and vss vref
movwf ADCON1 ;
; BANKSEL ADCON0 ;
movlw b'00001001' ; select channel an2 & turn adc on
movwf ADCON0 ;
BANKSEL PORTA;
call init_LCD ; Initialize the LCD
call busy_check ; Wait for LCD to finish initialising
call display_version ; Display title and version
;
; *******************************************************************************
; * *
; * Purpose: This is the Main Program Loop. *
; * *
; *******************************************************************************
;
main
movlw 100
call wait ; acquisiton delay & loop delay
BANKSEL ADCON0
bsf ADCON0,ADGO ; start conversion
btfsc ADCON0,ADGO ; is conversion done?
goto $-1 ; no, test again
BANKSEL ADRESH
movf ADRESH,w ; read upper 2 bits
movlb 0
movwf valueADC ; store in gpr space
BANKSEL ADRESL
movf ADRESL,w ; read lower 8 bits
movlb 0
movwf valueADC+1 ; store in gpr space
call getValue
call bin2BCD
call show_bcd
goto main ; Continue main loop
;
getValue
;first do ADC-487 to discover direction
bcf flags,0 ; clear the negative flag
movlw low(valueADC)
movwf acc
movlw high(valueADC)
movwf acc+1
movlw high(center)
subwf acc+1,f
movlw low(center)
subwf acc,f
btfss STATUS,C
decf acc+1,f
btfss acc+1,7 ; is it negative
goto notNeg
;need to negate acc
bsf flags,0 ; set the negative flag
movlw 0xff
xorwf acc,f
xorwf acc+1,f
incf acc,f
btfsc STATUS,Z
incf acc+1,f
notNeg
; have now got a valid lookup value
; and a flag to tell us if above or below 487
BANKSEL EEADRL ; Select Bank for EEPROM registers
movfw acc ;
movwf EEADRL
movfw acc+1
addlw 0x0e
movwf EEADRH
bcf EECON1,CFGS ; Do not select Configuration Space
bsf EECON1,EEPGD ; Select Program Memory
bsf EECON1,RD ; Initiate read
NOP ; required 2 x NOPs
NOP
; EEDAT will now contain 0 - 2500
; and flags,0 will be set if below center
movf EEDATH,w
movwf NumH ; for BCD conversion routine
movf EEDATL,w
movwf NumL ; for BCD conversion routine
movlb 0
return
;
; *******************************************************************************
; * Purpose: *
; * This subroutine converts a 16 bit binary number to decimal in *
; * TenK, Thou, Hund, Tens, Ones *
; *******************************************************************************
;
bin2BCD ; Takes number in NumH:NumL and returns decimal in TenK:Thou:Hund:Tens:Ones
; Fast 16-Bit Binary to Decimal by Peter Hemsley
; Input: 16-bit binary in NumH and NumL
; Output: Decimal (BCD) digits in TenK,Thou,Hund,Tens,Ones
; No temporary variables required
; Code size: 46 instructions
; Execution time: Variable, approx 150 to 170 cycles
Bin2DecFast
movf NumH,w ;Hex Digit 0X00 (H2)
iorlw 0xF0 ;w=H2-16
movwf Ones ;Ones=H2-16
movwf Tens ;Tens=H2-16
addwf Tens,f ;Tens=H2*2-32
addwf Tens,f ;Tens=H2*3-48, C=1
movwf Hund ;Hund=H2-16
rlf Hund,f ;Hund=H2*2-31
swapf NumH,w ;Hex Digit X000 (H3)
iorlw 0xF0 ;w=H3-16
addwf Hund,f ;Hund=H3+H2*2-47 Done!
movwf Thou ;Thou=H3-16
addwf Thou,f ;Thou=H3*2-32
addlw D'52' ;w=H3+36
addwf Ones,f ;Ones=H3+H2+20
swapf NumL,w ;Hex Digit 00X0 (H1)
iorlw 0xF0 ;w=H1-16
addwf Tens,f ;Tens=H2*3+H1-64
addwf Ones,f ;Ones=H3+H2+H1+4, C=1
rlf Ones,f ;Ones=(H3+H2+H1)*2+9, C=0
comf Ones,f ;Ones=-(H3+H2+H1)*2-10
rlf Ones,f ;Ones=-(H3+H2+H1)*4-20
movf NumL,w ;Hex Digit 000X (H0)
andlw 0x0F ;w=H0
addwf Ones,f ;Ones=H0-(H3+H2+H1)*4-20 Done!
rlf Tens,f ;C=0, Tens=H2*6+H1*2-128 Done!
movlw D'7'
movwf TenK ;TenK=7
addlw D'3' ;w=10, C=0
rlf Thou,f ;Thou=H3*4-64 Done!
mod0
addwf Ones,f ;D(X)=D(X)mod10
decf Tens,f ;D(X+1)=D(X+1)+D(X)div10
skpc
goto mod0
mod1
addwf Tens,f
decf Hund,f
skpc
goto mod1
mod2
addwf Hund,f
decf Thou,f
skpc
goto mod2
mod3
addwf Thou,f
decf TenK,f
skpc
goto mod3
return
;
; *******************************************************************************
; * Display data on the LCD. *
; *******************************************************************************
;
show_bcd
movlw 0xC1 ; Point the LCD to digit location
call cmnd2LCD ; Send digit location to LCD
movf Thou,f ; Test if 'file'is 0 or 1
btfss STATUS,Z ; The Z or Zero bit is set to "1" when the result
goto not_zero ; of an arithmetic or logical operation is zero
movlw ' ' ; Thou = 0, insert space
call data2LCD ; Send byte in W to LCD
goto show_Hund
not_zero
movfw Thou ; Thou is not 0, insert number
addlw 0x30 ; Convert to ASCII character
call data2LCD ; Send to LCD - rinse and repeat until all characters sent
show_Hund
movfw Hund
addlw 0x30
call data2LCD
movfw Tens
addlw 0x30
call data2LCD
movfw Ones
addlw 0x30
call data2LCD
return
;
; *******************************************************************************
; * *
; * Purpose: Send Command or Data byte to the LCD *
; * Entry point cmnd2LCD: Send a Command to the LCD *
; * Entry Point data2LCD: Send a Data byte to the LCD *
; * *
; * Input: W has the command or data byte to be sent to the LCD. *
; * *
; *******************************************************************************
;
cmnd2LCD ; ****** Entry point for commands ******
clrf rs_value ; Remember to clear RS (clear rs_value)
goto write2LCD ; Go to common code
data2LCD ; ****** Entry point for data ********
bsf rs_value,0 ; Remember to set RS (set bit 0 of rs_value)
write2LCD
movwf LCD_char ; Save byte to write to LCD
call busy_check ; Check to see if LCD is ready for new data
movlw 2 ;
movwf count ; SET UP LOOP COUNTER
write2LCD2
swapf LCD_char,f ; SWAP MS & LS NIBBLES
movf LCD_char,w
andlw 15 ; MAKE TOP 4 BITS OF W 0
movwf PORTB ; SEND MS NIBBLE
bcf PORTB,LCD_rs ; Guess RS should be clear - command mode
btfsc rs_value,0 ; Should RS be clear? (is bit 0 == 0?)
bsf PORTB,LCD_rs ; No, set RS - data mode
nop
bsf PORTB,LCD_e ; SET E HIGH
nop
bcf PORTB,LCD_e ; SET E LOW
decfsz count,F
goto write2LCD2 ; GO BACK AND SEND LS NIBBLE
return
;
; *******************************************************************************
; * *
; * Purpose: Check if LCD is done with the last operation. *
; * This subroutine polls the LCD busy flag to determine if *
; * previous operations are completed. *
; * *
; *******************************************************************************
;
busy_check
clrf PORTB ; Clear all outputs on PORTB
banksel TRISB ; Switch to bank for Tris operation
movlw b'00001000' ; Set RB3 input, others outputs
movwf TRISB ;
banksel PORTB
bcf PORTB,LCD_rs ; Set up LCD for Read Busy Flag (RS = 0)
nop
bsf PORTB,LCD_rw ; Set up LCD for Read (RW = 1)
LCD_is_busy
bsf PORTB,LCD_e ; Set E high
nop
bcf PORTB,LCD_e ; Drop E again
btfss PORTB,LCD_busy ; Is Busy Flag (RB3) clear?
goto not_busy ; Yes - exit
nop ; No
nop ; Wait a while
bsf PORTB,LCD_e ; Pulse E high (dummy read of lower nibble),
nop ; wait,
bcf PORTB,LCD_e ; and drop E again
goto LCD_is_busy ; If not, it is busy so jump back
not_busy
banksel TRISB ; Switch to bank 1 for Tristate operation
clrf TRISB ; All pins (RB7..RB0) are back to outputs
banksel PORTB ; Switch to bank 0
clrf PORTB ; Clear all of Port B (inputs and outputs)
return ;
;
;
; *******************************************************************************
; * *
; * Purpose: Power on initialization of Liquid Crystal Display. The LCD *
; * controller chip must be equivalent to an Hitachi 44780. *
; * *
; *******************************************************************************
;
init_LCD
movlw 100
call wait ; Wait for LCD to power up
; Put 4-bit command on RB3..RB0
; PIC's RB3..RB0 lines connect to LCD's DB7..DB4 lines
movlw 0x03 ; LCD init instruction (First)
movwf PORTB ; Send to LCD via RB3..RB0
bsf PORTB,LCD_e ; Set the LCD E line high,
movlw 100
call wait ; wait a "long" time,
bcf PORTB,LCD_e ; and then Clear E
movlw 0x03 ; LCD init instruction (Second)
movwf PORTB ; Send to LCD via RB3..RB0
bsf PORTB,LCD_e ; Set E high,
movlw 32
call wait ; wait a while,
bcf PORTB,LCD_e ; and then Clear E
movlw 0x03 ; LCD init instruction (Third)
movwf PORTB ; Send to LCD via RB3..RB0
bsf PORTB,LCD_e ; Set E high,
movlw 32
call wait ; wait a while,
bcf PORTB,LCD_e ; and then Clear E
movlw 0x02 ; 4-bit mode instruction
movwf PORTB ; Send to LCD via RB3..RB0
bsf PORTB,LCD_e ; Set E high,
movlw 16
call wait ; wait a while,
bcf PORTB,LCD_e ; and then Clear E
movlw 0x28 ; 1/16 duty cycle, 5x8 matrix
call cmnd2LCD ; Send command in w to LCD
movlw 0x08 ; Display off, cursor and blink off
call cmnd2LCD ; Send command to LCD
movlw 0x01 ; Clear and reset cursor
call cmnd2LCD ; Send command in w to LCD
movlw 0x06 ; Set cursor to move right, no shift
call cmnd2LCD ; Send command in w to LCD
movlw 0x0E ; Display on, cursor on and blink off
; movlw 0x0F ; Display on, cursor on and blink on
; movlw 0x0C ; Display on, cursor and blink off
call cmnd2LCD ; Send command in w to LCD
return ;
;
; *******************************************************************************
; * *
; * Function: clear_lcd *
; * *
; * Purpose: Clears the LCD and homes the cursor. *
; * *
; * Input: None *
; * *
; * Output: None *
; * *
; * Revisions: Ver 2.0: Added function for convenience and to reduce code *
; * space 4-4-04 W3CD. *
; * *
; *******************************************************************************
;
clear_lcd
movlw 0x01 ; Prepare to display a new message on LCD
call cmnd2LCD ; by clearing the current one
return
;
; *******************************************************************************
; * *
; * Purpose: Display version and other info on LCD for 1 second *
; * upon power-up *
; * *
; * Input: SIGN_ON_1 through SIGN_ON_16 *
; * *
; * Output: LCD displays info *
; * *
; *******************************************************************************
;
display_version
call clear_lcd
movlw SIGN_ON_1 ; digit 1
call data2LCD ;
movlw SIGN_ON_2 ; digit 2
call data2LCD ;
movlw SIGN_ON_3 ; digit 3
call data2LCD ;
movlw SIGN_ON_4 ; digit 4
call data2LCD ;
movlw SIGN_ON_5 ; digit 5
call data2LCD ;
movlw SIGN_ON_6 ; digit 6
call data2LCD ;
movlw SIGN_ON_7 ; digit 7
call data2LCD ;
movlw SIGN_ON_8 ; digit 8
call data2LCD ;
movlw SIGN_ON_9 ; digit 9
call data2LCD ;
movlw SIGN_ON_10 ; digit 10
call data2LCD ;
movlw SIGN_ON_11 ; digit 11
call data2LCD ;
movlw SIGN_ON_12 ; digit 12
call data2LCD ;
movlw SIGN_ON_13 ; digit 13
call data2LCD ;
movlw SIGN_ON_14 ; digit 14
call data2LCD ;
movlw SIGN_ON_15 ; digit 15
call data2LCD ;
movlw SIGN_ON_16 ; digit 16
call data2LCD ;
call wait_a_sec ; Wait one second
return
;
; *******************************************************************************
; * *
; * Purpose: Delay routines *
; * *
; *******************************************************************************
;
wait_a_sec ;PIC Time Delay = 0.99999900 s with Osc = 4000000 Hz
movlw D'6'
movwf CounterC
movlw D'19'
movwf CounterB
movlw D'172'
movwf CounterA
loop
decfsz CounterA,f
goto loop
decfsz CounterB,f
goto loop
decfsz CounterC,f
goto loop
return
wait_100us ;PIC Time Delay = 0.00009800 s with Osc = 4MHz
movlw D'31'
movwf CounterA
loop2
decfsz CounterA,1
goto loop2
return
wait ; Enter with 'w' holding number of times to execute 1mS delay routine
movwf timer1 ; Set up counter
call wait_1ms ; Go to wait loops
decfsz timer1,f
goto $-2
return
wait_1ms ;PIC Time Delay = 0.00099800 s with Osc = 4MHz
movlw D'2'
movwf CounterD
movlw D'74'
movwf CounterE
loop1
decfsz CounterE,f
goto loop1
decfsz CounterD,f
goto loop1
return
;
org 0xe00
;note, dead band incorporated into table
DW 0,0,0,0,0,5,11,16,22,27,33,39,44,50,55,61,67,72,78,83,89
DW 95,100,106,111,117,123,128,134,139,145,151,156,162,167,173,178
DW 184,190,195,201,206,212,218,223,229,234,240,246,251,257,262,268
DW 274,279,285,290,296,302,307,313,318,324,329,335,341,346,352,357
DW 363,369,374,380,385,391,397,402,408,413,419,425,430,436,441,447
DW 453,458,464,469,475,480,486,492,497,503,508,514,520,525,531,536
DW 542,548,553,559,564,570,576,581,587,592,598,604,609,615,620,626
DW 631,637,643,648,654,659,665,671,676,682,687,693,699,704,710,715
DW 721,727,732,738,743,749,755,760,766,771,777,782,788,794,799,805
DW 810,816,822,827,833,838,844,850,855,861,866,872,878,883,889,894
DW 900,906,911,917,922,928,934,939,945,950,956,961,967,973,978,984
DW 989,995,1001,1006,1012,1017,1023,1029,1034,1040,1045,1051,1057,1062,1068,1073
DW 1079,1085,1090,1096,1101,1107,1112,1118,1124,1129,1135,1140,1146,1152,1157,1163
DW 1168,1174,1180,1185,1191,1196,1202,1208,1213,1219,1224,1230,1236,1241,1247,1252
DW 1258,1263,1269,1275,1280,1286,1291,1297,1303,1308,1314,1319,1325,1331,1336,1342
DW 1347,1353,1359,1364,1370,1375,1381,1387,1392,1398,1403,1409,1414,1420,1426,1431
DW 1437,1442,1448,1454,1459,1465,1470,1476,1482,1487,1493,1498,1504,1510,1515,1521
DW 1526,1532,1538,1543,1549,1554,1560,1565,1571,1577,1582,1588,1593,1599,1605,1610
DW 1616,1621,1627,1633,1638,1644,1649,1655,1661,1666,1672,1677,1683,1689,1694,1700
DW 1705,1711,1717,1722,1728,1733,1739,1744,1750,1756,1761,1767,1772,1778,1784,1789
DW 1795,1800,1806,1812,1817,1823,1828,1834,1840,1845,1851,1856,1862,1868,1873,1879
DW 1884,1890,1895,1901,1907,1912,1918,1923,1929,1935,1940,1946,1951,1957,1963,1968
DW 1974,1979,1985,1991,1996,2002,2007,2013,2019,2024,2030,2035,2041,2046,2052,2058
DW 2063,2069,2074,2080,2086,2091,2097,2102,2108,2114,2119,2125,2130,2136,2142,2147
DW 2153,2158,2164,2170,2175,2181,2186,2192,2197,2203,2209,2214,2220,2225,2231,2237
DW 2242,2248,2253,2259,2265,2270,2276,2281,2287,2293,2298,2304,2309,2315,2321,2326
DW 2332,2337,2343,2348,2354,2360,2365,2371,2376,2382,2388,2393,2399,2404,2410,2416
DW 2421,2427,2432,2438,2444,2449,2455,2460,2466,2472,2477,2483,2488,2494,2500,2500
DW 2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500
DW 2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500
DW 2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500
DW 2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500
;
END
Absolutely no point storing it as bytes as they're 14 bit flash words, so still 1 location per entry - I.E. same size.Also, the table could be bytes rather than words,
The code was run (albeit in simulation) on the chip mentioned and referring to the datasheet for that chip. It works.You may need to use different instructions to read the table?
I suspect this was done as an attempt to simplify the code and not an actual requirement.as you need every value a multiple of ten.
That's not a problem, the 10 multiple was a preferred option but this works just as well - the main thing was an even(ish) spread of values.Edit, the values increase by ~5.6 per step, far from the 10 multiple.
And I've never had any problem (bar once) since I started using the busy read with 4 bit interfaces - must have something to do with the obtuseness of animate objectshave NEVER had much luck with busy read on 4 bit interfaces...
; * *
; *******************************************************************************
; * ADC scaling,16x8 multiply & 16x8 divide routines *
; * Plus various other bits of possibly useful bits of code *
; *******************************************************************************
;
;********************************************************************************
;
; Target Controller PIC16F1827
; __________
; ADC-IN-----RA2 |1 18| RA1---------
; -----------RA3 |2 17| RA0---------
; -----------RA4 |3 16| RA7---------
; -----------RA5 |4 15| RA6---------
; Ground----------Vss |5 14| VDD---------+5 V
; LCD D4----------RB0 |6 13| RB7---------
; LCD D5----------RB1 |7 12| RB6---------LCD_rs (LCD Pin 4)
; LCD D6----------RB2 |8 11| RB5---------LCD_rw (LCD Pin 5)
; LCD D7----------RB3 |9 10| RB4---------LCD_e (LCD Pin 6)
; ----------
;
; *******************************************************************************
; * Device type and options *
; *******************************************************************************
;
processor 16F1827
radix dec
errorlevel -207 ; Skip found label after column 1
errorlevel -302 ; Skip out of bank nuisance messages
errorlevel -303 ; Skip program word too large. Truncated to core size
;
; *******************************************************************************
; * Configuration fuse information for 16F1827: *
; *******************************************************************************
;
include <P16F1827.INC>
__CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_LO & _LVP_OFF
;
; *******************************************************************************
; Info for power-up display. Why was it done this way instead of with a table -
; because it is easier for beginners to visualise where the characters will
; appear on the LCD.
SIGN_ON_1 equ ' ' ; Position 1 on LCD - left most position
SIGN_ON_2 equ 'V'
SIGN_ON_3 equ 'K'
SIGN_ON_4 equ '5'
SIGN_ON_5 equ 'T'
SIGN_ON_6 equ 'M'
SIGN_ON_7 equ ' '
SIGN_ON_8 equ 'A'
SIGN_ON_9 equ 'D'
SIGN_ON_10 equ 'C'
SIGN_ON_11 equ ' '
SIGN_ON_12 equ 'T'
SIGN_ON_13 equ 'E'
SIGN_ON_14 equ 'S'
SIGN_ON_15 equ 'T'
SIGN_ON_16 equ ' ' ; Position 16 on LCD - right most position
;
; *******************************************************************************
; * General equates. *
; *******************************************************************************
;
#define center 486 ; For ADC scaling routine
;
; *******************************************************************************
; * Assign names to IO pins. *
; *******************************************************************************
;
LCD_busy equ 0x03 ; LCD busy bit
LCD_e equ 0x04 ; 0=disable, 1=enable
LCD_rw equ 0x05 ; 0=write, 1=read
LCD_rs equ 0x06 ; 0=instruction, 1=data
;
;
; 16F1827 Oscillator setup
; OSCCON - Oscillator control reg.
; ---------------------------------
; SPLLEN b7 enable PLL x4
; 1 = enabled 0 = disabled
; IRCF | b6-3 frequency selection
; 1111 = 16MHz HF
; 1110 = 8 or 32MHz HF
; 1101 = 4MHz HF
; 1100 = 2MHz HF
; 1011 = 1MHz HF
; 1010 = 500kHz HF
; 1001 = 250kHz HF
; 1000 = 125kHz HF
; 0111 = 500kHz MF (default)
; 0110 = 250kHz MF
; 0101 = 125kHz MF
; 0100 = 62.5kHz MF
; 0011 = 31.25kHz HF
; 0010 = 31.25kHz MF
; 000x = 31.25kHz LF
; Reserved B2 reserved, 0
; SCS B1 0-: 1x = int. OSC.
; 01 = Timer1 oscillator
; 00 = determined by FOSC <2:0> in Configuratio
; POR default 00111-00 500 kHz (POR = Power On Reset)
OSCCONVAL EQU b'01101000' ; 4MhZ CLOCK
;
; *******************************************************************************
; * Allocate variables in general purpose register space *
; *******************************************************************************
;
CBLOCK 0x20 ; Start Data Block
TenK
Thou
Hund
Tens
Ones
byte2send ;
LCD_char ; Character being sent to the LCD
rs_value ; The LCD rs line flag value
timer1 ; Used in delay routines
count ; loop counter (gets reused)
CounterA
CounterB
CounterC
CounterD
CounterE
flags
r1
r2
r3
t
ENDC ; End of Data Block
CBLOCK 0x70
NumH
NumL
ENDC ; End of Data Block
;
; *******************************************************************************
; * The 16F1827 resets to 0x00. *
; * The Interrupt vector is at 0x04. *
; *******************************************************************************
;
ORG 0x0000
goto start ; Jump to main program
ORG 0x0004
goto start ; Jump to main program
;
; *******************************************************************************
; * *
; * Purpose: This is the start of the program. *
; * *
; *******************************************************************************
;
start
BANKSEL PORTA
clrf PORTA
clrf PORTB
; Set PIC oscillator frequency
banksel OSCCON ; Select OSCCON
movlw OSCCONVAL ;
movwf OSCCON ; Loads the wanted value
banksel PORTA
; Configures all I / O as digital
Banksel ANSELA
bsf ANSELA,ANSA2 ; set ra2 to analog
clrf ANSELB
; Disable all wakeup pull-ups
Banksel WPUA
clrf WPUA
clrf WPUB
BANKSEL OPTION_REG
clrf OPTION_REG ;
;
movlw b'00110111' ; PORTA (RA0:2,4:5 inputs, RA3,6:7 outputs)
movwf TRISA ;
clrf TRISB ; Set port B to all outputs
movlw b'11000000' ; right justify, FOSC/4 vdd and vss vref
movwf ADCON1 ;
movlw b'00001001' ; select channel an2 & turn adc on
movwf ADCON0 ;
BANKSEL PORTA;
call init_LCD ; Initialize the LCD
call busy_check ; Wait for LCD to finish initialising
call display_version ; Display title and version
;
; *******************************************************************************
; * *
; * Purpose: This is the Main Program Loop. *
; * *
; *******************************************************************************
;
main
movlw 100
call wait ; acquisiton delay & loop delay
BANKSEL ADCON0
bsf ADCON0,ADGO ; start conversion
btfsc ADCON0,ADGO ; is conversion done?
goto $-1 ; no, test again
movf ADRESH,w ; read upper 2 bits
movwf NumH ; store in gpr space
movf ADRESL,w ; read lower 8 bits
movwf NumL ; store in gpr space
movlb 0
call getValue
call bin2BCD
call show_bcd
goto main ; Continue main loop
;--------------------------------------------------------------------------------
; ADC scaling routine
;--------------------------------------------------------------------------------
getValue
;first do ADC-487 to discover direction
bcf flags,0 ; clear the negative flag
movlw high(center)
subwf NumH,f
movlw low(center)
subwf NumL,f
btfss STATUS,C
decf NumH,f
btfss NumH,7 ; is it negative
goto notNeg
;need to negate acc
bsf flags,0 ; set the negative flag
movlw 0xff
xorwf NumL,f
xorwf NumH,f
incf NumL,f
btfsc STATUS,Z
incf NumH,f
notNeg
; 'flags' tells us if above or below center value
;--------------------------------------------------------------------------------
; Multiply by 56 (multiplier is in register 't')
;--------------------------------------------------------------------------------
clrf r3
clrf r2
clrf r1
bsf r1,7 ; used to count to 8
movlw 56 ; value to multiply by
movwf t
mult_loop
rrf t,f
btfss STATUS,C
goto noAdd
movfw NumL
addwf r2,f
movfw NumH
btfsc STATUS,C
incfsz NumH,w ; w = w+1
addwf r3,f
noAdd
rrf r3,f
rrf r2,f ; r2 is high byte of word
rrf r1,f ; r1 is low byte of word
btfss STATUS,C
goto mult_loop
;--------------------------------------------------------------------------------
; Divide by 10 (divisor is in 'w')- remainder is not calculated
;--------------------------------------------------------------------------------
movlw 16
movwf count
movlw 10 ; keep divisor value in accumulator
clrf r3 ; temporary register
divide
rlf r1,f ; shift next msb into temporary
rlf r2,f
rlf r3,f
rlf count,f ; carry has 9th bit of temporary
; copy carry to counter
subwf r3,f ; substract Y (in w) from temporary
skpnc ; if no borrow, set Counter.0
bsf count,0
btfss count,0 ; if Counter.0 clear (borrow) restore temporary
addwf r3,f
clrc ; restore counter
rrf count,f
;at this point carry is the next bit of result
decfsz count,f ; repeat 16 times to find integer part
goto divide
rlf r1,f
rlf r2,f
movfw r2
movwf NumH
movfw r1
movwf NumL
return
;
; *******************************************************************************
; * Takes number in NumH:NumL and returns decimal in TenK:Thou:Hund:Tens:Ones *
; * Fast 16-Bit Binary to Decimal by Peter Hemsley *
; * Input: 16-bit binary in NumH and NumL *
; * Output: Decimal (BCD) digits in TenK,Thou,Hund,Tens,Ones *
; * No temporary variables required *
; * Code size: 46 instructions *
; * Execution time: Variable, approx 150 to 170 cycles *
; *******************************************************************************
;
bin2BCD
Bin2DecFast
movf NumH,w ;Hex Digit 0X00 (H2)
iorlw 0xF0 ;w=H2-16
movwf Ones ;Ones=H2-16
movwf Tens ;Tens=H2-16
addwf Tens,f ;Tens=H2*2-32
addwf Tens,f ;Tens=H2*3-48, C=1
movwf Hund ;Hund=H2-16
rlf Hund,f ;Hund=H2*2-31
swapf NumH,w ;Hex Digit X000 (H3)
iorlw 0xF0 ;w=H3-16
addwf Hund,f ;Hund=H3+H2*2-47 Done!
movwf Thou ;Thou=H3-16
addwf Thou,f ;Thou=H3*2-32
addlw D'52' ;w=H3+36
addwf Ones,f ;Ones=H3+H2+20
swapf NumL,w ;Hex Digit 00X0 (H1)
iorlw 0xF0 ;w=H1-16
addwf Tens,f ;Tens=H2*3+H1-64
addwf Ones,f ;Ones=H3+H2+H1+4, C=1
rlf Ones,f ;Ones=(H3+H2+H1)*2+9, C=0
comf Ones,f ;Ones=-(H3+H2+H1)*2-10
rlf Ones,f ;Ones=-(H3+H2+H1)*4-20
movf NumL,w ;Hex Digit 000X (H0)
andlw 0x0F ;w=H0
addwf Ones,f ;Ones=H0-(H3+H2+H1)*4-20 Done!
rlf Tens,f ;C=0, Tens=H2*6+H1*2-128 Done!
movlw D'7'
movwf TenK ;TenK=7
addlw D'3' ;w=10, C=0
rlf Thou,f ;Thou=H3*4-64 Done!
mod0
addwf Ones,f ;D(X)=D(X)mod10
decf Tens,f ;D(X+1)=D(X+1)+D(X)div10
skpc
goto mod0
mod1
addwf Tens,f
decf Hund,f
skpc
goto mod1
mod2
addwf Hund,f
decf Thou,f
skpc
goto mod2
mod3
addwf Thou,f
decf TenK,f
skpc
goto mod3
return
;
; *******************************************************************************
; * Display data on the LCD. *
; *******************************************************************************
;
show_bcd
movlw 0xC1 ; Point the LCD to digit location
call cmnd2LCD ; Send digit location to LCD
; movf Thou,f ; Test if 'file'is 0 or 1
; btfss STATUS,Z ; The Z or Zero bit is set to "1" when the result
; goto not_zero ; of an arithmetic or logical operation is zero
;
; movlw ' ' ; Thou = 0, insert space
; call data2LCD ; Send byte in W to LCD
; goto show_Hund
movfw TenK ; Thou is not 0, insert number
addlw 0x30 ; Convert to ASCII character
call data2LCD ; Send to LCD - rinse and repeat until all characters sent
not_zero
movfw Thou ; Thou is not 0, insert number
addlw 0x30 ; Convert to ASCII character
call data2LCD ; Send to LCD - rinse and repeat until all characters sent
show_Hund
movfw Hund
addlw 0x30
call data2LCD
movfw Tens
addlw 0x30
call data2LCD
movfw Ones
addlw 0x30
call data2LCD
return
;
; *******************************************************************************
; * *
; * Purpose: Send Command or Data byte to the LCD *
; * Entry point cmnd2LCD: Send a Command to the LCD *
; * Entry Point data2LCD: Send a Data byte to the LCD *
; * *
; * Input: W has the command or data byte to be sent to the LCD. *
; * *
; *******************************************************************************
;
cmnd2LCD ; ****** Entry point for commands ******
clrf rs_value ; Remember to clear RS (clear rs_value)
goto write2LCD ; Go to common code
data2LCD ; ****** Entry point for data ********
bsf rs_value,0 ; Remember to set RS (set bit 0 of rs_value)
write2LCD
movwf LCD_char ; Save byte to write to LCD
call busy_check ; Check to see if LCD is ready for new data
movlw 2 ;
movwf count ; SET UP LOOP COUNTER
write2LCD2
swapf LCD_char,f ; SWAP MS & LS NIBBLES
movf LCD_char,w
andlw 15 ; MAKE TOP 4 BITS OF W 0
movwf PORTB ; SEND MS NIBBLE
bcf PORTB,LCD_rs ; Guess RS should be clear - command mode
btfsc rs_value,0 ; Should RS be clear? (is bit 0 == 0?)
bsf PORTB,LCD_rs ; No, set RS - data mode
nop
bsf PORTB,LCD_e ; SET E HIGH
nop
bcf PORTB,LCD_e ; SET E LOW
decfsz count,F
goto write2LCD2 ; GO BACK AND SEND LS NIBBLE
return
;
; *******************************************************************************
; * *
; * Purpose: Check if LCD is done with the last operation. *
; * This subroutine polls the LCD busy flag to determine if *
; * previous operations are completed. *
; * *
; *******************************************************************************
;
busy_check
clrf PORTB ; Clear all outputs on PORTB
banksel TRISB ; Switch to bank for Tris operation
movlw b'00001000' ; Set RB3 input, others outputs
movwf TRISB ;
banksel PORTB
bcf PORTB,LCD_rs ; Set up LCD for Read Busy Flag (RS = 0)
nop
bsf PORTB,LCD_rw ; Set up LCD for Read (RW = 1)
LCD_is_busy
bsf PORTB,LCD_e ; Set E high
nop
bcf PORTB,LCD_e ; Drop E again
btfss PORTB,LCD_busy ; Is Busy Flag (RB3) clear?
goto not_busy ; Yes - exit
nop ; No
nop ; Wait a while
bsf PORTB,LCD_e ; Pulse E high (dummy read of lower nibble),
nop ; wait,
bcf PORTB,LCD_e ; and drop E again
goto LCD_is_busy ; If not, it is busy so jump back
not_busy
banksel TRISB ; Switch to bank 1 for Tristate operation
clrf TRISB ; All pins (RB7..RB0) are back to outputs
banksel PORTB ; Switch to bank 0
clrf PORTB ; Clear all of Port B (inputs and outputs)
return ;
;
;
; *******************************************************************************
; * *
; * Purpose: Power on initialization of Liquid Crystal Display. The LCD *
; * controller chip must be equivalent to an Hitachi 44780. *
; * *
; *******************************************************************************
;
init_LCD
movlw 100
call wait ; Wait for LCD to power up
; Put 4-bit command on RB3..RB0
; PIC's RB3..RB0 lines connect to LCD's DB7..DB4 lines
movlw 0x03 ; LCD init instruction (First)
movwf PORTB ; Send to LCD via RB3..RB0
bsf PORTB,LCD_e ; Set the LCD E line high,
movlw 100
call wait ; wait a "long" time,
bcf PORTB,LCD_e ; and then Clear E
movlw 0x03 ; LCD init instruction (Second)
movwf PORTB ; Send to LCD via RB3..RB0
bsf PORTB,LCD_e ; Set E high,
movlw 32
call wait ; wait a while,
bcf PORTB,LCD_e ; and then Clear E
movlw 0x03 ; LCD init instruction (Third)
movwf PORTB ; Send to LCD via RB3..RB0
bsf PORTB,LCD_e ; Set E high,
movlw 32
call wait ; wait a while,
bcf PORTB,LCD_e ; and then Clear E
movlw 0x02 ; 4-bit mode instruction
movwf PORTB ; Send to LCD via RB3..RB0
bsf PORTB,LCD_e ; Set E high,
movlw 16
call wait ; wait a while,
bcf PORTB,LCD_e ; and then Clear E
movlw 0x28 ; 1/16 duty cycle, 5x8 matrix
call cmnd2LCD ; Send command in w to LCD
movlw 0x08 ; Display off, cursor and blink off
call cmnd2LCD ; Send command to LCD
movlw 0x01 ; Clear and reset cursor
call cmnd2LCD ; Send command in w to LCD
movlw 0x06 ; Set cursor to move right, no shift
call cmnd2LCD ; Send command in w to LCD
movlw 0x0E ; Display on, cursor on and blink off
; movlw 0x0F ; Display on, cursor on and blink on
; movlw 0x0C ; Display on, cursor and blink off
call cmnd2LCD ; Send command in w to LCD
return ;
;
; *******************************************************************************
; * *
; * Function: clear_lcd *
; * *
; * Purpose: Clears the LCD and homes the cursor. *
; * *
; *******************************************************************************
;
clear_lcd
movlw 0x01 ; Prepare to display a new message on LCD
call cmnd2LCD ; by clearing the current one
return
;
; *******************************************************************************
; * *
; * Purpose: Display version and other info on LCD for 1 second *
; * upon power-up *
; * *
; * Input: SIGN_ON_1 through SIGN_ON_16 *
; * *
; * Output: LCD displays info *
; * *
; *******************************************************************************
;
display_version
call clear_lcd
movlw SIGN_ON_1 ; digit 1
call data2LCD ;
movlw SIGN_ON_2 ; digit 2
call data2LCD ;
movlw SIGN_ON_3 ; digit 3
call data2LCD ;
movlw SIGN_ON_4 ; digit 4
call data2LCD ;
movlw SIGN_ON_5 ; digit 5
call data2LCD ;
movlw SIGN_ON_6 ; digit 6
call data2LCD ;
movlw SIGN_ON_7 ; digit 7
call data2LCD ;
movlw SIGN_ON_8 ; digit 8
call data2LCD ;
movlw SIGN_ON_9 ; digit 9
call data2LCD ;
movlw SIGN_ON_10 ; digit 10
call data2LCD ;
movlw SIGN_ON_11 ; digit 11
call data2LCD ;
movlw SIGN_ON_12 ; digit 12
call data2LCD ;
movlw SIGN_ON_13 ; digit 13
call data2LCD ;
movlw SIGN_ON_14 ; digit 14
call data2LCD ;
movlw SIGN_ON_15 ; digit 15
call data2LCD ;
movlw SIGN_ON_16 ; digit 16
call data2LCD ;
; call wait_a_sec ; Wait one second
nop ; for sim
return
;
; *******************************************************************************
; * *
; * Purpose: Delay routines *
; * *
; *******************************************************************************
;
wait_a_sec ;PIC Time Delay = 0.99999900 s with Osc = 4000000 Hz
movlw D'6'
movwf CounterC
movlw D'19'
movwf CounterB
movlw D'172'
movwf CounterA
loop
decfsz CounterA,f
goto loop
decfsz CounterB,f
goto loop
decfsz CounterC,f
goto loop
return
wait_100us ;PIC Time Delay = 0.00009800 s with Osc = 4MHz
movlw D'31'
movwf CounterA
loop2
decfsz CounterA,1
goto loop2
return
wait ; Enter with 'w' holding number of times to execute 1mS delay routine
movwf timer1 ; Set up counter
call wait_1ms ; Go to wait loops
decfsz timer1,f
goto $-2
return
wait_1ms ;PIC Time Delay = 0.00099800 s with Osc = 4MHz
movlw D'2'
movwf CounterD
movlw D'74'
movwf CounterE
loop1
decfsz CounterE,f
goto loop1
decfsz CounterD,f
goto loop1
return
;
END