;**** AVR编程说明 ******************************************************************** ;* 编号:LRDZAVR0100  ;* 标题: 32点打铃器例程 ;* 文件名:timecontr.asm ;* 版本: 1.0 ;* 开始日期: 02.06.13 ;* 目标MCU: AT90S8515 ;* 技术支持: webmaster@lrdz.51.net ;* 硬件结构: PA0-5对应6个LED数显管的位 ,PC0-7对应各LED数显管的段 ,PB4-7为键盘。 ;* 软件描述: 上电后,时钟从00.00.00(时/分/秒)自动走时,在走时状态时 , 按PB4(设定 ;* 键)超过3秒可循环选择调整时间/工作参数 ,接着按PB5以确定选择的操作 ,进入调整操作后 , ;* 按PB5选择欲调整参数,按PB6(增加键)完成调整参数操作 。按PB7,进入时控运行,PB1亮, ;* 再按PB7停止时控运行,回显走时。在定时到时,PB0点亮。 ;************************************************************************************* .device AT90S8515 .include "8515def.inc" .equ DISBUF = $0060 ;显示缓冲区起始地址 .equ TIMEDIS = $0066 ;时钟时分秒存放单元 .equ XSDBZ = $0073 ;小数点位标志 .equ DISTBL = $0f00 ;显示字符编码表起始地址 .equ TIMECTR = $0010 ;32段时间控制表首址(EEPRON) .equ TIMECBZ = $0080 ;控制时间到标志 .cseg .org $0000 rjmp RESET .org $0007 rjmp TIM0_OVF ;****主程序*************************************************************************** .def cntms =r9 .def hour =r10 .def minute =r11 .def second =r12 .def EEdwr =r16 .def EEawr =r17 .def EEawrh =r18 .def EEdrd =r16 .def EEard =r17 .def EEardh =r18 .def temp =r20 .def temp1 =r21 .def temp2 =r22 .def temp3 =r23 .def temp4 =r24 .def TIM0INT =r19 .org $0020 RESET: ldi temp,low(ramend) ;设置堆栈指针 out spl,temp ldi temp,high(ramend) out sph,temp ldi temp,0b11111111 ;设置各口线输入输出状态 out ddra,temp ldi temp,0b00000011 out ddrb,temp ldi temp,0b11111111 out ddrc,temp ldi zl,TIMECBZ clr zh clr temp st y,temp clr r9 ;清各工作寄存器 clr r10 clr r11 clr r12 clr r13 clr r14 clr r15 clr r16 clr r17 clr r18 clr r19 clr r25 ldi temp,$5 out tccr0,temp ;T0设置ck/1024分频 ldi temp,256-195 out tcnt0,temp ;装T0时间常数 res1: ldi temp,$02 ;允许T0中断,并计时 out timsk,temp sei ;开中断 res2: clr r6 clr r7 sbi PORTb,1 sbi PORTB,0 res3: ldi temp,$af res4: rcall colodis ;时钟走时显示 dec temp brne res4 sbis pinb,7 ;键扫描 rjmp PB7M sbis pinb,4 rjmp BP4M ;去参数设置 rjmp res3 ;****《系统功能程序》 .org $0080 ;定义系统功能程序存放区首址 ;****32点打铃器工作程序************************************************************************* PB7M: cbi PORTb,1 ;置运行指示灯亮 clr r25 clr r7 GNCX11:ldi r17,TIMECTR ;首个控制点EEPRON地址 clr r18 lsl r25 lsl r25 add r17,r25 ;取得EEPRON中控制点地址(Aj=A0+4*j),A=(r17),j=(r25) lsr r25 lsr r25 rcall EERead cpi r16,0 breq GNCX12 ;r16=(r17)=0为“ON” inc r25 cpi r25,31 brmi GNCX11 rjmp GNCX16 GNCX12:inc r17 rcall EERead cp r16,r10 brne GNCX13 inc r17 rcall EERead cp r16,r11 brne GNCX14 inc r17 rcall EERead mov r7,r16 inc r7 cbi PORTb,0 rjmp GNCX15 GNCX13:dec r17 inc r25 rjmp GNCX11 GNCX14:dec r17 dec r17 inc r25 rjmp GNCX11 GNCX15:cpi TIM0INT,1 brne GNCX17 clr TIM0INT dec r7 brne GNCX17 clr r7 sbi PORTb,0 rjmp GNCX16 GNCX17:rcall colodis sbic pinb,7 rjmp GNCX15 rjmp res2 GNCX16:ldi temp,$5f GNCX18:rcall colodis dec temp brne GNCX18 sbic pinb,7 rjmp GNCX11 rjmp res2 ;****参数设置 BP4M: ldi temp3,$ff ldi temp4,$f BP4M1: nop rcall colodis sbic pinb,4 rjmp res1 dec temp3 ;PB4有按下 brne BP4M1 inc temp3 dec temp4 brne BP4M1 ldi temp3,$ff ;超3秒进入 ldi temp4,$f BP4M2: clr yh ldi yl,low(DISBUF) ;设置显示cloc. ldi temp,25 st y+,temp st y+,temp ldi temp,18 st y+,temp ldi temp,19 st y+,temp ldi temp,20 st y+,temp ldi temp,18 st y,temp ldi zl,low(XSDBZ) clr zh ldi temp,0b00100000 ;b0-5对应LED自左到右1-6位的小数点,置“1”在该位置小数点。 st z,temp rcall display sbis pinb,5 rjmp cloc ;进入时间设置 dec temp3 brne BP4M2 inc temp3 dec temp4 brne BP4M2 BP4M3: ldi temp3,$ff ldi temp4,$f BP4M4: clr yh ldi yl,low(DISBUF) ;设置显示labor. ldi temp,25 st y+,temp ldi temp,19 st y+,temp ldi temp,10 st y+,temp ldi temp,11 st y+,temp ldi temp,20 st y+,temp ldi temp,22 st y,temp ldi zl,low(XSDBZ) clr zh ldi temp,0b00100000 ;b0-5对应LED自左到右1-6位的小数点,置“1”在该位置小数点。 st z,temp rcall display sbis pinb,5 rjmp GNCS1 ;进入工作参数设置 dec temp3 brne BP4M4 inc temp3 dec temp4 brne BP4M4 sbic pinb,4 rjmp BP4M rjmp res1 ;****时钟调整****************************************************************** cloc: clr temp out timsk,temp ;不许T0中断 cli ;关中断 rcall colodis mov temp,r10 clr temp4 ldi temp1,20 ldi temp3,$80 cloc3: ldi yl,low(DISBUF) add yl,temp4 sbic pinb,5 ;选择时分秒 rjmp cloc4 dec temp1 brne cloc4 ldi temp1,80 inc temp4 inc temp4 add yl,temp4 cpi yl,$68 brmi cloc4 clr temp4 ldi yl,low(DISBUF) cloc4: nop sbic pinb,6 ;调整时分秒值 rjmp cloc8 dec temp3 brne cloc8 ldi temp3,$20 cloc5: cpi yl,$60 brne cloc6 inc r10 mov temp,r10 cpi temp,24 brmi cloc8 clr temp clr r10 cloc6: cpi yl,$62 brne cloc7 inc r11 mov temp,r11 cpi temp,60 brmi cloc8 clr temp clr r11 cloc7: cpi yl,$64 brne cloc8 inc r12 mov temp,r12 cpi temp,60 brmi cloc8 clr temp clr r12 cloc8: cpi yl,$60 brne cloc9 ldi zl,low(XSDBZ) clr zh ldi temp,0b00000010 ;b0-5对应LED自左到右1-6位的小数点,置“1”在该位置小数点。 st z,temp mov r16,r10 rjmp cloc11 cloc9: cpi yl,$62 brne cloc10 ldi zl,low(XSDBZ) clr zh ldi temp,0b00001000 ;b0-5对应LED自左到右1-6位的小数点,置“1”在该位置小数点。 st z,temp mov r16,r11 cloc10: cpi yl,$64 brne cloc11 ldi zl,low(XSDBZ) clr zh ldi temp,0b00100000 ;b0-5对应LED自左到右1-6位的小数点,置“1”在该位置小数点。 st z,temp mov r16,r12 cloc11: rcall bto st y+,r3 st y,r4 rcall display sbis pinb,4 ;退出 rjmp cloc12 rjmp cloc3 cloc12: ldi temp,$02 out timsk,temp ;允许T0中断 sei ;开中断 rjmp res1 ;****32点打铃器工作参数调整********************************************************** GNCS1: clr r25 ;首个控制点 clr r22 ;r22为0显示开关页面,为1显示h-xx页面,为2显示m-xx页面,为3显示c-xx页面 ldi zl,low(XSDBZ) clr zh ldi r19,0b00000010 st z,r19 gncs: ldi r17,TIMECTR ;首个控制点EEPRON地址 clr r18 ldi yl,low(DISBUF) ;设置显示缓冲区起始地址 clr yh lsl r25 lsl r25 add r17,r25 ;取得EEPRON中控制点地址(Aj=A0+4*j),A=(r17),j=(r25) lsr r25 lsr r25 mov r16,r25 rcall bto st y+,r3 st y+,r4 cpi r22,0 breq kgymxs cpi r22,1 breq hymxs cpi r22,2 breq mymxs cpi r22,3 breq cymxs clr r22 rjmp gncs kgymxs: rcall EERead cpi r16,0 brne offxs ldi r23,27 ;显示xx.--on st y+,r23 st y+,r23 ldi r23,20 st y+,r23 ldi r23,26 st y,r23 rjmp gzcsxs offxs: ldi r23,27 ;显示xx.-off st y+,r23 ldi r23,20 st y+,r23 ldi r23,15 st y+,r23 st y,r23 rjmp gzcsxs hymxs: ldi r23,28 ;显示xx.h-aa st y+,r23 ldi r23,27 st y+,r23 inc r17 rcall EERead rcall bto st y+,r3 st y+,r4 dec r17 rjmp gzcsxs mymxs: ldi r23,26 ;显示xx.n-aa st y+,r23 ldi r23,27 st y+,r23 inc r17 inc r17 rcall EERead rcall bto st y+,r3 st y+,r4 dec r17 dec r17 rjmp gzcsxs cymxs: ldi r23,18 ;显示xx.c-aa st y+,r23 ldi r23,27 st y+,r23 inc r17 inc r17 inc r17 rcall EERead rcall bto st y+,r3 st y+,r4 dec r17 dec r17 dec r17 gzcsxs: ldi r23,40 ldi r24,40 gzcsxs1: rcall display sbis pinb,5 ;翻页 rjmp fycz ;有,去翻页 sbis pinb,6 ;变值 rjmp bzcz ;有,去变值 sbis pinb,4 ;复位 rjmp res1 ;有,去复位 rjmp gncs fycz: dec r23 brne gzcsxs1 rcall EERead cpi r16,0 brne fycz1 inc r22 cpi r22,4 brmi fycz2 clr r22 fycz1: inc r25 cpi r25,32 brmi fycz2 clr r25 fycz2: rjmp gncs bzcz: dec r24 brne gzcsxs1 cpi r22,0 brne bzcz2 bzcz1: rcall EERead cpi r16,0 breq bzcz11 clr r16 rjmp bzcz12 bzcz11: ldi r16,1 bzcz12: rcall EEWrite rjmp gncs bzcz2: add r17,r22 rcall EERead inc r16 cpi r22,1 breq bzcz21 cpi r16,60 brmi bzcz22 clr r16 rjmp bzcz22 bzcz21: cpi r16,24 brmi bzcz22 clr r16 bzcz22: rcall EEWrite sub r17,r22 rjmp gncs ;****显示子程序*********************************************************************** ;* ;* 功能:将SRAM显示缓冲区存放的数送数码管显示 ;* 入口:DISBUF---显示缓冲区起始地址(SRAM) ;* Y--显示缓冲区的指针 ;* DISTBL---显示字符编码表起始地址(FLASH) ;* LEDSXW---LED闪显寄存器位设置 ;* XSDBZ----小数点设置 ;* 出口:Y--显示缓冲区的指针,指向高地址 ;* ;****程序段 display: nop push temp push temp1 push temp2 push temp3 push temp4 push r6 ldi temp1,6 ldi temp3,0b11011111 ldi yl,low(DISBUF) ldi yh,high(DISBUF) ldi xl,low(XSDBZ) clr xh ld r6,x disp1: ld temp,y+ ldi zl,low(DISTBL) ldi zh,high(DISTBL) add zl,temp lsl zl rol zh lpm lsr r6 brcc disp2 ldi temp4,0b10000000 or r0,temp4 disp2: out PORTC,r0 in temp2,PORTA ori temp2,0b00111111 and temp2,temp3 out PORTA,temp2 sec ror temp3 rcall delay in temp2,PORTA ori temp2,0b00111111 out PORTA,temp2 ;关显示 dec temp1 brne disp1 pop r6 pop temp4 pop temp3 pop temp2 pop temp1 pop temp ret ;****时钟显示子程序********************************************************************* colodis: push temp ldi yl,low(DISBUF) ;设置显示缓冲区起始地址 clr yh ldi xl,low(TIMEDIS) ;设置时钟时分秒存放单元 clr xh ldi zl,low(XSDBZ) clr zh ldi temp,0b00001010 ;b0-5对应LED自左到右1-6位的小数点,置“1”在该位置小数点。 st z,temp rcall ram6ram rcall display pop temp ret ;****延时子程序********************************************************************** delay: nop ;延时子程序 push temp2 push temp1 ldi temp2,$ff lp1: ldi temp1,$f lp2: dec temp1 brne lp2 dec temp2 brne lp1 pop temp1 pop temp2 ret ;子程序返回 ;****写EEPRON子程序********************************************************************* ;* ;*功能:将EEDWR(r16)内容写入以EEAWR(r18:r17)内容为地址的EEPRON单元内。 ;* ;****程序段 EEWrite:sbic EECR,EEWE rjmp EEWrite out EEARH,EEawrh out EEARL,EEawr out EEDR,EEdwr sbi EECR,EEMWE sbi EECR,EEWE ret ;****读EEPRON子程序********************************************************************* ;* ;*功能:从以EEARD(r18:r17)内容为地址的EEPRON单元读区内容送EEDRD(r16)寄存器。 ;* ;****程序段 EERead: sbic EECR,EEWE rjmp EERead out EEARH,EEardh out EEARL,EEard sbi EECR,EERE sbi EECR,EERE in EEdrd,EEDR ret ;****6字节SRAM内容传送子程序************************************************************ ;* ;* 功能:将SRAM内连续6字节由BLOCK1传送到BLOCK2 ;* x---欲传送6字节起始地址(SRAM)指针 ;* y---欲放置6字节起始地址(SRAM)指针 ;* ;****程序段 ram6ram:push temp1 push temp2 ldi temp1,$06 ramd1: ld temp2,x+ st y+,temp2 dec temp1 brne ramd1 pop temp2 pop temp1 ret ;****8位二进制数转3位BCD数子程序******************************************************** ;* ;*功能:把一个8位无符号二进制数转换为3位BCD码数。 ;*入口:r16---内装8位无符号二进制数。 ;*出口:BCD码放在r2:r3:r4,r2存放百位。 ;* ;****程序段 bto: push r16 clr r2 clr r3 clr r4 rjmp bto2 bto1: inc r2 bto2: subi r16,100 brpl bto1 ldi temp,100 add r16,temp rjmp bto4 bto3: inc r3 bto4: subi r16,10 brpl bto3 ldi temp,10 add r16,temp mov r4,r16 pop r16 ret ;****时钟0中断服务程序****************************************************** .org $0bf0 TIM0_OVF: push temp ldi temp,256-195 out tcnt0,temp ;重装T0时间常数 inc cntms mov temp,cntms cpi temp,40 brne timecunt clr cntms inc second mov temp,second cpi temp,60 brne timecunt clr second ldi TIM0INT,1 inc minute mov temp,minute cpi temp,60 brne timecunt clr minute inc hour mov temp,hour cpi temp,24 brne timecunt clr hour timecunt: ldi xl, low(TIMEDIS) clr xh mov r16,hour rcall bto st x+,r3 st x+,r4 mov r16,minute rcall bto st x+,r3 st x+,r4 mov r16,second rcall bto st x+,r3 st x+,r4 pop temp reti ;****字形表***************************************************************** .cseg .org DISTBL .dw 0x003f,0x0006,0x005b,0x004f,0x0066,0x006d,0x007d,0x0007,0x007f,0x006f .dw 0x0077,0x007c,0x0039,0x005e,0x0079,0x0071,0x0073,0x0076,0x0058,0x0038 .dw 0x005c,0x0067,0x0050,0x006e,0x0078,0x0000,0x0054,0x0040,0x0074,0x0000 ;*********************************END***************************************