|
;##############################################################################
;Project Name:
;Revision: 0.0
;Author: Hu Zhengliang
;E-mail: zerosoft@21cn.com
;Mobile: 13826538845
;Date:2006-12-5
;##############################################################################
;##############################################################################
;Function:
;8跑马灯程序
;##############################################################################
;##############################################################################
; .include "tn15def.inc"
; .include "8515def.inc" ;Includes the 8515 definitions file
; .include "8535def.inc"
.include "m16def.inc"
.def pwm_r =r3
.def Temp =R16 ;Gives "Defines" RegisterR16 the name Temp
.def key1_y =r17
.def pinc_r =r18
.def delay10mS =r20 ;10mS 定时中断次数计数器
.def delay30mS =r21 ;30mS 定时中断次数计数器
.def delay500mS =r22 ;500mS 定时中断次数计数器
.def pwm_step =r23
.def key_r =r24
.def delay_r =r25 ;delay_r.0====10mS延时完成标志
;delay_r.1====30mS延时完成标志
;delay_r.2====500mS延时完成标志
;=================================================================================
.org $000 ;Places the following code from address 0x0000
rjmp RESET ;复位中断向量
.org $002
rjmp EXT_INT0 ;IRQ0 中断向量
.org $004
rjmp EXT_INT1 ;IRQ1 中断向量
.org $006
rjmp TIM2_COMP ;Timer2 比较中断向量
.org $008
rjmp TIM2_OVF ;Timer2 溢出中断向量
.org $00a
rjmp TIM1_CAPT ;Timer1 捕捉中断向量
.org $00c
rjmp TIM1_COMPA ;Timer1 比较A 中断向量
.org $00e
rjmp TIM1_COMPB ;Timer1 比较B 中断向量
.org $010
rjmp TIM1_OVF ;Timer1 溢出中断向量
.org $012
rjmp TIM0_OVF ;Timer0 溢出中断向量
.org $014
rjmp SPI_STC ;SPI 传输结束中断向量
.org $016
rjmp USART_RXC ;USART RX 结束中断向量
.org $018
rjmp USART_UDRE ;UDR 空中断向量
.org $01a
rjmp USART_TXC ;USART TX 结束中断向量
.org $01C
rjmp ADC_ok ;ADC 转换结束中断向量
.org $01e
rjmp EE_RDY ;EEPROM 就绪中断向量
.org $020
rjmp ANA_COMP ;模拟比较器中断向量
.org $022
rjmp TWSI ;两线串行接口中断向量
.org $024
rjmp EXT_INT2 ;IRQ2 中断向量
.org $026
rjmp TIM0_COMP ;定时器0 比较中断向量
.org $028
rjmp SPM_RDY ;SPM 就绪中断向量
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;******************************************************************************
;模块1:复位初始值设置
;******************************************************************************
.org $02a
RESET: ;Reset Label
ldi temp,high(RAMEND)
out SPH,temp ; 设置堆栈指针为RAM 的顶部
ldi temp,low(RAMEND)
out SPL,temp ;SPL--堆栈的低8位
sei ;全局中断使能
;===================================================
ldi temp, 0xff
out ddra, temp ;定义PA为输出口
out ddrb, temp ;定义PB为输出口
out porta, temp ;PA输出全高
out portb, temp ;PB输出全高
ldi temp, 0x00
out ddra, temp ;PORTA定义为输入口
out ddrb, temp ;PORTB定义为输入口
ldi temp, 0xff ;PB0设置内置上拉
out porta, temp ;设置PA口内置上拉
out portb, temp ;设置PB口内置上拉
ldi Temp, 0xFF ;
out DDRC, Temp ;PORTC定义为输出口
out ddrd, temp ;PORTD定义为输出口
ldi Temp, 0x7F ;PD7输出低电平
out portd, temp ;PORTD其它为输出高电平
ldi temp, 0xfe
out PORTc, temp ;
;===================================================
;ldi temp, 0x01 ;
ldi temp, 0xc1 ;T/C中断使能 11000001
out timsk, temp ;T/C0与T/C2溢出中断使能,T/C2比较中断使能。
;===================================================
ldi temp, 0x04 ;00000100T/C0 预分频选择:CK/256
out tccr0,temp
ldi temp, 0x82 ;给T/C0赋初始值。2mS中断一次
out tcnt0,temp
;===================================================
ldi temp, 0b01001001 ;01001001:tccr2.6:3(快速PWM模式),tccr2.5:4(断开OC2);时钟不分频.
out tccr2, temp ;设置TC2为快速PWM模式,匹配时清零OC2,计数时钟为16M
ldi temp, 0x5f ;设定匹配的初始值为0x5f+80=0xaf, 则PWM的占空比为50%。
out ocr2, temp ;10111111
mov pwm_r, temp
ldi pwm_step, 0x02 ;设置调节PWM时的步长.
;ldi temp, 0xfe ;10111111
;out tcnt2, temp ;设定T2的起始计数值为0x5f, 只计160个数,0xFF-0x5F=0xA0=160, 10uS中断一次
;******************************************************************************
;模块2: 主循环程序
;******************************************************************************
main:
rcall keyscan
rcall key_exe
;rcall pwmout
rcall led8_out
rjmp main
;$$$$$$=以下为子程序=$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
;******************************************************************************
;模块3:按键检测
;******************************************************************************
;;DEF 没有按键动作: 0x00 ;DEF 键松开,消抖成功:
;;DEF 键按下,消抖中: 0x01
;;DEF 键按下,消抖成功: 0x02
;;DEF 键松开,消抖中: 0x03
;;key1_y: =0(没有被执行过); =1(已被执行过)
;;PB0按下松开后执行,按一次PD7为高,再按一次PD7为低.
keyscan: ;检测PB0是否被按下,并且是否被执行过
cpi key_r, 0x00 ;等待按键时,进入key_chk1
breq key_chk0
cpi key_r, 0x01 ;键按下消抖中,进入key_chk2
breq key_chk1
cpi key_r, 0x02 ;键按下消抖成功,进入key_chk3
breq key_chk2
cpi key_r, 0x03 ;键松开消抖中,进入key_chk4
breq key_chk3
ldi key_r, 0x00
rjmp keyscan_ret
;======================================================
key_chk0: ;0x00入口
sbic pinb, 0 ;PB0==0表示键被按下,
rjmp keyscan_ret ;PB0为高,继续等待
ldi key_r, 0x01 ;置正在消抖标志
CLR delay30mS ;开始消抖:清30mS延时中断计数器
;cbr delay_r, 0x02 ;开始消抖:清30mS延时完成标志
;andi delay_r, 0b11111101
rjmp keyscan_ret
;======================================================
key_chk1: ;0x01入口
sbic pinb, 0 ;PB0==0表示键被按下,
rjmp key_chk1_1 ;PB0为高,消抖不成功,返回0x00
;rcall delay30mS
;sbrs delay_r, 1 ;延时完成,置键值标志
cpi delay30mS, 0x0f
brne keyscan_ret ;延时没完,退出
ldi key_r, 0x02 ;为"1"时说明消抖成功.,置键值标志
ldi key1_y, 0x00
rjmp keyscan_ret
key_chk1_1:
ldi key_r, 0x00
rjmp keyscan_ret
;======================================================
key_chk2: ;0x02入口
cpi key1_y, 0x00
breq keyscan_ret
sbis pinb, 0 ;PB0==0表示键被按下,
rjmp keyscan_ret ;
ldi key_r, 0x03 ;置正在消抖标志
CLR delay30mS ;开始消抖:清30mS延时中断计数器
;cbr delay_r, 0x02 ;开始消抖:清30mS延时完成标志
;andi delay_r, 0b11111101
rjmp keyscan_ret
;=======================================================
key_chk3: ;0x03入口
sbis pinb, 0 ;PB0==0表示键被按下,
rjmp key_chk3_1 ;PB0为高,消抖不成功,返回0x00
;rcall delay30mS
;sbrs delay_r, 0x01 ;延时完成,置键值标志
;rjmp keyscan_ret ;延时没完,退出
cpi delay30mS, 0x0f
brne keyscan_ret ;延时没完,退出
ldi key_r, 0x00 ;为"1"时说明消抖成功.,置键值标志
ldi key1_y, 0x00
rjmp keyscan_ret
key_chk3_1:
ldi key_r, 0x02
keyscan_ret: ;0x04入口,松开后未执行,直接退出
ret
;******************************************************************************
;模块4: PWM开启与关闭模块
;******************************************************************************
pwmout:
pwmout_ret:
ret
;******************************************************************************
;模块5:按键执行模块
;功能: 每按一次KEY(PB0),LED(pd0)循环亮灭;
; 每按一次PB0, PWM==(OCCR2+2), 到顶不再加.
;******************************************************************************
key_exe:
cpi key_r, 0x02 ;
brne key_exe_ret ;不相等跳,无键值直接退出
cpi key1_y, 0x00 ;
brne key_exe_ret ;不相等跳,无键值直接退出
ldi key1_y, 0x01 ;按键已执行.
;======================================
;LED 更新
sbis pind, 0 ;pd0==1, 清0
rjmp set_pd0 ;pd0==0, 置1
cbi portd, 0
rjmp inc_pwm ;改变完LED,接下来调整PWM
set_pd0:
sbi portd, 0
;======================================
inc_pwm: ;调整PWM
mov temp, pwm_r
cpi temp, 0xff
breq key_exe_ret
cpi temp, 0x5f ;如果当前为最小占空比,则增加OCR2前先连接OC2并使能T2中断
brne inc_ocr2
in temp, tccr2
ori temp, 0b00100000 ;tccr5:4==00 与OC2连接。
out tccr2,temp
ldi temp, 0xfa
out tcnt2, temp
inc_ocr2:
add pwm_r, pwm_step
out ocr2, pwm_r
key_exe_ret:
ret
;===============================
;;def pinc_r=r18
led8_out: ;PC口接8只LED,作流水闪烁,
in temp, pinc
cpi delay500mS, 0xfa ;delay 500mS
brne led8_out_ret
CLR delay500mS ;清500mS中断次数
cpi temp, 0x7f
brne inc_portc
ldi temp, 0xfe ;流水一个周期结束,重装一次。
rjmp led8_out_ret
inc_portc:
lsl temp
INC temp
led8_out_ret:
out portc, temp
ret
;$$$$$$=以下为中断处理程序=$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
;******************************************************************************
;模块10: 中断处理程序
;******************************************************************************
EXT_INT0:
RETI
;==============================================================================
EXT_INT1:
RETI
;==============================================================================
TIM2_COMP:
RETI
;==============================================================================
TIM2_OVF:
mov r2, temp
ldi temp, 0x5F
out tcnt2, temp ;设定T2的起始计数值为0x5f, 只计160个数,0xFF-0x5F=0xA0=160
mov temp, r2
RETI
;==============================================================================
tim1_ovf:
NOP
RETI
;==============================================================================
tim0_ovf:
mov r2,temp ;保护temp的值
ldi temp, 0x82 ;reload tcnt0.
out tcnt0,temp
inc_delay10mS: ;0x05
cpi delay10mS, 0x05
breq inc_delay30mS
INC delay10mS
inc_delay30mS: ;0x0f
cpi delay30mS, 0x0f
breq inc_delay500mS
INC delay30mS
inc_delay500mS: ;0xfa
cpi delay500mS, 0xfa
breq reload_tcnt0
INC delay500mS
reload_tcnt0:
mov temp, r2 ;还原temp的值
RETI
;==============================================================================
TIM1_CAPT:
RETI
;==============================================================================
TIM1_COMPA:
RETI
;==============================================================================
TIM1_COMPB:
RETI
;==============================================================================
SPI_STC:
RETI
;==============================================================================
USART_RXC:
RETI
;==============================================================================
USART_UDRE:
RETI
;==============================================================================
USART_TXC:
RETI
;==============================================================================
ADC_ok:
RETI
;==============================================================================
EE_RDY:
RETI
;==============================================================================
ANA_COMP:
RETI
;==============================================================================
TWSI:
RETI
;==============================================================================
EXT_INT2:
RETI
;==============================================================================
TIM0_COMP:
RETI
;==============================================================================
SPM_RDY:
RETI
;==============================================================================
;oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
;****************************************************************************** |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|