Code:
'****************************************************************'* Name : MAX30102 FOR PIC 18 DEMO *
'* Author : Richard *
'* Notice : *
'* : *
'* Date : 9/1/2022 *
'* Version : 1.0 *
'* Notes : MAX30102 *
'* :18f26k22 @64Mhz *
'****************************************************************
#CONFIG ; The PBP configuration for the PIC18F26K22 is:
CONFIG FOSC = INTIO67
CONFIG PLLCFG = OFF ;Oscillator multiplied by 4
CONFIG PRICLKEN = ON ;Primary clock enabled
CONFIG FCMEN = OFF ;Fail-Safe Clock Monitor disabled
CONFIG IESO = OFF ;Oscillator Switchover mode disabled
CONFIG BOREN = SBORDIS ; Brown-out Reset enabled in hardware only (SBOREN is disabled)
CONFIG WDTEN = ON ; WDT is always enabled. SWDTEN bit has no effect ;|
CONFIG WDTPS = 32768 ; 1:32768 ---> HERE enable the watchdog timer with a 1:32768 postscale;|
CONFIG PWRTEN = ON
CONFIG HFOFST = ON ; HFINTOSC output and ready status are not delayed by the oscillator stable status
CONFIG MCLRE = EXTMCLR ; MCLR pin enabled, RE3 input pin disabled
CONFIG LVP = OFF ; Single-Supply ICSP disabled
CONFIG XINST = OFF ; Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
CONFIG DEBUG = OFF ; Disabled
CONFIG CP0 = OFF ; Block 0 (000800-003FFFh) not code-protected
CONFIG CP1 = OFF ; Block 1 (004000-007FFFh) not code-protected
CONFIG CP2 = OFF ; Block 2 (008000-00BFFFh) not code-protected
CONFIG CP3 = OFF ; Block 3 (00C000-00FFFFh) not code-protected
CONFIG CPB = OFF ; Boot block (000000-0007FFh) not code-protected
CONFIG CPD = OFF ; Data EEPROM not code-protected
CONFIG WRT0 = OFF ; Block 0 (000800-003FFFh) not write-protected
CONFIG WRT1 = OFF ; Block 1 (004000-007FFFh) not write-protected
CONFIG WRT2 = OFF ; Block 2 (008000-00BFFFh) not write-protected
CONFIG WRT3 = OFF ; Block 3 (00C000-00FFFFh) not write-protected
CONFIG WRTC = OFF ; Configuration registers (300000-3000FFh) not write-protected
CONFIG WRTB = OFF ; Boot Block (000000-0007FFh) not write-protected
CONFIG WRTD = OFF ; Data EEPROM not write-protected
CONFIG EBTR0 = OFF ; Block 0 (000800-003FFFh) not protected from table reads executed in other blocks
CONFIG EBTR1 = OFF ; Block 1 (004000-007FFFh) not protected from table reads executed in other blocks
CONFIG EBTR2 = OFF ; Block 2 (008000-00BFFFh) not protected from table reads executed in other blocks
CONFIG EBTR3 = OFF ; Block 3 (00C000-00FFFFh) not protected from table reads executed in other blocks
CONFIG EBTRB = OFF ; Boot Block (000000-0007FFh) not protected from table reads executed in other blocks
#ENDCONFIG
goto overasm
asm
PutMulResult?D macro Din
MOVE?BB Din, R2
MOVE?BB Din + 1, R2 + 1
MOVE?BB Din + 2, R0
MOVE?BB Din + 3, R0 + 1
RST?RP
endm
endasm
overasm:
define OSC 64
OSCCON = %01110000 ; 16Mhz
OSCTUNE.6 = 1 ; Enable 4x PLL
while ! osccon2.7 :WEND ; to make sure the pll has stabilised before you run any other code
TRISC = %11011000
ANSELC=0
ANSELB=0
#DEFINE DEBUGING 1
DEFINE DEBUG_REG PORTB
DEFINE DEBUG_BIT 7
DEFINE DEBUG_BAUD 9600
DEFINE DEBUG_MODE 0
SDA var portc.4
SCL VAR portc.3
reg var BYTE
fifo var byte[6] bank0
addr var byte
REVISION var byte
PARTID var byte
buffer var word[384]
ptr var byte
btr var byte
index var word
average var byte[4] bank0
ave var word
peaks var byte[8]
lastpeak var word
lastlow var word
lpfdata var word[192]
result var word ext
result1 var word ext
pulse var word
@result = _fifo
@result1 = _fifo + 3
;----------------------- REGISTER -------------------------
REG_TEMP_INT con $1F
REG_TEMP_FRAC con $20
REG_TEMP_CONFIG con $21
REG_PART_REVISION con $FE
REG_MODE con $09
REG_SPO2_CONFIG con $0A ;SPO2_ADC_RGE[6:5]SPO2_SR[4:2]LED_PW[1:0]
REG_LED1_PA con $0C
REG_LED2_PA con $0D
FIFO_WR_PTR con $04 ;FIFO_WR_PTR[4:0]
FIFO_RD_PTR con $06
FIFO_DATA con $07
FIFO_CONFIG con $08 ;FIFO_A_FULL[3:0] SMP_AVE[7:5]
OVF_COUNTER con $05
STATUS1 con 0 ;A_FULL[7]
INTERRUPT_EN con 2
' -----------------------------------------------------------------------------|
#IFDEF DEBUGING
LATB.7=1
PAUSE 2000
DEBUG 13,10, "READY"
#ENDIF
ADDR = $ae ; addr is 0x57 << 1
reg = REG_PART_REVISION
i2cread SDA,scl,ADDR,reg,[REVISION,PARTID]
reg = REG_MODE
i2cwrite SDA,scl,ADDR,reg,[3]
reg = REG_SPO2_CONFIG
i2cwrite SDA,scl,ADDR,reg,[$20]
reg = REG_LED2_PA
i2cwrite SDA,scl,ADDR,reg,[10]
reg = REG_LED1_PA
i2cwrite SDA,scl,ADDR,reg,[10]
reg = FIFO_CONFIG
i2cwrite SDA,scl,ADDR,reg,[16]
reg = INTERRUPT_EN
i2cwrite SDA,scl,ADDR,reg,[$E0]
DEBUG 13,10, "PART ID: 0X",hex PARTID,"/0X",hex REVISION
start:
reg= REG_TEMP_CONFIG
i2cwrite SDA,scl,ADDR,reg,[1]
reg= REG_TEMP_INT
i2cread sda,scl,ADDR,reg,[fifo[0],fifo[1]]
DEBUG 13,10, "TEMP: ",DEC fifo[0],".",DEC2( fifo[1]<<6)
GOSUB AQUIRE
pause 2000
goto start
aquire:
index=0
reg= FIFO_WR_PTR
i2cwrite SDA,scl,ADDR,reg,[0]
reg= FIFO_RD_PTR
i2cwrite SDA,scl,ADDR,reg,[0]
reg = OVF_COUNTER
i2cwrite sda,scl,ADDR,reg,[0]
asm
banksel 0
clrf _average
clrf _average+1
clrf _average+2
clrf _average+3
endasm
while index <256
btr = 0
reg = STATUS1
WHILE (btr & 192) = 0
i2cread sda,scl,ADDR,reg,[btr]
WEND
reg = FIFO_WR_PTR
i2cread SDA,scl,ADDR,reg,[Ptr]
reg = FIFO_RD_PTR
i2cread SDA,scl,ADDR,reg,[btr]
btr = (ptr - btr) & 31
WHILE (btr && (index < 256))
reg = FIFO_DATA ;---------ir----------;===========red===========
i2cread sda,scl,ADDR,reg,[FIFO[2],FIFO[1],FIFO[0],FIFO[5],FIFO[4],FIFO[3]]
asm ;ROTATE READING TO GET SUFFICIENT RESOLOUTION INTO lower WORD
banksel 0
bcf STATUS,C
RRCF _fifo + 2 ,f
RRCF _fifo + 1 ,f
RRCF _fifo ,f
bcf STATUS,C
RRCF _fifo + 2 ,f
RRCF _fifo + 1 ,f
RRCF _fifo ,f
bcf STATUS,C
RRCF _fifo + 5 ,f
RRCF _fifo + 4 ,f
RRCF _fifo + 3 ,f
bcf STATUS,C
RRCF _fifo + 5 ,f
RRCF _fifo + 4 ,f
RRCF _fifo + 3 ,f
movf _fifo ,w ;RED AVERAGE
addwf _average,f
movf _fifo + 1 ,w
btfsc STATUS,C
incfsz _fifo + 1 ,w
addwf _average + 1,f
btfsc STATUS,C
incf _average + 2,f
endasm
buffer[index] = result ;ir
index = index + 1
buffer[index] = result1 ;red
index = index + 1
btr = btr - 1
WEND
wend
DEBUG 13,10,hex2 average[3],hex2 average[2],hex2 average[1],hex2 average
@ PutMulResult?D _average ;RED AVERAGE
ave = DIV32 128 ;RED AVERAGE
reg = OVF_COUNTER
i2cread sda,scl,ADDR,reg,[reg ]
DEBUG 13,10,"OverFlows ",DEC reg,9,dec ave,9,hex ave
FOR index = 0 TO 255 step 2
ave = (ave ** 57000) + (buffer[index] ** 8535 )
lpfdata[index>>1]=ave
;.....lpf..;;;;----red-----;;;;======-ir-========
DEBUG 13,10,dec ave,9,dec buffer[index],9,dec buffer[index+1]
NEXT
' RETURN
lastpeak = lpfdata[0]
lastlow = lpfdata[0]
asm
banksel _peaks
clrf _peaks
clrf _peaks+1
clrf _peaks+2
clrf _peaks+3
clrf _peaks+4
clrf _peaks+5
clrf _peaks+6
clrf _peaks+7
banksel 0
endasm
DEBUG 13,10,"lpf"
lastpeak = lpfdata[0]
lastlow = lpfdata[0]
for index = 0 TO 31 ;p1
if (lpfdata[index] > lastpeak) then
lastpeak = lpfdata[index]
peaks[4] = index :peaks[5]=index :peaks[6]=index :peaks[7]=index
endif
if (lpfdata[index] < lastlow) then
lastlow = lpfdata[index]
peaks[0] = index :peaks[1]=index :peaks[2]=index :peaks[3]=index
endif
NEXT
lastpeak = lpfdata[32]
lastlow = lpfdata[32]
for index = 32 TO 63 ;p2
if (lpfdata[index] >lastpeak) then
lastpeak = lpfdata[index]
peaks[5] = index :peaks[6]=index :peaks[7]=index
endif
if (lpfdata[index] <lastlow) then
lastlow = lpfdata[index]
peaks[1] = index :peaks[2]=index :peaks[3]=index
endif
NEXT
lastpeak = lpfdata[64]
lastlow = lpfdata[64]
for index = 64 TO 95 ;p3
if (lpfdata[index] >lastpeak) then
lastpeak = lpfdata[index]
peaks[6]= index :peaks[7]=index
endif
if (lpfdata[index] < lastlow) then
lastlow= lpfdata[index]
peaks[2]= index :peaks[3]=index
endif
NEXT
lastpeak = lpfdata[96]
lastlow = lpfdata[96]
for index = 96 TO 127 ;p4
if (lpfdata[index] >lastpeak) then
lastpeak = lpfdata[index]
peaks[7] = index
endif
if (lpfdata[index] <lastlow) then
lastlow = lpfdata[index]
peaks[3] = index
endif
NEXT
DEBUG 13,10,dec peaks[4],9,dec peaks[0];,9, dec lpfdata[peaks[0]]-lpfdata[peaks[1]]
DEBUG 13,10,dec peaks[5],9,dec peaks[1]
DEBUG 13,10,dec peaks[6],9,dec peaks[2]
DEBUG 13,10,dec peaks[7],9,dec peaks[3]
' pulse = 3000/abs( btr-ptr)
' DEBUG 13,10,dec ptr , 9,dec btr , 9,dec pulse
RETURN
Bookmarks