|
发表于 2008-4-17 16:57:17
|
显示全部楼层
感谢你的资料,根据此资料我写了一个小玩具,不说了,开!
.include "tn13def.inc"
.DEF TEMP = R16 ;各种临时变量。
.DEF ZERO = R3 ;清零寄存器
.DEF CON = R19 ;存放计数器的内存
.DEF ADS = R20 ;递加值的初始内存。存放递加数
.DEF TOCR0 = R21 ;存放定时器值
.org 0x0000
RJMP RESET ;开机跳转
RJMP RESET ;外部按键唤醒休眠
.ORG 0X4A
RESET: ;初始化系统中断和资源部分
CLI ;关闭全局中断标志
WDR ;喂狗,防止它出来咬人
LDI TEMP,$00 ;设置清除ram
MOV ZERO,TEMP ;清除R3
MOV CON,ZERO ;清除累计计数器
MOV TOCR0,TEMP ;清除pwm初值
LDI TEMP,low(RAMEND) ;设置堆栈指针低位 ??
OUT SPL,TEMP ;设置堆栈指针为ram顶部??
OUT WDTCR,ZERO ;把狗喂饱了再偷偷打死,免得以后害人
OUT DIDR0,ZERO ;关闭全部数字输入输出缓冲
OUT SREG,ZERO ;清除全部数学标志。(增加稳定性)
LDI TEMP,$10 ;装muccr控制数
MOV ADS,TEMP ;把递加值放在递加数寄存器内
OUT MCUCR,TEMP ;传递控制数:上拉开=0;休眠关;掉电休眠模式
LDI TEMP,$FF
OUT PORTB,TEMP ;端口上拉全开
LDI TEMP,$3D
OUT DDRB,TEMP ;端口PB1输入开,也是int0端口
LDI TEMP,0x19 ;减小temp值,快速进入休眠
BEGIN:
RCALL DY01S ;定时基准是0s1
DEC TEMP ;递减约2s5后无按键则休眠
BREQ LJ0 ;TEMP=0经中间跳转句去跳转区?
SBIC PINB,1 ;键判断是否启动
RJMP BEGIN ;键判断结束区
ADT:
RCALL DY01S ;延迟0.1s再判断
SBIC PINB,1 ;K=0;按键有效。同时包括出错判断
RJMP BEGIN ;初次键判断延迟及误复位处理完
CBI DDRB,3 ;开PB3输入,置为输入高阻
CBI PORTB,3 ;开PB3输入(pwm只能驱动PB4)
LDI TEMP,$C3 ;装各种操作数操作pwm初始化
OUT TCCR0A,TEMP ;定义输出模式\输出脚
LDI TEMP,$01 ;T0时钟系统CLIio不分频 128k
OUT TCCR0B,TEMP ;定义输出模式\分频系数
LDI TOCR0,$00 ;初始pwm值
LDI CON,$06 ;初始化计数器,6级输出
;-------------------------------------------------------------
; DEF R20=TOCR0,K=PB1,低电平动作,可能在硬件新版本中加入
;上拉电阻,以维持端口电平
;_____________________________________________________________
RA1:
ADD TOCR0,ADS ;ADD计时器和步进值
OUT OCR0A,TOCR0 ;输出pwm脉冲,pb4会亮
DEC CON ;递增计数值;判断是否到6次,减完保持
BREQ RHOLD ;如果相等就跳转到保持段
LDI TEMP,$50 ;定义每个按键周期检测是0s8,4s8循环完
RA2:
RCALL DY01S
DEC TEMP ;0s8递减数
BREQ RJX ;延迟数检查是否减完,减完就跳转
RJMP RA2 ;08延迟数没减完,返回继续减
RJX:
SBIS PINB,1 ;再检测键释放?是跳过下行
RJMP RA1 ;没释放,回去再加pwm值
;-----------------------------------------------------------
; 读取键盘释放信息,并开始计时。
;-----------------------------------------------------------
RHOLD:
RCALL DY01S ;延迟释放
SBIC PINB,1 ;检测键盘释放B=0?跳行!
RJMP RTMOUT ;释放了就跳去开始计时
RJMP RHOLD ;没释放再返回等待
LJ0:
RJMP LJ1
;-------------------专用0s1延迟-------------------------
DY01S: ;目前延迟时间0.1S,10HZ
LDI R17,$C8 ;原9.6/8预分频为1.2M,软件版本1.27
D41:LDI R18,$40 ;现改1.2M 8频,CLK=128K.O.1S=12800
D42:DEC R18
DEC R17
BRNE D41
RET
;-----------------------------------------------------------
; 1800s自关机超时,定义键盘检测:如果按下进绿灯循环
;-----------------------------------------------------------
RTMOUT:
LDI CON,$C8 ;延迟循环值1
RL1: LDI TEMP,$5A ;装载另一个操作数,准备递减延迟
RL2: RCALL DY01S ;每个周期调用01s延迟
DEC TEMP
RJMP RKEY ;每0.1s检测一次键
RL3: BRNE RL2
DEC CON
BRNE RL1
RJMP OFF ;减完了就去关机了。
;--------------转为1800s制造的R键判断延迟-----------------
RKEY:
SBIC PINB,1 ;检测键按下,跳转去绿色控制
RJMP RL3 ;否则返回
;---------------进绿色开启段,关闭红色---------------------
GDT:
OUT OCR0A,ZERO ;关掉pwm输出
RCALL DY01S ;为同步定时器,防止一个延迟
LDI TEMP,$FF
OUT PORTB,TEMP ;端口上拉全开
LDI TEMP,$3D
OUT DDRB,TEMP ;端口PB1输入开,也是int0端口
RCALL DY01S ;延迟0s1
SBIC PINB,1 ;按键仍然有效,做识别
RJMP BEGIN ;无键动作做出误处理
CBI DDRB,4 ;开PB4输入,置为输入高阻
CBI PORTB,4 ;开PB4输入(pwm只能驱动PB3)
LDI TOCR0,$00 ;初始pwm值
LDI CON,$06 ;初始化计数器,6级输出
;-------------------------------------------------------------
; DEF R20=TOCR0,K=PB1,低电平动作,可能在硬件新版本中加入
;上拉电阻,以维持端口电平
;_____________________________________________________________
GA1:
ADD TOCR0,ADS ;INC计时器和步进值
OUT OCR0A,TOCR0 ;输出pwm脉冲
DEC CON ;递增计数值;判断是否到6次,减完保持
BREQ GHOLD ;如果相等就跳转到保持段
LDI TEMP,$50 ;定义每个按键周期检测是0s8,4s8循环完
GA2:
RCALL DY01S
DEC TEMP ;0s8递减数
BREQ GJX ;延迟数检查是否减完,减完就跳转
RJMP GA2 ;08延迟数没减完,返回继续减
GJX:
SBIS PINB,1 ;再检测键释放=1?是跳过下行
RJMP GA1 ;没释放,回去再加pwm值
;-----------------------------------------------------------
; 读取键盘释放信息,并开始计时。
;-----------------------------------------------------------
GHOLD:
RCALL DY01S ;延迟释放
SBIC PINB,1 ;检测键盘按下B=0?跳行!
RJMP GTMOUT ;释放了就跳去开始计时
RJMP RHOLD ;没释放再返回等待
LJ1:
RJMP POW_OFF
;-----------------------------------------------------------
; 1800s自关机超时,定义键盘检测:如果按下进绿灯循环
;-----------------------------------------------------------
GTMOUT:
LDI CON,$C8 ;延迟循环值1
GL1: LDI TEMP,$5A ;装载另一个操作数,准备递减延迟
GL2: RCALL DY01S ;每个周期调用01s延迟
DEC TEMP
RJMP GKEY ;每0.1s检测一次键
GL3: BRNE GL2
DEC CON
BRNE GL1
RJMP OFF ;减完了就去关机了。
;--------------转为1800s制造的G键判断延迟-----------------
GKEY:
SBIC PINB,1 ;检测键按下,跳转去绿色控制
RJMP GL3 ;否则返回
;--------------------------------------------------------
; DEF TIME_OUT关机段,当超时再按键则判断是否释放
; 释放后,全关
;--------------------------------------------------------
OFF:
OUT TCCR0A,ZERO
OUT TCCR0B,ZERO
LDI TEMP,$FF
OUT PORTB,TEMP ;端口上拉全开
LDI TEMP,$3D
OUT DDRB,TEMP ;端口PB1输入开,也是int0端口
RCALL DY01S
SBIC PINB,1 ;读键释放否?
RJMP POW_OFF ;K=1,已释放就去关
RCALL DY01S
RJMP OFF ;K=0,返回再检测键释放没
;-------------------------------------------------------
; 主程序结束,定义全关,重开sleep和中断wake up
;-------------------------------------------------------
POW_OFF:
LDI TEMP,$40
OUT GIMSK,TEMP ;开启INT0中断允许
LDI TEMP,$30
OUT MCUCR,TEMP
SEI
SLEEP ;进入休眠模式
RJMP OFF ;强制在此循环 |
|