; ;********************************************************************* ; pwmcmd.asm - PWM subruotines for cmd monitor Disti Cert 98 ;********************************************************************* ; ; created 2/28/98 -mls ; modified 3/21/98 -jea ; ;********************************************************************* ; pwm interface functions ;********************************************************************* SetPWM1 ; load percent duty cycle value into pwm1 ;********************************************************************* ; ; install this command in the CmdMenu lookup table CmdPC = $ ; save current inline assembly PC value org CurCmdMenuAdr ; set assembly PC to addr for new entry ; CmdMenu table entry data "PWM1=n\r", CmdPC, "Set pwm1 duty cycle as percent\r\n" CurCmdMenuAdr = $ ; set current CmdMenu addr for next entry org CmdPC ; begin cmd code gen at inline address ; ; This routine accepts a command with a value between 0 and 99 and ; sets the PWM number 1 to that percent duty cycle by writing to ; PW1DCH. Hint: Because the period register was loaded with 99, one ; count is 1%. After the value is written to the register, a ; confirmation message is returned. This message acutally reads the ; duty cycle register and is therefore useful as a stand alone report ; if called at that point. ; call InitPWM1 ; init pwm1 bsf ALUSTA, 7 ; make sure FSR doesn't increment movlw cmdPrmBuff ; load parameter buffer address movwf FSR1 ; into FSR1 movlw .100 ; test if > 100%, if so clip cpfsgt INDF1 ; if cmd value > 100, leave 100 in WREG movfp INDF1, WREG ; else put cmd value in WREG movlb 3 ; set bank for PWM duty cycle control movwf PW1DCH ; and move to duty cycle register ; fall through to display pwm duty cycle ; ;********************************************************************* DspPWM1 ; displays current duty cycle value in pwm1 ;********************************************************************* ; ; install this command in the CmdMenu lookup table CmdPC = $ ; save current inline assembly PC value org CurCmdMenuAdr ; set assembly PC to addr for new entry ; CmdMenu table entry data "PWM1\r", CmdPC, "Read pwm1 duty cycle\r\n" CurCmdMenuAdr = $ ; set current CmdMenu addr for next entry org CmdPC ; begin cmd code gen at inline address ; CpyTbl2Out Pwm1D ; init beginning of output string CpyTbl2Out DcD ; include duty cycle text movlb 3 ; be sure bank 3 still selected movfp PW1DCH, WREG ; move stored % to WREG call Dec2Buf ; convert into output buffer CpyTbl2Out PcD ; add finishing text return ; return from Cmd ; This is the end of the functions executable code ; ; These data statements store constant ascii output strings in program ; memory. They're accessed using the CpyTbl2Buf and CpyTblCont macros ; with the addresses given by the labels. Pwm1D ; constant string for pwm1 display data "\nPWM1", 0 Pwm2D ; constant string for pwm2 display data "\nPWM2", 0 DcD ; constant string for duty cycle display data " Duty Cycle = ", 0 PcD ; constant string for % display data "%\n\r", 0 ; ;********************************************************************* InitPWM1; Initialize the pwm1 peripheral ;********************************************************************* ; ; Instructions: Set up PWM1 to use timer 1. Use the value decimal 99 ; in the period register to facilitate percent calculations. Be ; careful not to change other functions when you write to TCON1 and ; TCON2. ; movlb 2 ; select bank for PR1 movlw .99 ; make period 100 for easy percent calcs movwf PR1 ; and apply to PWM1 movlb 3 ; select bank for other control registers clrf PW1DCL ; clear LSbs of the duty cycle register clrf PW1DCH ; zero duty cycle bcf TCON1,3 ; insure T1 & 2 are separate 8 bit timers movlw b'00010001' ; mask to turn on timer one and PWM1 iorwf TCON2 ; write only my bits, do not change others return ; return with pwm initialized ; ;********************************************************************* SetPWM2 ; load percent duty cycle value into pwm1 ;********************************************************************* ; ; install this command in the CmdMenu lookup table CmdPC = $ ; save current inline assembly PC value org CurCmdMenuAdr ; set assembly PC to addr for new entry ; CmdMenu table entry data "PWM2=n\r", CmdPC, "Set pwm2 duty cycle as percent\r\n" CurCmdMenuAdr = $ ; set current CmdMenu addr for next entry org CmdPC ; begin cmd code gen at inline address ; ; Same function as above, except for PWM2. Reuses string constants. ; call InitPWM2 ; init pwm2 bsf ALUSTA, 7 ; make sure FSR doesn't increment movlw cmdPrmBuff ; load parameter buffer address movwf FSR1 ; into FSR1 IncTgt ; entry point for IncPWM2 movlw .100 ; test if > 100%, if so clip cpfsgt INDF1 ; if cmd value greater than 100, leave 100 in WREG... movfp INDF1, WREG ; else put cmd value in WREG... DecTgt ; entry point for DecPWM2 movlb 3 ; set bank for PWM duty cycle control movwf PW2DCH ; and move to duty cycle register ; fall through to display pwm duty cycle ; ;********************************************************************* DspPWM2 ; displays current duty cycle for PWM2 ;********************************************************************* ; ; install this command in the CmdMenu lookup table CmdPC = $ ; save current inline assembly PC value org CurCmdMenuAdr ; set assembly PC to addr for new entry ; CmdMenu table entry data "PWM2\r", CmdPC, "Read pwm2 duty cycle\r\n" CurCmdMenuAdr = $ ; set current CmdMenu addr for next entry org CmdPC ; begin cmd code gen at inline address ; CpyTbl2Out Pwm2D ; init beginning of output string CpyTbl2Out DcD ; include duty cycle text movlb 3 ; be sure bank 3 still selected movfp PW2DCH, WREG ; move stored % to WREG call Dec2Buf ; convert into output buffer CpyTbl2Out PcD ; add finishing text return ; return from Cmd ; ;********************************************************************* IncPWM2 ; Increase duty cycle for PWM2 by input parameter amount ;********************************************************************* ; ; install this command in the CmdMenu lookup table CmdPC = $ ; save current inline assembly PC value org CurCmdMenuAdr ; set assembly PC to addr for new entry ; CmdMenu table entry data "PWM2+=n\r", CmdPC, "Increase pwm2 duty cycle by n%\r\n" CurCmdMenuAdr = $ ; set current CmdMenu addr for next entry org CmdPC ; begin cmd code gen at inline address ; ; This routine accepts a percentage increment and adds it to the duty ; cycle of PWM2. It also uses SetPWM2 to test validity and report. movlb 3 ; set bank bits bsf ALUSTA, 7 ; make sure FSR doesn't increment movlw cmdPrmBuff ; load parameter buffer address movwf FSR1 ; into FSR1 movfp PW2DCH, WREG ; move stored % to WREG addwf INDF1, f ; sum cmd value and existing value goto IncTgt ; go validate, store, and report ; ;********************************************************************* DecPWM2 ; Decrease duty cycle for PWM2 by input parameter amount ;********************************************************************* ; ; install this command in the CmdMenu lookup table CmdPC = $ ; save current inline assembly PC value org CurCmdMenuAdr ; set assembly PC to addr for new entry ; CmdMenu table entry data "PWM2-=n\r", CmdPC, "Decrease pwm2 duty cycle by n%\r\n" CurCmdMenuAdr = $ ; set current CmdMenu addr for next entry org CmdPC ; begin cmd code gen at inline address ; ; This routine accepts a percentage decrement and subtracts it from ; the duty cycle of PWM2. It tests for and prevents underflow and ; also uses SetPWM2 to test validity and report. movlb 3 ; set bank bits bsf ALUSTA, 7 ; make sure FSR doesn't increment movlw cmdPrmBuff ; load parameter buffer address movwf FSR1 ; into FSR1 movfp INDF1, WREG ; move CHANGE % to WREG cpfslt PW2DCH ; if current duty cycle < decr amount skip goto $+2 ; else sub dec amount movfp PW2DCH, WREG ; set equal, sub for zero, then go store subwf PW2DCH, w ; sub dec amount from duty cycle goto DecTgt ; go store and report ; ;********************************************************************* InitPWM2; Initialize the pwm2 peripheral ;********************************************************************* ; ; Instructions: Set up PWM2 to use timer 1. Use the value decimal 99 ; in the period register to facilitate percent calculations. Be ; careful not to change other functions when you write to TCON1 and ; TCON2. ; movlb 2 ; select bank for PR2 movlw .99 ; make period 100 for easy percent calcs movwf PR2 ; and apply to PWM2 movlb 3 ; select bank for other control registers clrf PW2DCL ; clear LSbs of the duty cycle register clrf PW2DCH ; zero duty cycle bcf TCON1,3 ; insure T1 & 2 are separate 8 bit timers movlw b'00100001' ; mask to turn on timer one and PWM2 iorwf TCON2 ; write only my bits, do not change others return ; return with pwm initialize ; end of file pwmcmd.asm *****************************************************
See: