; ; Ventilator - Start project - 8 April 2020 - ; Current version 15 April 2020 - ;_____________________________________________________________________ list p=16f1718 ; list directive to define processor #include #include "p16f1718.inc" ;------------------------------------------------------------------------------ ; CONFIGURATION WORD SETUP ;------------------------------------------------------------------------------ __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF __CONFIG _CONFIG2, _WRT_OFF & _STVREN_OFF & _BORV_HI & _LVP_OFF ;------------------------------------------------------------------------------ ; VARIABLE DEFINITIONS ;------------------------------------------------------------------------------ #define BANK0 0x00 #define BANK1 0x80 #define BANK2 0x100 CBLOCK 0x20 ; Define GPR variable register locations ; User variables allocated contiguously appo appo2 fanSpeed maxKpa pressMed nloop ngir LedTrigCnt startPre MotorVoltage downspeed end_bank_0_vars:0 endc if end_bank_0_vars > 0x70 error "Bank0 variable space overrun" endif CBLOCK 0x20 ; Define bank 1 variable register locations end_bank_1_vars:0 endc if end_bank_1_vars > 0x70 error "Bank1 variable space overrun" endif CBLOCK 0x70 ; Common RAM (16 byte comuni a tutti i banchi) Stato Stato2 Stato3 AdcLSB AdcMSB delay1 delay2 delay3 delay4 cbing0 cbing1 prodLo prodHi end_global_vars:0 endc if end_global_vars > 0x80 error "Global variable space overrun" endif ;---------- LEDINALA EQU 0 ; RA out LEDESALA EQU 1 ; RA out LEDTRIG EQU 2 ; RA out LEDTRIGTIME EQU 3 ; RA out ;---------- beeperA EQU 4 ; RB out beeperB EQU 5 ; RB out ;---------- BRAKE EQU 1 ; RC out MOTORE EQU 2 ; RC out PRESSURE EQU 3 ; RC AN15 in POTINALA EQU 4 ; RC AN16 in POTESALA EQU 5 ; RC AN17 in POTTRIG EQU 6 ; RC AN18 in POTPRESS EQU 7 ; RC AN19 in ;------------------------------------------------------------------------------ ; RESET VECTOR ;------------------------------------------------------------------------------ ; code 0x00 ORG 0x0000 ; processor reset vector pagesel $ GOTO init ; When using debug header, first inst. ; may be passed over by ICD2. ;------------------------------------------------------------------------------ ; INTERRUPT SERVICE ROUTINE ;------------------------------------------------------------------------------ ORG 0x0004 banksel 0 RETFIE ; return from interrupt ;------------------------------------------------------------------------------ ; ENTRY PROGRAM ;------------------------------------------------------------------------------ init ;===================================================================================================== ;===================================================================================================== call Osc16Mhz banksel WDTCON movlw b'00010011' ; 512 mS watchdog movwf WDTCON banksel OPTION_REG movlw b'01111111' movwf OPTION_REG ; abilita i pull-up separati banksel T1CON ; movlw b'00110100' ; TMR1= instruction clock, prescaler 1:8, no ext ck, OFF movwf T1CON ; BANKSEL WPUA CLRF WPUA ; Set RA no pull-up ; BANKSEL TRISA ; MOVLW B'00000000' ; Set RA as output MOVWF TRISA ; BANKSEL ANSELA ; MOVLW B'00000000' ;Set RA as digital MOVWF ANSELA ; BANKSEL WPUB CLRF WPUB ; Set RB no pull-up ; BANKSEL TRISB ; MOVLW B'00000000' ; Set RB 0 output MOVWF TRISB ; BANKSEL ANSELB ; MOVLW B'00000000' ; Set RB as digital MOVWF ANSELB ; BANKSEL WPUC CLRF WPUC ; Set RC no pull-up ; BANKSEL TRISC ; MOVLW B'11111000' ;Set RC 3,4,5,6,7 input MOVWF TRISC BANKSEL ANSELC ; MOVLW B'11111000' ;Set RC 3-7 analogical MOVWF ANSELC ; banksel 0 ; _______________________ FINE SET REGISTRI __________ call BRAKE_OFF call MOTORE_OFF call LEDTRIGTIME_OFF call LEDINALA_OFF call LEDESALA_OFF call LEDTRIG_OFF call PWMinit call beep call delay100mS call beep call delay1Sec ;______________________________________________________________________________ ;______________________________________________________________________________ ;______________________________________________________________________________ ;______________________________________________________________________________ ;______________________________________________________________________________ StartCycle: ;____________________________________ INSPIRATION _____________________________________________ call LEDINALA_ON call R_POTINALA ; read Pot IN value movwf nloop lsrf nloop,f ; IN/2 : 0 -> 127 call StartingFan ; set Speed Fan to a fraction value of Pressure setting movlw 80 addwf nloop ; min_Pot =80 max_Pot =207 ;______________________________ loopIn: call delayed_ledTrigOff call SkpIncFanSpeed ; ramp value of fanspeed (to 128) goto endUpRamp ; if reached max speed jump lslf fanspeed,w ; x2 speed to W call WsetMotor ; set motor voltage ; test if pressure greater preset call SetMaxKPa ; set maxKPa based on PRESSURE POT position call PRESS4toW ; read pressure in W 255 = 25 cm H2O subwf maxKPa,w skpc bsf fanspeed,7 ; set end ramp movfw MotorVoltage ; Store current value movwf downspeed ; in downspeed goto endloopIn endUpRamp: ; btfss nloop,0 ; goto endloopIn ; only odd cycle call PRESS4toW ; read pressure in W 255 = 25 cm H2O subwf maxKPa,w skpnc goto endloopIn decf downspeed,f movfw downspeed skpnz ; test underflow incf downspeed,f movfw downspeed call WsetMotor ; set motor voltage endloopIn: clrwdt call delay8mS decfsz nloop,f goto loopIn ;_______________________________________ BRAKE FAN ____________________________________________ movlw 0 call WsetMotor call delay1mS ; wait for PWM end call LEDESALA_ON call BRAKE_ON ; short cicuit on motor termninal call delay500mS call delay500mS call BRAKE_OFF call LEDINALA_OFF ;________________________________________ EXPIRATION ________________________________________ ; ________ 1 to 4 sec movlw 30 ; Idle Speed call WsetMotor movlw 55 movwf nloop call delay500mS dEsa call R_POTESALA ; Timer call wdelay clrwdt decfsz nloop,f goto dEsa ;________________________________ Store Reference Pressure ________________________________________ call PRESS4toW movwf pressmed ;__________________________________ Test Trigger for negative pressure ________________________________________ call LEDTRIGTIME_ON call R_POTTRIG movwf nloop skpnz goto exinala lsrf nloop,f ; /2 : 0 -> 127 movlw 43 addwf nloop,f testInal: clrwdt call delay20mS call delay3mS call PRESS4toW ; compare pressure value subwf pressMed,w ; with reference pressure stored skpc goto nextL skpnz goto nextL andlw 0xfc ; trigger sensivity ( 0xff max, 0xfe, 0xfc, 0xf8, 0xf0 min ) skpz ; if enough lower than reference value goto startTrig ; end EXPIRATION fase nextL decfsz nloop,f goto testInal call beep ; alarm not trigger detect! exinala: call LEDESALA_OFF call LEDTRIGTIME_OFF goto startcycle ;__________________________________________________________________ startTrig: call LEDTRIGTIME_OFF movlw 10 movwf LedTrigCnt call LEDTRIG_ON goto StartCycle ;______________________________________________________________________________ ;______________________________________________________________________________ ;______________________________________________________________________________ ;______________________________________________________________________________ SkpIncFanSpeed: incf fanspeed,f btfsc fanspeed,7 ; stop on end ramp (128) bcf fanspeed,0 btfss fanspeed,7 ; test end ramp (128) call incStack ; not skp on return if end ramp return ;________________________ delayed_ledTrigOff: decf LedTrigCnt skpnz call LEDTRIG_OFF ; Led Trig Pulse Off return ;_________________________________________________ StartingFan: call PressSetToW ; read Pot Pressure value movwf startPre ; Pressure/4 : 0 -> 31 lsrf startPre,f lsrf startPre,f lsrf startPre,w addlw 50 ; starting value from 50 to 81 movwf fanspeed call WsetMotor return ;_________________________________________________ SetMaxKPa: call PressSetToW movwf maxKPa return PressSetToW: ; (from 25 to 152) call R_POTPRESS lsrf AdcMSB,w ; pot/2 addlw 25 return ;_________________________________________________ PRESS4toW: ; 10 bit pressure reading call R_PRESSURE btfsc AdcMSB,7 goto Over25Kpa btfsc AdcMSB,6 goto Over25Kpa rlf AdcLSB,f rlf AdcMSB,f rlf AdcLSB,f rlf AdcMSB,w return Over25Kpa movlw 255 return ;_________________________________________________ WSetMotor: movwf MotorVoltage banksel CCPR1L movwf CCPR1L banksel 0 return PWMinit: banksel TRISC bsf TRISC,2 banksel RC2PPS movlw b'00001100' ; CCP1 to PORTC movwf RC2PPS banksel 0 movlw 255 movwf PR2 banksel CCP1CON movlw b'00001100' ; setup PWM about 4 Khz movwf CCP1CON movwf CCPR1L banksel 0 movlw 20 movwf TMR2 ; Using TMR2 as a PWM Generator clrf T2CON ; Select Prescaler as 16 bsf T2CON,T2CKPS0 ; PWM a circa 4 Khz. bsf T2CON,TMR2ON ; start TMR2 banksel TRISC bcf TRISC,2 banksel 0 return ;___________________________________________________________________________________________________________ ;_________________________________________ Osc16Mhz movlw b'01111010' ;16 MHz MFosc bra Oscill Osc32Khz movlw b'00000010' ;32Khz MFosc Oscill banksel OSCCON movwf OSCCON banksel 0 return ;_____________________ u1200 call u600 ; delay 1200uS con chiamata e ritorno ecc u600 call u300 ; delay 600uS con chiamata e ritorno ecc u300 call u150 ; delay 300uS con chiamata e ritorno ecc u150 movlw 200 ; delay 150uS con chiamata e ritorno ecc bra uw u100 movlw 132 ; delay 100uS con chiamata e ritorno ecc bra uw u50 movlw 66 ; delay 50uS con chiamata e ritorno ecc bra uw uw movwf delay1 decfsz delay1,f goto $-1 return ; wdelay: ; ritardo da 0 a 20 mS in funzione di w movwf delay2 skpnz return clrf delay1 decfsz delay1,f goto $-1 decfsz delay2,f goto $-3 return ;______________________________________ delay1sec movlw 100 ddd movwf delay3 lm clrwdt call delay10mS decfsz delay3, f bra lm return delay1000mS movlw 100 bra ldy delay500mS movlw 50 bra ldy delay400mS movlw 40 bra ldy delay200mS movlw 20 bra ldy delay100mS movlw 10 bra ldy delay30mS movlw 3 bra ldy delay50mS movlw 5 ldy movwf delay3 lx clrwdt call delay10mS decfsz delay3, f bra lx return delay20mS movlw 200 goto delay01mS delay10mS movlw 100 goto delay01mS delay8mS movlw 80 goto delay01mS delay6mS movlw 60 goto delay01mS delay3mS movlw 30 goto delay01mS delay1mS movlw 10 goto delay01mS delay01mS movwf delay2 call u100 decfsz delay2, f goto $-2 return SampleDelay movlw 50 movwf delay2 decfsz delay2, f goto $-1 return ;--------------------- Lettura DAC ----------------------------- R_PRESSURE: movlw b'00111101' ; AN15 goto Acquire R_POTPRESS: movlw b'01000001' ; AN16 goto Acquire R_POTTRIG: movlw b'01000101' ; AN17 goto Acquire R_POTESALA: movlw b'01001001' ; AN18 goto Acquire R_POTINALA: movlw b'01001101' ; AN19 goto Acquire leggiDAC: movlw b'01111001' goto Acquire leggiFixV: movlw b'01111101' goto Acquire ;______________ Acquire: banksel ADCON0 movwf ADCON0 ; configure A2D for Channel, Left justified, and turn on the A2D module BANKSEL ADCON1 ; Dati 8 bit in ADRESH e 2 in ADRESL MOVLW B'01110000' ; Rif. Voltage VDT, OSC RC MOVWF ADCON1 ; and clock AD = clk/32 banksel 0 call SampleDelay ; wait almeno 5uS for A2D amp to settle and capacitor to charge. banksel ADCON0 bsf ADCON0,ADGO ; start conversion nop btfsc ADCON0,ADGO ; this bit will change to zero when the conversion is complete goto $-1 banksel ADRESL movfw ADRESL ; carica gli Lsb del risultato movwf AdcLSB ; in memoria movfw ADRESH ; carica i bit Msb movwf AdcMSB ; in memoria banksel 0 return ;____________________________ SEGNALI ACUSTICI _________________ beep: movlf 50,delay2 ; durata del beep bra faibeepNorm beepino: movlf 10,delay2 ; durata del beep bra faibeepNorm beepone: clrf delay2 call faibeepNorm call faibeepNorm beepNorm: ; freq. norm call faibeepNorm call delay100mS return faibeepMeno: movlf 220,delay3 bra faibeep faibeepPiu: movlf 185,delay3 bra faibeep faibeepNorm: movlf 200,delay3 faibeep: ; fa un beep di durata delay2 e frequenza delay3 (typ.150) banksel LATB bsf LATB,beeperA bcf LATB,beeperB movfw delay3 call uw clrwdt banksel LATB bcf LATB,beeperA bsf LATB,beeperB movfw delay3 call uw decfsz delay2,f bra faibeep banksel 0 return ;_____________________________ SEGNALI LUMINOSI _________________ LEDTRIGTIME_ON: banksel LATA bsf LATA,LEDTRIGTIME banksel 0 return LEDTRIGTIME_OFF: banksel LATA bcf LATA,LEDTRIGTIME banksel 0 return LEDINALA_ON: banksel LATA bsf LATA,LEDINALA banksel 0 return LEDINALA_OFF: banksel LATA bcf LATA,LEDINALA banksel 0 return LEDTRIG_ON: banksel LATA bsf LATA,LEDTRIG banksel 0 return LEDTRIG_OFF: banksel LATA bcf LATA,LEDTRIG banksel 0 return LEDESALA_ON: banksel LATA bsf LATA,LEDESALA banksel 0 return LEDESALA_OFF: banksel LATA bcf LATA,LEDESALA banksel 0 return MOTORE_ON: banksel LATC bsf LATC,MOTORE banksel 0 return MOTORE_OFF: banksel LATC bcf LATC,MOTORE banksel 0 return BRAKE_ON: banksel LATC bsf LATC,BRAKE banksel 0 return BRAKE_OFF: banksel LATC bcf LATC,BRAKE banksel 0 return ;_________________________________________________________________________________________________ IncStack: ; non tocca il CARRY dello STATUS ne W banksel STKPTR decf STKPTR,f ; sposta il puntatore dello stack al precedente return incf TOSL,f ; incrementa l'indirizzo skpnz incf TOSH,f incf STKPTR,f ; riposiziona il puntatore dello stack all'ultimo return banksel 0 return goto init END