;时 间 : 2019-12
; PIC10F200 Configuration Bit Settings
; Assembly source line config statements
#include "p10f200.inc"
; CONFIG
; __config 0xFFEB
__CONFIG _WDTE_OFF & _CP_OFF & _MCLRE_OFF
;***************变量定义*****************************************
;对于10F200单片机,GPR寄存器从0x10地址开始,范围0x10-0x1F共16bytes
;****************************************************************
;变量块定义
cblock 0x10
delay.loop.in
delay.loop.out
switch.timer
hold.timer
led.state
mode
index
index.base
mask
endc
;位变量定义
pb.switch equ 3 ;按键端口
pb.led1 equ 0 ;LED1端口
pb.led2 equ 1 ;LED2端口
pb.led3 equ 2 ;LED3端口
multiplex equ 7 ;multiplex标志变量
pson equ 1<<multiplex
psoff equ 0
led1on equ 1<<pb.led1
led1off equ 0
led2on equ 1<<pb.led2
led2off equ 0
led3on equ 1<<pb.led3
led3off equ 0
;宏定义
ledstep macro hold,pwrsave,led1,led2,led3
retlw hold
retlw pwrsave|led1|led2|led3
ENDM
restart MACRO
retlw 0
ENDM
;***********************************************************
;对于pic10F200芯片,内部晶振校准值参数在0xFF地址存储的
ORG 0x0000
movwf OSCCAL
goto start
;**********************************************************
;LED闪烁模式查找表
;对于每一种闪烁模式,必须在有一个相应的分支入口
;返回值max.mode同样必须设置
radix dec
select.mode movfw mode
addwf PCL,f
retlw mode.1
retlw mode.2
retlw mode.3
retlw mode.4
retlw mode.5
retlw mode.6
retlw mode.7
max.mode retlw 7 ;模式最大种类数
;定义闪烁序列
;ledstep hold_time,power_save,LED1_state,LED2_state,LED3_state
;hold_time是1-255的数值,没计一个数单位20ms,所以当hold_time=50时,就是1000ms
;power_save定义了省电模式,开启后LED亮度略暗,更省电
;psoff---省电模式关闭,全功率运行
;pson---省电模式开启,节电运行
;LEDx_state 定义灯的亮或灭
;模式1,常量,节电模式
mode.1 ledstep 50,pson,led1on,led2on,led3on
restart
;模式2,常量,正常模式
mode.2 ledstep 50,psoff,led1on,led2on,led3on
restart
;模式3,所有闪烁,节电模式
mode.3 ledstep 18,pson,led1on,led2on,led3on
ledstep 18,pson,led1off,led2off,led3off
restart
;模式4,单个LED亮,正常模式
mode.4 ledstep 12,psoff,led1on,led2off,led3off
ledstep 12,psoff,led1off,led2on,led3off
ledstep 12,psoff,led1off,led2off,led3on
ledstep 12,psoff,led1off,led2on,led3off
restart
;模式5,所有LED频闪,正常模式
mode.5 ledstep 2,psoff,led1on,led2on,led3on
ledstep 30,psoff,led1off,led2off,led3off
restart
;模式6,所有LED短灭长亮,正常模式
mode.6 ledstep 2,psoff,led1on,led2off,led3off
ledstep 10,psoff,led1off,led2on,led3off
ledstep 60,pson,led1on,led2on,led3on
ledstep 10,psoff,led1off,led2on,led3off
restart
;模式7,所有LED短灭长亮,正常模式
mode.7 ledstep 1,psoff,led1on,led2off,led3off
ledstep 3,psoff,led1off,led2on,led3off
ledstep 1,psoff,led1on,led2off,led3off
ledstep 3,psoff,led1off,led2on,led3off
ledstep 1,psoff,led1on,led2off,led3off
ledstep 3,psoff,led1off,led2on,led3off
ledstep 1,psoff,led1on,led2off,led3off
ledstep 3,psoff,led1off,led2on,led3off
ledstep 1,psoff,led1on,led2off,led3off
ledstep 3,psoff,led1off,led2on,led3off
ledstep 1,psoff,led1on,led2off,led3off
ledstep 50,psoff,led1off,led2on,led3off
restart
;结束LED闪烁模式查找表
radix hex
;唤醒或者上电的pic初始化
start movlw (1<<pb.switch) ;设置按键端口输入
tris GPIO
movlw ~(1<<NOT_GPWU |1<<NOT_GPPU|1<<T0CS);
option
clrwdt
btfsc STATUS,GPWUF ;查询唤醒标志
goto wakeup ;标志置位需要唤醒
;仅在上电后初始化变量
clrf GPIO ;启动后关闭所有输出
clrf mode
clrf delay.loop.in ;初始化延时计数变量
clrf switch.timer ;初始化按键计数变量
clrf led.state
movlw 1<<pb.led3 ;初始化multiples mask
movwf mask
movlw mode.1 ;初始化模式索引
movwf index
goto reload ;跳转到设置新模式
;*****************************************************************************
; 程序主循环开始
wakeup movlw .100 ;设置一个2000ms倒计时计数
movwf switch.timer
movf GPIO,W
bcf STATUS,GPWUF
btfsc GPIO,pb.switch; ;按键没有按下跳过下一条
sleep
waking.up call delay ;等待
btfsc GPIO,pb.switch ;按键还按下?
goto wakeup ;没按下,进入休眠
decfsz switch.timer,F ;按下,计数器减一,若为0跳过下一步
goto waking.up
bsf switch.timer,7 ;把计数器最高位置1,这里是一个标志位
main call delay ;延时20ms
btfss GPIO,pb.switch ;是否按下?
goto switch.down ;是按下,执行按下任务
switch.release btfsc switch.timer,7 ;如果这个置位了,我们只是从休眠唤醒
clrf switch.timer ;清计数器
movlw -.3
addwf switch.timer,W
clrf switch.timer
skpc
goto lights
;以下仅执行一次,当一个按键事件发生后
incf mode,F ;状态加1
call max.mode ;与最大模式比较
subwf mode,W
skpnc
clrf mode
call select.mode ;查表执行函数
movwf index; ;保存索引
movwf index.base
goto reload ;设置新模式
;LED函数选择
switch.down btfsc switch.timer,7 ;
goto lights
incf switch.timer,F
movlw -.100
addwf switch.timer,W
skpc
goto lights
;按键保持2秒后关闭
clrf GPIO
clrf led.state
btfss GPIO,pb.switch
goto $-1
call delay
movf GPIO,W
bcf STATUS,GPWUF
sleep
;******************************************************************************
;延时函数,主频4Mhz 时钟
delay movlw .26 ;延时20.2ms
movwf delay.loop.out
;内循环
delay.loop decfsz delay.loop.in,F ;重复255次
goto $-1
;分时控制LED,提高电池寿命
rrf mask,F
skpnc
bsf mask,2
movfw mask
andwf led.state,W
btfss led.state,multiplex ;multiplex标志清零?
movfw led.state ;关闭分时控制
movwf GPIO
;外循环
decfsz delay.loop.out,F
goto delay.loop
retlw 0x00
lights decfsz hold.timer,F ;led计数器减1
goto main ;循环
reload call lookup ;查找下一个计数值
movwf led.state ;存储
goto main
reset.index movfw index.base ;把index.base值读入W
movwf index ;把值放入当前索引
goto reload ;
lookup movfw index ;把index值给W
incf index,F ;index=index+1
movwf PCL ;把W给PCL
END