搜索
bottom↓
回复: 3

一个流水灯光控制程序源码。哪位高手能找出其中BUG?

[复制链接]

出0入0汤圆

发表于 2006-12-5 11:50:57 | 显示全部楼层 |阅读模式
;##############################################################################

;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, 杜汶泽)

出0入0汤圆

发表于 2006-12-5 15:04:35 | 显示全部楼层
不要太长哦呵呵!

出0入0汤圆

发表于 2006-12-5 15:49:40 | 显示全部楼层
累的

出0入0汤圆

发表于 2012-9-15 00:42:01 | 显示全部楼层
真的很长啊,我也有点了……
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 06:17

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表