📄 频率计.lst
字号:
(0101) void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s) //列x=0~15,行y=0,1
(0102) {
(0103) LCD_set_xy( X, Y ); //写地址
00EF 2D2A MOV R18,R10
00F0 2F06 MOV R16,R22
00F1 DFE7 RCALL _LCD_set_xy
00F2 C005 RJMP 0x00F8
(0104) while (*s) // 写显示字符
(0105) {
(0106) LCD_write_data( *s );
00F3 01FA MOVW R30,R20
00F4 8100 LDD R16,Z+0
00F5 DFC3 RCALL _LCD_write_data
(0107) s ++;
00F6 5F4F SUBI R20,0xFF
00F7 4F5F SBCI R21,0xFF
00F8 01FA MOVW R30,R20
00F9 8020 LDD R2,Z+0
00FA 2022 TST R2
00FB F7B9 BNE 0x00F3
00FC 940E01DC CALL pop_gset3
00FE 9508 RET
_LCD_write_char:
data --> Y+4
Y --> R22
X --> R20
00FF 940E01E5 CALL push_gset2
0101 2F62 MOV R22,R18
0102 2F40 MOV R20,R16
(0108) }
(0109)
(0110) }
(0111)
(0112) void LCD_write_char(unsigned char X,unsigned char Y,unsigned char data) //列x=0~15,行y=0,1
(0113) {
(0114) LCD_set_xy( X, Y ); //写地址
0103 2F26 MOV R18,R22
0104 2F04 MOV R16,R20
0105 DFD3 RCALL _LCD_set_xy
(0115) LCD_write_data( data);
0106 810C LDD R16,Y+4
0107 DFB1 RCALL _LCD_write_data
0108 940E01D9 CALL pop_gset2
010A 9508 RET
FILE: D:\avr\+++精华+++\频率计\main.c
(0001) /*****************************************
(0002) * 基于频率计程序设计 *
(0003) * 功 能:频率计 *
(0004) * 时钟频率:内部8M *
(0005) * 设 计:莫锦攀 *
(0006) * 修改日期:2007年07月05日 *
(0007) * 编译环境:ICC-AVR6.31 *
(0008) * 实验环境:M16学习板 *
(0009) * 使用端口:PC6,PC7,PA4~PA7,PD6(ICP) *
(0010) *****************************************/
(0011)
(0012) #include <iom16v.h>
(0013) #include "1602.h"
(0014)
(0015) #define uint unsigned int
(0016) #define uchar unsigned char
(0017)
(0018) uint Cnt1; //第一次捕获值
(0019) uint Cnt2; //第二次捕获值
(0020) uint Cnt; //捕获差值
(0021) uchar Flag=0; //捕获次数
(0022) uchar Data[6]={0,0,0,0,0,0};//显示初值,最后一个0是结束符,方便液晶显示
(0023)
(0024) void init_timer1(void) //初始化T/C1的输入捕获中断
(0025) {
(0026) TIMSK=1<<OCIE0; //0X02输入捕获使能
_init_timer1:
010B E082 LDI R24,2
010C BF89 OUT 0x39,R24
(0027) TCCR1B=0xC2; //输入捕获噪音使能,下降沿捕获,时钟8分频1us计数一次
010D EC82 LDI R24,0xC2
010E BD8E OUT 0x2E,R24
(0028) TIFR=1<<ICF1; //0x20写"1"清输入捕获标志位
010F E280 LDI R24,0x20
0110 BF88 OUT 0x38,R24
(0029) SREG=SREG&0x7f; //全局中断关
0111 B78F IN R24,0x3F
0112 778F ANDI R24,0x7F
0113 BF8F OUT 0x3F,R24
0114 9508 RET
_hz:
p --> R20
i --> R22
0115 940E01E5 CALL push_gset2
0117 01A9 MOVW R20,R18
0118 01B8 MOVW R22,R16
(0030) }
(0031)
(0032) void hz(uint i,uchar *p) //显示处理,+48是因为液晶显示的是ASCII码
(0033) {p[4]=i%10+48;//个
0119 E02A LDI R18,0xA
011A E030 LDI R19,0
011B 018B MOVW R16,R22
011C 940E01BD CALL mod16u
011E 01C8 MOVW R24,R16
011F 96C0 ADIW R24,0x30
0120 01FA MOVW R30,R20
0121 8384 STD Z+4,R24
(0034) p[3]=i/10%10+48;//十
0122 E02A LDI R18,0xA
0123 E030 LDI R19,0
0124 018B MOVW R16,R22
0125 940E01BF CALL div16u
0127 E02A LDI R18,0xA
0128 E030 LDI R19,0
0129 940E01BD CALL mod16u
012B 01C8 MOVW R24,R16
012C 96C0 ADIW R24,0x30
012D 01FA MOVW R30,R20
012E 8383 STD Z+3,R24
(0035) p[2]=i/100%10+48;//百
012F E624 LDI R18,0x64
0130 E030 LDI R19,0
0131 018B MOVW R16,R22
0132 940E01BF CALL div16u
0134 E02A LDI R18,0xA
0135 E030 LDI R19,0
0136 940E01BD CALL mod16u
0138 01C8 MOVW R24,R16
0139 96C0 ADIW R24,0x30
013A 01FA MOVW R30,R20
013B 8382 STD Z+2,R24
(0036) p[1]=i/1000%10+48;//千
013C EE28 LDI R18,0xE8
013D E033 LDI R19,3
013E 018B MOVW R16,R22
013F 940E01BF CALL div16u
0141 E02A LDI R18,0xA
0142 E030 LDI R19,0
0143 940E01BD CALL mod16u
0145 01C8 MOVW R24,R16
0146 96C0 ADIW R24,0x30
0147 01FA MOVW R30,R20
0148 8381 STD Z+1,R24
(0037) p[0]=i/10000%10+48;//万
0149 E120 LDI R18,0x10
014A E237 LDI R19,0x27
014B 018B MOVW R16,R22
014C 940E01BF CALL div16u
014E E02A LDI R18,0xA
014F E030 LDI R19,0
0150 940E01BD CALL mod16u
0152 01C8 MOVW R24,R16
0153 96C0 ADIW R24,0x30
0154 01FA MOVW R30,R20
0155 8380 STD Z+0,R24
0156 940E01D9 CALL pop_gset2
0158 9508 RET
_timer1:
0159 9722 SBIW R28,2
(0038) }
(0039)
(0040)
(0041) void timer1(void) //捕获检测
(0042) {if(TIFR&0x20)
015A B628 IN R2,0x38
015B FE25 SBRS R2,5
015C C04B RJMP 0x01A8
(0043) {TIFR|=0x20; //清除捕获标志位
015D B788 IN R24,0x38
015E 6280 ORI R24,0x20
015F BF88 OUT 0x38,R24
(0044) Cnt=ICR1L; //cnt暂存
0160 B426 IN R2,0x26
0161 2433 CLR R3
0162 92300073 STS Cnt+1,R3
0164 92200072 STS Cnt,R2
(0045) Cnt2=(ICR1H<<8)+ICR1L; //cnt2存放点前捕获值
0166 B426 IN R2,0x26
0167 B437 IN R3,0x27
0168 92300075 STS Cnt2+1,R3
016A 92200074 STS Cnt2,R2
(0046) Cnt=Cnt2-Cnt1; //cnt存放两次时间差
016C 90200076 LDS R2,Cnt1
016E 90300077 LDS R3,Cnt1+1
0170 90400074 LDS R4,Cnt2
0172 90500075 LDS R5,Cnt2+1
0174 1842 SUB R4,R2
0175 0853 SBC R5,R3
0176 92500073 STS Cnt+1,R5
0178 92400072 STS Cnt,R4
(0047) Cnt1=Cnt2; //cnt1存放上次捕获值
017A 90200074 LDS R2,Cnt2
017C 90300075 LDS R3,Cnt2+1
017E 92300077 STS Cnt1+1,R3
0180 92200076 STS Cnt1,R2
(0048) Flag++; //检测到第一次捕获
0182 91800060 LDS R24,Flag
0184 5F8F SUBI R24,0xFF
0185 93800060 STS Flag,R24
(0049) if(Flag==2) //检测到第二次捕获
0187 3082 CPI R24,2
0188 F4F9 BNE 0x01A8
(0050) {Flag=0; //清除捕获标志位
0189 2422 CLR R2
018A 92200060 STS Flag,R2
(0051) hz(Cnt,Data); //显示处理
018C E621 LDI R18,0x61
018D E030 LDI R19,0
018E 0182 MOVW R16,R4
018F DF85 RCALL _hz
(0052) LCD_write_string(6,1,Data); //显示
0190 E681 LDI R24,0x61
0191 E090 LDI R25,0
0192 8399 STD Y+1,R25
0193 8388 STD Y+0,R24
0194 E021 LDI R18,1
0195 E006 LDI R16,6
0196 DF52 RCALL _LCD_write_string
(0053) delay_nms(100);
0197 E604 LDI R16,0x64
0198 E010 LDI R17,0
0199 DED5 RCALL _delay_nms
(0054) Cnt=0;Cnt1=0;Cnt2=0; //清除捕获值几捕获差值
019A 2422 CLR R2
019B 2433 CLR R3
019C 92300073 STS Cnt+1,R3
019E 92200072 STS Cnt,R2
01A0 92300077 STS Cnt1+1,R3
01A2 92200076 STS Cnt1,R2
01A4 92300075 STS Cnt2+1,R3
01A6 92200074 STS Cnt2,R2
(0055) }
(0056) }
01A8 9622 ADIW R28,2
01A9 9508 RET
_main:
01AA 9722 SBIW R28,2
(0057) }
(0058)
(0059)
(0060) void main(void)
(0061) {
(0062) LCD_init();//液晶初始化
01AB DED2 RCALL _LCD_init
(0063) init_timer1();
01AC DF5E RCALL _init_timer1
(0064) DDRD=0x00;
01AD 2422 CLR R2
01AE BA21 OUT 0x11,R2
(0065) PORTD=0xff;//设置D口为带上拉电阻输入
01AF EF8F LDI R24,0xFF
01B0 BB82 OUT 0x12,R24
01B1 C008 RJMP 0x01BA
(0066) while(1)
(0067) {LCD_write_string(3,0,"ICP BY MJP");
01B2 E687 LDI R24,0x67
01B3 E090 LDI R25,0
01B4 8399 STD Y+1,R25
01B5 8388 STD Y+0,R24
01B6 2722 CLR R18
01B7 E003 LDI R16,3
01B8 DF30 RCALL _LCD_write_string
(0068) timer1();
FILE: <library>
01B9 DF9F RCALL _timer1
01BA CFF7 RJMP 0x01B2
01BB 9622 ADIW R28,2
01BC 9508 RET
mod16u:
01BD 9468 BSET 6
01BE C001 RJMP xdiv16u
div16u:
01BF 94E8 BCLR 6
xdiv16u:
01C0 92EA ST R14,-Y
01C1 92FA ST R15,-Y
01C2 938A ST R24,-Y
01C3 24EE CLR R14
01C4 24FF CLR R15
01C5 E180 LDI R24,0x10
01C6 0F00 LSL R16
01C7 1F11 ROL R17
01C8 1CEE ROL R14
01C9 1CFF ROL R15
01CA 16E2 CP R14,R18
01CB 06F3 CPC R15,R19
01CC F018 BCS 0x01D0
01CD 1AE2 SUB R14,R18
01CE 0AF3 SBC R15,R19
01CF 9503 INC R16
01D0 958A DEC R24
01D1 F7A1 BNE 0x01C6
01D2 F416 BRTC 0x01D5
01D3 2D0E MOV R16,R14
01D4 2D1F MOV R17,R15
01D5 9189 LD R24,Y+
01D6 90F9 LD R15,Y+
01D7 90E9 LD R14,Y+
01D8 9508 RET
pop_gset2:
01D9 E0E2 LDI R30,2
01DA 940C01EB JMP pop
pop_gset3:
01DC E0E4 LDI R30,4
01DD 940C01EB JMP pop
push_gset5:
01DF 92FA ST R15,-Y
01E0 92EA ST R14,-Y
push_gset4:
01E1 92DA ST R13,-Y
01E2 92CA ST R12,-Y
push_gset3:
01E3 92BA ST R11,-Y
01E4 92AA ST R10,-Y
push_gset2:
01E5 937A ST R23,-Y
01E6 936A ST R22,-Y
push_gset1:
01E7 935A ST R21,-Y
01E8 934A ST R20,-Y
01E9 9508 RET
pop_gset1:
01EA E0E1 LDI R30,1
pop:
01EB 9149 LD R20,Y+
01EC 9159 LD R21,Y+
01ED FDE0 SBRC R30,0
01EE 9508 RET
01EF 9169 LD R22,Y+
01F0 9179 LD R23,Y+
01F1 FDE1 SBRC R30,1
01F2 9508 RET
01F3 90A9 LD R10,Y+
01F4 90B9 LD R11,Y+
01F5 FDE2 SBRC R30,2
01F6 9508 RET
01F7 90C9 LD R12,Y+
01F8 90D9 LD R13,Y+
01F9 FDE3 SBRC R30,3
01FA 9508 RET
01FB 90E9 LD R14,Y+
01FC 90F9 LD R15,Y+
01FD 9508 RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -