📄 定时器.lst
字号:
(0128) LCD_write_command( address);
00E6 2F04 MOV R16,R20
00E7 DFB3 RCALL _LCD_write_command
00E8 940E01C1 CALL pop_gset2
00EA 9508 RET
_LCD_write_string:
s --> R20
Y --> R10
X --> R22
00EB 940E01CB CALL push_gset3
00ED 2EA2 MOV R10,R18
00EE 2F60 MOV R22,R16
00EF 814E LDD R20,Y+6
00F0 815F LDD R21,Y+7
(0129) }
(0130)
(0131) void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s) //列x=0~15,行y=0,1
(0132) {
(0133) LCD_set_xy( X, Y ); //写地址
00F1 2D2A MOV R18,R10
00F2 2F06 MOV R16,R22
00F3 DFE7 RCALL _LCD_set_xy
00F4 C005 RJMP 0x00FA
(0134) while (*s) // 写显示字符
(0135) {
(0136) LCD_write_data( *s );
00F5 01FA MOVW R30,R20
00F6 8100 LDD R16,Z+0
00F7 DFC3 RCALL _LCD_write_data
(0137) s ++;
00F8 5F4F SUBI R20,0xFF
00F9 4F5F SBCI R21,0xFF
00FA 01FA MOVW R30,R20
00FB 8020 LDD R2,Z+0
00FC 2022 TST R2
00FD F7B9 BNE 0x00F5
00FE 940E01C4 CALL pop_gset3
0100 9508 RET
_LCD_write_char:
data --> Y+4
Y --> R22
X --> R20
0101 940E01CD CALL push_gset2
0103 2F62 MOV R22,R18
0104 2F40 MOV R20,R16
(0138) }
(0139)
(0140) }
(0141)
(0142) void LCD_write_char(unsigned char X,unsigned char Y,unsigned char data) //列x=0~15,行y=0,1
(0143) {
(0144) LCD_set_xy( X, Y ); //写地址
0105 2F26 MOV R18,R22
0106 2F04 MOV R16,R20
0107 DFD3 RCALL _LCD_set_xy
(0145) LCD_write_data( data);
0108 810C LDD R16,Y+4
0109 DFB1 RCALL _LCD_write_data
010A 940E01C1 CALL pop_gset2
010C 9508 RET
_process:
p --> R20
i --> R22
010D 940E01CD CALL push_gset2
010F 01A9 MOVW R20,R18
0110 01B8 MOVW R22,R16
FILE: D:\avr\+++精华+++\+M16范例+\定时器\main.c
(0001) /*****************************************
(0002) * 基于T/C0的定时器设计 *
(0003) * 功 能:定时器 *
(0004) * 时钟频率:外部7.3728M *
(0005) * 设 计:莫锦攀 *
(0006) * 修改日期:2007年07月30日 *
(0007) * 编译环境:ICC-AVR6.31 *
(0008) * 实验环境:M16学习板 *
(0009) * 使用端口:PC6,PC7,PA4~PA7 *
(0010) *使用1M频率时不够精确所以用8M的了,注意要 *
(0011) *使用T/C0定时功能前的初始化工作 *
(0012) *****************************************/
(0013)
(0014)
(0015) #include <iom16v.h>
(0016) #include "1602.h"
(0017) #include "delay.h"
(0018)
(0019) #define uchar unsigned char
(0020) #define uint unsigned int
(0021)
(0022) uchar data[5]={0,0,0,0,0};//显示的初始值:0,0,0,0
(0023) uint cnt=0; //初始计数值:0
(0024) uchar timer[2]={0,0};//初始时间00:00
(0025)
(0026)
(0027)
(0028) //********计数值处理函数******************//
(0029) void process(uchar *i,uchar *p)
(0030) {p[0]=i[0]/10+48;//分的高位
0111 E01A LDI R17,0xA
0112 01FB MOVW R30,R22
0113 8100 LDD R16,Z+0
0114 940E01AB CALL div8u
0116 2F80 MOV R24,R16
0117 5D80 SUBI R24,0xD0
0118 01FA MOVW R30,R20
0119 8380 STD Z+0,R24
(0031) p[1]=i[0]%10+48;//分的低位
011A E01A LDI R17,0xA
011B 01FB MOVW R30,R22
011C 8100 LDD R16,Z+0
011D 940E01A9 CALL mod8u
011F 2F80 MOV R24,R16
0120 5D80 SUBI R24,0xD0
0121 01FA MOVW R30,R20
0122 8381 STD Z+1,R24
(0032)
(0033) p[2]=i[1]/10+48;//秒的高位
0123 E01A LDI R17,0xA
0124 01FB MOVW R30,R22
0125 8101 LDD R16,Z+1
0126 940E01AB CALL div8u
0128 2F80 MOV R24,R16
0129 5D80 SUBI R24,0xD0
012A 01FA MOVW R30,R20
012B 8382 STD Z+2,R24
(0034) p[3]=i[1]%10+48;//秒的低位
012C E01A LDI R17,0xA
012D 01FB MOVW R30,R22
012E 8101 LDD R16,Z+1
012F 940E01A9 CALL mod8u
0131 2F80 MOV R24,R16
0132 5D80 SUBI R24,0xD0
0133 01FA MOVW R30,R20
0134 8383 STD Z+3,R24
0135 940E01C1 CALL pop_gset2
0137 9508 RET
_lcd:
0138 9722 SBIW R28,2
(0035) //注意这里加48是因为ASCII码中数字都要加48的原因
(0036) }
(0037)
(0038)
(0039) //************液晶显示函数******************//
(0040) void lcd(void)
(0041) {
(0042) LCD_write_string(2,0,"Timer by MJP");
0139 E689 LDI R24,0x69
013A E090 LDI R25,0
013B 8399 STD Y+1,R25
013C 8388 STD Y+0,R24
013D 2722 CLR R18
013E E002 LDI R16,2
013F DFAB RCALL _LCD_write_string
(0043) LCD_write_char(6,1,data[0]);
0140 90200060 LDS R2,data
0142 8228 STD Y+0,R2
0143 E021 LDI R18,1
0144 E006 LDI R16,6
0145 DFBB RCALL _LCD_write_char
(0044) LCD_write_char(7,1,data[1]);
0146 90200061 LDS R2,data+1
0148 8228 STD Y+0,R2
0149 E021 LDI R18,1
014A E007 LDI R16,7
014B DFB5 RCALL _LCD_write_char
(0045) LCD_write_char(8,1,':');
014C E38A LDI R24,0x3A
014D 8388 STD Y+0,R24
014E E021 LDI R18,1
014F E008 LDI R16,0x8
0150 DFB0 RCALL _LCD_write_char
(0046) LCD_write_char(9,1,data[2]);
0151 90200062 LDS R2,data+2
0153 8228 STD Y+0,R2
0154 E021 LDI R18,1
0155 E009 LDI R16,0x9
0156 DFAA RCALL _LCD_write_char
(0047) LCD_write_char(10,1,data[3]);
0157 90200063 LDS R2,data+3
0159 8228 STD Y+0,R2
015A E021 LDI R18,1
015B E00A LDI R16,0xA
015C DFA4 RCALL _LCD_write_char
015D 9622 ADIW R28,2
015E 9508 RET
_Timer0:
015F 922A ST R2,-Y
0160 923A ST R3,-Y
0161 938A ST R24,-Y
0162 939A ST R25,-Y
0163 93EA ST R30,-Y
0164 B62F IN R2,0x3F
0165 922A ST R2,-Y
(0048) }
(0049)
(0050) //************T/C0中断服务函数******************//
(0051) #pragma interrupt_handler Timer0:10
(0052) void Timer0(void)
(0053) {cnt++;
0166 91800065 LDS R24,cnt
0168 91900066 LDS R25,cnt+1
016A 9601 ADIW R24,1
016B 93900066 STS cnt+1,R25
016D 93800065 STS cnt,R24
(0054) if(cnt==450)//450*64*256=7372800
016F 3C82 CPI R24,0xC2
0170 E0E1 LDI R30,1
0171 079E CPC R25,R30
0172 F4D9 BNE 0x018E
(0055) {cnt=0;
0173 2422 CLR R2
0174 2433 CLR R3
0175 92300066 STS cnt+1,R3
0177 92200065 STS cnt,R2
(0056) timer[1]++;//秒加1
0179 91800068 LDS R24,timer+1
017B 5F8F SUBI R24,0xFF
017C 93800068 STS timer+1,R24
(0057) if(timer[1]==60){timer[1]=0;timer[0]++;}//分加1
017E 338C CPI R24,0x3C
017F F439 BNE 0x0187
0180 92200068 STS timer+1,R2
0182 91800067 LDS R24,timer
0184 5F8F SUBI R24,0xFF
0185 93800067 STS timer,R24
(0058) if(timer[0]==60){timer[0]=0;}//计数达到最高,重新开始
0187 91800067 LDS R24,timer
0189 338C CPI R24,0x3C
018A F419 BNE 0x018E
018B 2422 CLR R2
018C 92200067 STS timer,R2
(0059) }
018E 9029 LD R2,Y+
018F BE2F OUT 0x3F,R2
0190 91E9 LD R30,Y+
0191 9199 LD R25,Y+
0192 9189 LD R24,Y+
0193 9039 LD R3,Y+
0194 9029 LD R2,Y+
0195 9518 RETI
(0060) }
(0061)
(0062)
(0063)
(0064) //************初始化函数******************//
(0065) void init(void)
(0066) {
(0067) LCD_init();//液晶初始化
_init:
0196 DEE9 RCALL _LCD_init
(0068) SEI();//开全局中断
0197 9478 BSET 7
(0069) TCCR0=0x03;//系统时钟64分频
0198 E083 LDI R24,3
0199 BF83 OUT 0x33,R24
(0070) TCNT0=0x00;//tcnt清零
019A 2422 CLR R2
019B BE22 OUT 0x32,R2
(0071) TIMSK=0x01;//打开T/C中断屏蔽寄存器
019C E081 LDI R24,1
019D BF89 OUT 0x39,R24
019E 9508 RET
(0072) }
(0073)
(0074) void main(void)
(0075) {init();//初始化
_main:
019F DFF6 RCALL _init
01A0 C006 RJMP 0x01A7
(0076) while(1)
(0077) {
(0078) process(timer,data);//计数值处理
01A1 E620 LDI R18,0x60
01A2 E030 LDI R19,0
01A3 E607 LDI R16,0x67
01A4 E010 LDI R17,0
01A5 DF67 RCALL _process
(0079) lcd();//显示
FILE: <library>
01A6 DF91 RCALL _lcd
01A7 CFF9 RJMP 0x01A1
01A8 9508 RET
mod8u:
01A9 9468 BSET 6
01AA C001 RJMP xdiv8u
div8u:
01AB 94E8 BCLR 6
xdiv8u:
01AC 932A ST R18,-Y
01AD 92FA ST R15,-Y
01AE 92EA ST R14,-Y
01AF 24FF CLR R15
01B0 24EE CLR R14
01B1 E120 LDI R18,0x10
01B2 0F00 LSL R16
01B3 1CFF ROL R15
01B4 1CEE ROL R14
01B5 16E1 CP R14,R17
01B6 F010 BCS 0x01B9
01B7 1AE1 SUB R14,R17
01B8 9503 INC R16
01B9 952A DEC R18
01BA F7B9 BNE 0x01B2
01BB F40E BRTC 0x01BD
01BC 2D0E MOV R16,R14
01BD 90E9 LD R14,Y+
01BE 90F9 LD R15,Y+
01BF 9129 LD R18,Y+
01C0 9508 RET
pop_gset2:
01C1 E0E2 LDI R30,2
01C2 940C01D3 JMP pop
pop_gset3:
01C4 E0E4 LDI R30,4
01C5 940C01D3 JMP pop
push_gset5:
01C7 92FA ST R15,-Y
01C8 92EA ST R14,-Y
push_gset4:
01C9 92DA ST R13,-Y
01CA 92CA ST R12,-Y
push_gset3:
01CB 92BA ST R11,-Y
01CC 92AA ST R10,-Y
push_gset2:
01CD 937A ST R23,-Y
01CE 936A ST R22,-Y
push_gset1:
01CF 935A ST R21,-Y
01D0 934A ST R20,-Y
01D1 9508 RET
pop_gset1:
01D2 E0E1 LDI R30,1
pop:
01D3 9149 LD R20,Y+
01D4 9159 LD R21,Y+
01D5 FDE0 SBRC R30,0
01D6 9508 RET
01D7 9169 LD R22,Y+
01D8 9179 LD R23,Y+
01D9 FDE1 SBRC R30,1
01DA 9508 RET
01DB 90A9 LD R10,Y+
01DC 90B9 LD R11,Y+
01DD FDE2 SBRC R30,2
01DE 9508 RET
01DF 90C9 LD R12,Y+
01E0 90D9 LD R13,Y+
01E1 FDE3 SBRC R30,3
01E2 9508 RET
01E3 90E9 LD R14,Y+
01E4 90F9 LD R15,Y+
01E5 9508 RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -