花了一个多星期的时间,终于把我的第一款PIC产品给搞出来了~~~~~~~,功耗也达到了客户的要求,运行时0.3mA,休眠时用万用表测不出来,显示为0,应该是小于2uA吧
下面是除法子程序:
说明:这些子程序是从AVR上转过来的,习惯了AVR的一些字符,所以我在写这子程序的时候作了保留,如果你需用下面的程序,请先定义好此寄存器
由于第一次用PIC单片机,所以此程序可能写得不够好,请大家指正,以便此子程序能更完善,谢谢!
;******* XL = XHXL/100 ****************
;16位数除以100
;入口参数:低8位==>XL,高8位==>XH
;结果:商==>XL, 余数==>XH
;示例:
;MOVLW LOW(3000)
;MOVWF XL
;MOVLW HIGH(3000)
;MOVWF XH
;CALL DIV100
DIV100 MOVLW 100
SUBWF XH,W
BC DV100F ;XH>=100
MOVLW 8
MOVWF ZL
DV1000 CLRC
RLF XL,F
RLF XH,F
MOVLW 100
SUBWF XH,W
BNC DV1001
MOVLW 100
SUBWF XH,F
BSF XL,0
DV1001 DECFSZ ZL,F
GOTO DV1000
RETURN
;******* XL = XL/10 ****************
;8位数除以10
;入口参数:8位==>XL
;结果:商==>XL的低4位, 余数==>XL的高4位
;示例:
;MOVLW LOW(200)
;MOVWF XL
;CALL DIV10
DIV10 MOVFW XL
SUBLW 0A0H
BNC DV10F
MOVLW 4
MOVWF ZL
DV100 CLRC
RLF XL,F
BC DV101
MOVLW 0A0H
SUBWF XL,W
BNC DV102
DV101 MOVLW 0A0H
SUBWF XL,F
BSF XL,0
DV102 DECF ZL,F
BNZ DV100
RETURN
;******* XHXL = ZLYHYLXHXL/R1R0 ****************
;注意:此子程序运行于250K的频率以下会有点问题,感觉时间跟不上,我用500K的时候就正常,这中间的其它频率我没试,有兴趣的朋友可以试下
;16/24/32位数除以16位数
;入口参数:被除数的低8位==>XH,高8位==>YL,类推..,除数低8位==>R0,高8位==>R1
;结果:商==>XL, 余数==>XH
;示例:
;MOVLW LOW(3000000)
;MOVWF XH
;MOVLW HIGH(3000000)
;MOVWF YL
;MOVLW UPPER(3000000)
;MOVWF YH
;MOVLW LOW(1000)
;MOVWF R0
;MOVLW HIGH(1000)
;MOVWF R1
;CLRF XL
;CLRF ZL
;CALL DIV16R
DIV16R MOVLW 16
MOVWF ZH
DIV16 MOVFW ZL
SUBWF R1,W
BNC DIV16F
BZ DIV162
GOTO DIV160
DIV162 MOVFW R0
SUBWF YH,W
BC DIV16F
DIV160 CLRC
RLF XL,F
RLF XH,F
RLF YL,F
RLF YH,F
RLF ZL,F
BC DV1600
MOVFW R1
SUBWF ZL,W
BNC DV161
BZ DIV163
GOTO DV1600
DIV163 MOVFW R0
SUBWF YH,W
BNC DV161
DV1600 CLRC
MOVFW R0
SUBWF YH,F
SKPC
DECF ZL,F
DV164 MOVFW R1
SUBWF ZL,F
BSF XL,0
DV161 DECF ZH,F
BNZ DIV160
RETURN
;******* XL = XHXL/ZL ****************
;16位数除以8位数
;入口参数:被除数低8位==>XL,高8位==>XH,除数==>ZL
;结果:商==>XL, 余数==>XH
;示例:
;MOVLW LOW(2000)
;MOVWF XL
;MOVLW HIGH(2000)
;MOVWF XH
;MOVLW 200
;MOVWF ZL
;CALL DIV8
DIV8 MOVFW ZL ;XHXL/ZL
SUBWF XH,W
BC DIV8F
MOVLW 8
MOVWF ZH
DIV80 CLRC
RLF XL,F
RLF XH,F
BC DIV81
MOVFW ZL
SUBWF XH,W
BNC DIV82
DIV81 MOVFW ZL
SUBWF XH,F
BSF XL,0
DIV82 DECF ZH,F
BNZ DIV80
RETURN
;以下部分是处理溢出情况,全部返回FFH
DIV16F MOVLW 0FFH
MOVWF YL
MOVWF YH
DV100F
DIV8F MOVLW 0FFH
MOVWF XH
DV10F MOVLW 0FFH
MOVWF XL
RETURN
;*********************************************************************
; ACCb(16 bits) / ACCa(16 bits) -> ACCb(16 bits) with
; Remainder in ACCc (16 bits)
;
UDIV1616:
call ud16setup
clrf ACCcHI
clrf ACCcLO
ud16dloop:
bcf STATUS, C
rlf ACCdLO, F
rlf ACCdHI, F
rlf ACCcLO, F
rlf ACCcHI, F
movf ACCaHI, W
subwf ACCcHI, W ; check if a>c
btfss STATUS, Z
goto ud16nochk
movf ACCaLO, W
subwf ACCcLO, W ; if msb equal then check lsb
ud16nochk:
btfss STATUS, C ; carry set if c>a
goto ud16nogo
movf ACCaLO, W ; c-a into c
subwf ACCcLO, F
btfss STATUS, C
decf ACCcHI, F
movf ACCaHI, W
subwf ACCcHI, F
bsf STATUS, C ; shift a 1 into b (result)
ud16nogo:
rlf ACCbLO, F
rlf ACCbHI, F
decfsz temp, F ; loop until all bits checked
goto ud16dloop
return
ud16setup:
movlw .16 ; for 16 shifts
movwf temp
movf ACCbHI, W ; move ACCb to ACCd
movwf ACCdHI
movf ACCbLO, W
movwf ACCdLO
clrf ACCbHI
clrf ACCbLO
return
--------------------
;*********************************************************************
; ACCb / ACCa -> ACCb with Remainder in ACCc
;
UDIV0808:
call ud8setup
clrf ACCc
ud8dloop:
bcf STATUS, C
rlf ACCd, F
rlf ACCc, F
movf ACCa, W
subwf ACCc, W ; check if a>c
btfss STATUS, Z
goto ud8nochk
ud8nochk:
btfss STATUS, C ; carry set if c>a
goto ud8nogo
btfss STATUS, C
decf ACCc, F
movf ACCa, W
subwf ACCc, F
bsf STATUS, C ; shift a 1 into b (result)
ud8nogo:
rlf ACCb, F
decfsz temp, F ; loop until all bits checked
goto ud8dloop
return
ud8setup:
movlw .8 ; for 16 shifts
movwf temp
movf ACCb, W ; move ACCb to ACCd
movwf ACCd
clrf ACCb
return
用2位的LED显示出来0-99,中间延时1S
共阳的7段LED:
- -
| | | |
- -
| | | |
- -
高位。 低位
///////////////////////////////////////////
for (a=0; a<100; a++){
count=a;
led_l=(char)(count%10); //计算出低位的值。
led_h=count/10;
led_h%=count; //计算出高位的值
delay_ms(1000);
}
/////////低位LED数字显示程序//////////////////////////
output_low(X2); //共阳的7段LED 关闭高位数字
output_high(X1); // 开低位数字
output_C(TB[led_l]);
//-----------高位LED数字显示程序---------------------
output_low(X1); //
output_high(X2); //
output_C(TB[led_h]); //高位
18及以上,基本上就是c了。
一周热门 更多>