📄 tc0_timer.lst
字号:
__start:
__text_start:
0009 C098 RJMP _Timer0
000A E0D2 LDI R29,2
000B BFCD OUT 0x3D,R28
000C BFDE OUT 0x3E,R29
000D 51C0 SUBI R28,0x10
000E 40D0 SBCI R29,0
000F EA0A LDI R16,0xAA
0010 8308 STD Y+0,R16
0011 2400 CLR R0
0012 E7E1 LDI R30,0x71
0013 E0F0 LDI R31,0
0014 E010 LDI R17,0
0015 37E1 CPI R30,0x71
0016 07F1 CPC R31,R17
0017 F011 BEQ 0x001A
0018 9201 ST R0,Z+
0019 CFFB RJMP 0x0015
001A 8300 STD Z+0,R16
001B E0E0 LDI R30,0
001C E0F0 LDI R31,0
001D E6A0 LDI R26,0x60
001E E0B0 LDI R27,0
001F E010 LDI R17,0
0020 31E1 CPI R30,0x11
0021 07F1 CPC R31,R17
0022 F021 BEQ 0x0027
0023 95C8 LPM
0024 9631 ADIW R30,1
0025 920D ST R0,X+
0026 CFF9 RJMP 0x0020
0027 D061 RCALL _main
_exit:
0028 CFFF RJMP _exit
_DelayMs:
j --> R20
i --> R16
0029 D0BE RCALL push_gset1
FILE: C:\DOCUME~1\Administrator\桌面\张军\AVR\AVR单片机系统开发实例稿\第二章\第二章程序\定时计数器的C语言编程\基于TC0的时钟设计\Timer.C
(0001) //***************FileName:Timer.C******************//
(0002) //***************ICCAVR V6.30编译*****************//
(0003)
(0004) #include <io8535v.h>
(0005) #define uchar unsigned char
(0006) #define uint unsigned int
(0007)
(0008) //数码管字型表,对应0,1,2,3,4,5,6,7,8,9//
(0009) uchar Table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
(0010) uchar Data[4]={0,0,0,0}; //显示初始值:0 0 0 0
(0011) uchar CNT=0; //初始计数值:0
(0012) uchar Timer[2]={0x00,0x00}; //初始时间00:00
(0013)
(0014) void DelayMs(uint i) //Ms级延时,参数i为延时时间
(0015) {uint j;
(0016) for(;i!=0;i--)
002A C00A RJMP 0x0035
(0017) {for(j=8000;j!=0;j--) {;}}
002B E440 LDI R20,0x40
002C E15F LDI R21,0x1F
002D C002 RJMP 0x0030
002E 5041 SUBI R20,1
002F 4050 SBCI R21,0
0030 3040 CPI R20,0
0031 0745 CPC R20,R21
0032 F7D9 BNE 0x002E
0033 5001 SUBI R16,1
0034 4010 SBCI R17,0
0035 3000 CPI R16,0
0036 0701 CPC R16,R17
0037 F799 BNE 0x002B
(0018) }
0038 D0B2 RCALL pop_gset1
0039 9508 RET
_Display:
sel --> R20
i --> R22
p --> R10
003A D0C7 RCALL push_gset3
003B 2EA0 MOV R10,R16
003C 2EB1 MOV R11,R17
(0019)
(0020) void Display(uchar *p) //动态显示函数,参数p为待显示的数组名
(0021) {uchar i,sel=0x01;
003D E041 LDI R20,1
(0022) for(i=0;i<4;i++)
003E 2766 CLR R22
003F C012 RJMP 0x0052
(0023) {PORTB=sel; //选通最右边的数码管
0040 BB48 OUT 0x18,R20
(0024) PORTC=Table[p[i]]; //送字型码
0041 2FE6 MOV R30,R22
0042 27FF CLR R31
0043 0DEA ADD R30,R10
0044 1DFB ADC R31,R11
0045 81E0 LDD R30,Z+0
0046 27FF CLR R31
0047 E680 LDI R24,0x60
0048 E090 LDI R25,0
0049 0FE8 ADD R30,R24
004A 1FF9 ADC R31,R25
004B 8020 LDD R2,Z+0
004C BA25 OUT 0x15,R2
(0025) DelayMs(2); //显示延时
004D E002 LDI R16,2
004E E010 LDI R17,0
004F DFD9 RCALL _DelayMs
(0026) sel=sel<<1; //移位以显示前一位
0050 0F44 LSL R20
0051 9563 INC R22
0052 3064 CPI R22,4
0053 F360 BCS 0x0040
(0027) }
(0028) }
0054 D091 RCALL pop_gset3
0055 9508 RET
_Process:
p2 --> R20
p1 --> R22
0056 D0A8 RCALL push_gset2
0057 2F42 MOV R20,R18
0058 2F53 MOV R21,R19
0059 2F60 MOV R22,R16
005A 2F71 MOV R23,R17
(0029)
(0030) //计数值处理函数。参数p1:时间数组名;参数p2:显示数组名//
(0031) //功能:此函数用于将计数值拆分为BCD码的10分,分,10秒,秒//
(0032) void Process(uchar *p1,uchar *p2)
(0033) {p2[0]=p1[0]/10;
005B E01A LDI R17,0xA
005C 2FE6 MOV R30,R22
005D 2FF7 MOV R31,R23
005E 8100 LDD R16,Z+0
005F D06E RCALL div8u
0060 2FE4 MOV R30,R20
0061 2FF5 MOV R31,R21
0062 8300 STD Z+0,R16
(0034) p2[1]=p1[0]-p2[0]*10;
0063 8110 LDD R17,Z+0
0064 E00A LDI R16,0xA
0065 D09F RCALL mpy8s
0066 2FE6 MOV R30,R22
0067 2FF7 MOV R31,R23
0068 8020 LDD R2,Z+0
0069 1A20 SUB R2,R16
006A 2FE4 MOV R30,R20
006B 2FF5 MOV R31,R21
006C 8221 STD Z+1,R2
(0035) p2[2]=p1[1]/10;
006D E01A LDI R17,0xA
006E 2FE6 MOV R30,R22
006F 2FF7 MOV R31,R23
0070 8101 LDD R16,Z+1
0071 D05C RCALL div8u
0072 2FE4 MOV R30,R20
0073 2FF5 MOV R31,R21
0074 8302 STD Z+2,R16
(0036) p2[3]=p1[1]-p2[2]*10;
0075 2FE4 MOV R30,R20
0076 2FF5 MOV R31,R21
0077 8112 LDD R17,Z+2
0078 E00A LDI R16,0xA
0079 D08B RCALL mpy8s
007A 2FE6 MOV R30,R22
007B 2FF7 MOV R31,R23
007C 8021 LDD R2,Z+1
007D 1A20 SUB R2,R16
007E 2FE4 MOV R30,R20
007F 2FF5 MOV R31,R21
0080 8223 STD Z+3,R2
(0037) }
0081 D062 RCALL pop_gset2
0082 9508 RET
(0038)
(0039) void Init_IO(void) //初始化I/O口
(0040) {DDRA=0xff; //设置A口为推挽1输出
_Init_IO:
0083 EF8F LDI R24,0xFF
0084 BB8A OUT 0x1A,R24
(0041) PORTA=0xff;
0085 BB8B OUT 0x1B,R24
(0042) DDRC=0xff; //设置C口为推挽1输出;
0086 BB84 OUT 0x14,R24
(0043) PORTC=0xff;
0087 BB85 OUT 0x15,R24
(0044) }
0088 9508 RET
(0045)
(0046) void main(void)
(0047) {uchar Load;
(0048) Init_IO(); //初始化I/O口
_main:
Load --> Y+1
0089 DFF9 RCALL _Init_IO
(0049) PORTA=0xff; //点亮以测试所有的数码管
008A EF8F LDI R24,0xFF
008B BB8B OUT 0x1B,R24
(0050) PORTC=0x00;
008C 2422 CLR R2
008D BA25 OUT 0x15,R2
(0051) DelayMs(3000); //延时
008E EB08 LDI R16,0xB8
008F E01B LDI R17,0xB
0090 DF98 RCALL _DelayMs
(0052) PORTC=0xff; //熄灭所有的数码管
0091 EF8F LDI R24,0xFF
0092 BB85 OUT 0x15,R24
(0053) TCCR0=0x04; //T/C0工作于定时方式,系统时钟256分频
0093 E084 LDI R24,4
0094 BF83 OUT 0x33,R24
(0054) TCNT0=0x06; //计数初始值6
0095 E086 LDI R24,6
0096 BF82 OUT 0x32,R24
0097 C008 RJMP 0x00A0
(0055) while(1)
(0056) {Process(Timer,Data); //计数值处理
0098 E62A LDI R18,0x6A
0099 E030 LDI R19,0
009A E60F LDI R16,0x6F
009B E010 LDI R17,0
009C DFB9 RCALL _Process
(0057) Display(Data); //动态扫描显示
009D E60A LDI R16,0x6A
009E E010 LDI R17,0
009F DF9A RCALL _Display
00A0 CFF7 RJMP 0x0098
(0058) }
(0059) }
00A1 9508 RET
_Timer0:
00A2 922A ST R2,-Y
00A3 938A ST R24,-Y
00A4 939A ST R25,-Y
00A5 B62F IN R2,0x3F
00A6 922A ST R2,-Y
(0060)
(0061) //********************T/C0中断服务函数********************//
(0062) #pragma interrupt_handler Timer0:10
(0063) void Timer0(void)
(0064) {CNT++; //中断次数累加
00A7 9180006E LDS R24,0x6E
00A9 5F8F SUBI R24,0xFF
00AA 9380006E STS 0x6E,R24
(0065) if(CNT==125)
00AC 378D CPI R24,0x7D
00AD F4C1 BNE 0x00C6
(0066) {CNT=0; //计数到125次,计数值复位
00AE 2422 CLR R2
00AF 9220006E STS 0x6E,R2
(0067) Timer[1]++; //秒加1
00B1 91800070 LDS R24,0x70
00B3 5F8F SUBI R24,0xFF
00B4 93800070 STS 0x70,R24
(0068) if(Timer[1]==60)
00B6 338C CPI R24,0x3C
00B7 F439 BNE 0x00BF
(0069) {Timer[1]=0;
00B8 92200070 STS 0x70,R2
(0070) Timer[0]++;} //分进位
00BA 9180006F LDS R24,0x6F
00BC 5F8F SUBI R24,0xFF
00BD 9380006F STS 0x6F,R24
(0071) if(Timer[0]==60)
00BF 9180006F LDS R24,0x6F
00C1 338C CPI R24,0x3C
00C2 F419 BNE 0x00C6
(0072) Timer[0]=0;} //计数到达最高位,计数复位
00C3 2422 CLR R2
00C4 9220006F STS 0x6F,R2
(0073) }
FILE: <library>
00C6 9029 LD R2,Y+
00C7 BE2F OUT 0x3F,R2
00C8 9199 LD R25,Y+
00C9 9189 LD R24,Y+
00CA 9029 LD R2,Y+
00CB 9518 RETI
mod8u:
00CC 9468 BSET 6
00CD C001 RJMP xdiv8u
div8u:
00CE 94E8 BCLR 6
xdiv8u:
00CF 932A ST R18,-Y
00D0 92FA ST R15,-Y
00D1 92EA ST R14,-Y
00D2 24FF CLR R15
00D3 24EE CLR R14
00D4 E120 LDI R18,0x10
00D5 0F00 LSL R16
00D6 1CFF ROL R15
00D7 1CEE ROL R14
00D8 16E1 CP R14,R17
00D9 F010 BCS 0x00DC
00DA 1AE1 SUB R14,R17
00DB 9503 INC R16
00DC 952A DEC R18
00DD F7B9 BNE 0x00D5
00DE F40E BRTC 0x00E0
00DF 2D0E MOV R16,R14
00E0 90E9 LD R14,Y+
00E1 90F9 LD R15,Y+
00E2 9129 LD R18,Y+
00E3 9508 RET
pop_gset2:
00E4 E0E2 LDI R30,2
00E5 C006 RJMP pop
pop_gset3:
00E6 E0E4 LDI R30,4
00E7 C004 RJMP pop
push_gset1:
00E8 935A ST R21,-Y
00E9 934A ST R20,-Y
00EA 9508 RET
pop_gset1:
00EB E0E1 LDI R30,1
pop:
00EC 9149 LD R20,Y+
00ED 9159 LD R21,Y+
00EE FDE0 SBRC R30,0
00EF 9508 RET
00F0 9169 LD R22,Y+
00F1 9179 LD R23,Y+
00F2 FDE1 SBRC R30,1
00F3 9508 RET
00F4 90A9 LD R10,Y+
00F5 90B9 LD R11,Y+
00F6 FDE2 SBRC R30,2
00F7 9508 RET
00F8 90C9 LD R12,Y+
00F9 90D9 LD R13,Y+
00FA FDE3 SBRC R30,3
00FB 9508 RET
00FC 90E9 LD R14,Y+
00FD 90F9 LD R15,Y+
00FE 9508 RET
push_gset2:
00FF 937A ST R23,-Y
0100 936A ST R22,-Y
0101 CFE6 RJMP push_gset1
push_gset3:
0102 92BA ST R11,-Y
0103 92AA ST R10,-Y
0104 CFFA RJMP push_gset2
mpy8s:
0105 920A ST R0,-Y
0106 2400 CLR R0
0107 2300 TST R16
0108 F029 BEQ 0x010E
0109 9506 LSR R16
010A F408 BCC 0x010C
010B 0E01 ADD R0,R17
010C 0F11 LSL R17
010D CFF9 RJMP 0x0107
010E 2D00 MOV R16,R0
010F 9009 LD R0,Y+
0110 9508 RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -