📄 no5.lst
字号:
.equ UDREaddr=$00C ;UART Data Register Empty Interrupt Vector Address
.equ UTXCaddr=$00D ;UART Transmit Complete Interrupt Vector Address
.equ ADCCaddr=$00E ;ADC Conversion Complete Interrupt Vector Address
.equ ERDYaddr=$00F ;EEPROM Write Complete Interrupt Vector Address
.equ ACIaddr =$010 ;Analog Comparator Interrupt Vector Address
.def temp = r19 ;十六进制转换暂存器
.def count = r8 ;十六进制转换计数器
.def res1 = r4
.def res2 = r5 ;res1、res2存放结果的十六进制
.def cnt1d = r6
.def cnt2d = r7 ;cnt1、dcnt2d存放结果的十进制
.org 0x00
.equ label=$0200
000000 c01f rjmp RESET ;
;.org 0x01 ;通用中断
;INTT0: RJMP GINT ;
;.org 0x06 ;timerl
;INTTT: RJMP TINT ;
.org 0x020 ;
RESET:
000020 e50f SYS: ldi R16,low(RAMEND) ;设置堆栈
000021 bf0d out SPL,R16
000022 e002 ldi R16,high(RAMEND)
000023 bf0e out SPH,R16
000024 e208 ldi r16,$28 ;8279写控制寄存器
000025 bb02 out portd,r16
000026 ed01 ldi r16,$d1
000027 bb08 out portb,r16
000028 9a94 sbi portd,4
; ldi r20,0X30
; rcall Delay
;wdr ;看门狗复位
;ldi R16,$0F ;0b00001111
;out WDTCR,R16 ;狗周期2048MS
000029 ef08 ldi R16,$F8 ;0B11111000
00002a bb0a out DDRA,R16 ;A口0~2输入,3~7输出
00002b 9ada sbi porta,2
00002c ef0a ldi R16,$FA ;0B11111110
00002d bb01 out DDRD,R16 ;D口0/2输入,1/3~7输出
00002e ef0f ldi R16,$FF ;0B11111111
00002f bb04 out DDRC,R16 ;C口输出
000030 bb07 out DDRB,R16 ;B口输出
000031 e805 ldi R16,$85 ;设置ADC转换,中断触发,ADC为单次模式且32M分频
000032 b906 out adcsr,R16
000033 2700 clr R16
000034 b907 out admux,R16 ;ADC 0通道
;sbi adcsr,6 ;启动ADC
000035 e908 ldi r16,$98 ;初始化COM
000036 b90a out ucr,r16 ;设置UART控制寄存器---UCR
000037 e109 ldi r16,25
000038 b909 out ubrr,r16 ;设置UART波特率
;ldi r16,$40 ;INT0可用,INT1屏蔽
;out GIMSK,R16
;ldi r16,$3 ;INT0上升沿触发
;out mcucr,r16
000039 9894 cbi portd,4
00003a e000 ldi r16,$00 ;8279键盘显示方式初始
00003b bb08 out portb,r16
00003c 9a94 sbi portd,4
00003d 0000 nop
00003e 9894 cbi portd,4
00003f e202 ldi r16,$22 ;8279时钟分频=2
000040 bb08 out portb,r16
000041 9a94 sbi portd,4
000042 2711 clr r17
000043 9a36 main: sbi adcsr,6 ;启动ADC
000044 d029 rcall ADC1
000045 d03a rcall zhcwsd ;转换成温度
000046 fd10 sbrc r17,0 ;r17的0位清0跳行
000047 d05c rcall zhcsd ;转换成湿度
000048 2c4b mov res1,m16ua
000049 2c5c mov res2,m16ub
00004a d082 rcall htd3 ;16进制转10进制
00004b d0a2 rcall display
00004c 3017 cpi r17,$07
00004d f439 brne addre1 ;不等于7则跳转
00004e 2711 clr r17 ;等于7
00004f 9938 sbic admux,0 ;内地址
000050 c002 rjmp addre2 ;如果admux=1则置0
000051 9a38 sbi admux,0 ;如果admux=0则置1
000052 c003 rjmp addre3
000053 9838 addre2: cbi admux,0
000054 c001 rjmp addre3
000055 9513 addre1: inc r17
000056 2f21 addre3: mov r18,r17
000057 7021 andi r18,$01
000058 3021 cpi r18,$01
000059 f411 brne addre4
00005a 9adb sbi porta,3
00005b c001 rjmp addre5
00005c 98db addre4: cbi porta,3
00005d 2f21 addre5: mov r18,r17
00005e 7022 andi r18,$02
00005f 3022 cpi r18,$02
000060 f411 brne addre6
000061 9adc sbi porta,4
000062 c001 rjmp addre7
000063 98dc addre6: cbi porta,4
000064 2f21 addre7: mov r18,r17
000065 7024 andi r18,$04
000066 3024 cpi r18,$04
000067 f411 brne addre8
000068 9add sbi porta,5
000069 c001 rjmp addre9
00006a 98dd addre8: cbi porta,5
00006b e546 addre9: ldi r20,0X56 ;延时1秒
00006c d0ae rcall Delay
00006d cfd5 rjmp main
;********* 子程序区 *********
;**** ADC转换子程序
00006e 9936 ADC1: sbic adcsr,adsc ;转换结束跳行否则等待
00006f cffe rjmp ADC1
000070 b024 in r2,adcl ;把转换结果送r2,r3
000071 b035 in r3,adch
000072 99ca sbic pina,2 ;读开关量
000073 e020 ldi r18,$0 ;开关量关
000074 e021 ldi r18,$1 ;开关量开
000075 e0b1 ldi r27,$01 ;传数据到SRAM 0100 处
000076 2fa1 mov r26,r17
000077 932c st x,r18 ;传开关量到 0100
000078 9938 sbic admux,0
000079 c002 rjmp admux1
00007a 9650 adiw r26,$10 ;传A0数据到SRAM 0110 处
00007b c001 rjmp chuan
00007c 9690 admux1: adiw r26,$20 ;传A1数据到SRAM 0120 处
00007d 922d chuan: st x+,r2 ;传低位数据
00007e 923c st x,r3 ;传高位数据
00007f 9508 ret
;**** 数据转换成温湿度
000080 2c92 zhcwsd: mov mc16ul,r2 ;T=D*40/1023=D*50/11*10/3*4/31*2
000081 2ca3 mov mc16uh,r3
000082 24cc clr mp16uh
000083 e352 ldi mcnt16u,50
000084 2eb5 mov mp16ul,mcnt16u
000085 d025 rcall mpy16u
000086 2cbb mov mp16ul,m16ua
000087 2ccc mov mp16uh,m16ub
000088 e05b ldi mcnt16u,11
000089 2e95 mov mc16ul,mcnt16u
00008a 24aa clr mc16uh
00008b d02e rcall div16u
00008c 2c9b mov mc16ul,m16ua
00008d 2cac mov mc16uh,m16ub
00008e e05a ldi mcnt16u,10
00008f 2eb5 mov mp16ul,mcnt16u
000090 24cc clr mp16uh
000091 d019 rcall mpy16u
000092 2cbb mov mp16ul,m16ua
000093 2ccc mov mp16uh,m16ub
000094 e053 ldi mcnt16u,3
000095 2e95 mov mc16ul,mcnt16u
000096 24aa clr mc16uh
000097 d022 rcall div16u
000098 2c9b mov mc16ul,m16ua
000099 2cac mov mc16uh,m16ub
00009a e054 ldi mcnt16u,4
00009b 2eb5 mov mp16ul,mcnt16u
00009c 24cc clr mp16uh
00009d d00d rcall mpy16u
00009e 2cbb mov mp16ul,m16ua
00009f 2ccc mov mp16uh,m16ub
0000a0 e15f ldi mcnt16u,31
0000a1 2e95 mov mc16ul,mcnt16u
0000a2 24aa clr mc16uh
0000a3 d016 rcall div16u
0000a4 2c9b zhcsd: mov mc16ul,m16ua ;湿度10~90%,应多乘2
0000a5 2cac mov mc16uh,m16ub
0000a6 e052 ldi mcnt16u,2
0000a7 2eb5 mov mp16ul,mcnt16u
0000a8 24cc clr mp16uh
0000a9 d001 rcall mpy16u
0000aa 9508 ret
;**** 16位无符号乘法
.def mc16uL =r9 ;被乘数低字节
.def mc16uH =r10 ;被乘数高字节
.def mp16uL =r11 ;乘数低字节
.def mp16uH =r12 ;乘数高字节
.def m16ua =r11 ;结果 字节 0 (LSB)
.def m16ub =r12 ;结果 字节 1
.def m16u2 =r13 ;结果 字节 2
.def m16u3 =r14 ;结果 字节 3 (MSB)
.def mcnt16u =r21 ;循环计数
0000ab 24ee mpy16u: clr m16u3 ;清2.3
0000ac 24dd clr m16u2
0000ad e150 ldi mcnt16u,16 ;
0000ae 94c6 lsr mp16uH
0000af 94b7 ror mp16uL
0000b0 f410 m16u_1: brcc noad8 ;C清零转
0000b1 0cd9 add m16u2,mc16uL ;加被乘数到2
0000b2 1cea adc m16u3,mc16uH ;加被乘数到3
0000b3 94e7 noad8: ror m16u3 ;带进位右循环
0000b4 94d7 ror m16u2 ;带进位右循环
0000b5 94c7 ror m16ub ;带进位右循环
0000b6 94b7 ror m16ua ;带进位右循环
0000b7 955a dec mcnt16u ;计数减1
0000b8 f7b9 brne m16u_1 ;不为零转
0000b9 9508 ret
;***** 16位无符号除法
.def drem16uL=r13 ;余数 低位
.def drem16uH=r14 ;余数 高位
.def dres16uL=r11 ; 商 低位
.def dres16uH=r12 ; 商 高位
.def dd16uL =r11 ;被除数 低位
.def dd16uH =r12 ;被除数 高位
.def dv16uL =r9 ;除数 低位
.def dv16uH =r10 ;除数 高位
.def dcnt16u =r21
0000ba 24dd div16u: clr drem16uL ;清除余数低位
0000bb 18ee sub drem16uH,drem16uH ;清除余数高位
0000bc e151 ldi dcnt16u,17 ;循环计数
0000bd 1cbb d16u_1: rol dd16uL ;带进位左移
0000be 1ccc rol dd16uH
0000bf 955a dec dcnt16u ;decrement counter
0000c0 f409 brne d16u_2 ;不为0转
0000c1 9508 ret ;return
0000c2 1cdd d16u_2: rol drem16uL ;shift dividend into remainder
0000c3 1cee rol drem16uH
0000c4 18d9 sub drem16uL,dv16uL ;remainder = remainder - divisor
0000c5 08ea sbc drem16uH,dv16uH ;
0000c6 f420 brcc d16u_3 ;if result negative
0000c7 0cd9 add drem16uL,dv16uL ;restore remainder
0000c8 1cea adc drem16uH,dv16uH
0000c9 9488 clc ;clear carry to be shifted into result
0000ca cff2 rjmp d16u_1 ;else
0000cb 9408 d16u_3: sec ;set carry to be shifted into result
0000cc cff0 rjmp d16u_1
;**** 16进制转10进制子程序
0000cd e130 htd3: ldi temp,16
0000ce 2e83 mov count,temp
0000cf 2733 clr temp
0000d0 2466 clr cnt1d
0000d1 2477 clr cnt2d
0000d2 9488 clc
loopd:
0000d3 1c44 rol res1
0000d4 1c55 rol res2
0000d5 1c66 rol cnt1d
0000d6 1c77 rol cnt2d
0000d7 948a dec count
0000d8 f409 brne c
0000d9 9508 ret
0000da d001 c: rcall adjn
0000db cff7 rjmp loopd
adjn:
0000dc 928f push count
0000dd 2c86 mov count,cnt1d
0000de d006 rcall adjd1
0000df 2c68 mov cnt1d,count
0000e0 2c87 mov count,cnt2d
0000e1 d003 rcall adjd1
0000e2 2c78 mov cnt2d,count
0000e3 908f pop count
0000e4 9508 ret
adjd1:
0000e5 e033 ldi temp,3
0000e6 0d38 add temp,count
0000e7 fd33 sbrc temp,3
0000e8 2e83 mov count,temp
0000e9 e330 ldi temp,$30
0000ea 0d38 add temp,count
0000eb fd37 sbrc temp,7
0000ec 2e83 mov count,temp
0000ed 9508 ret
;**** LED数显子程序
0000ee 9a95 display:sbi portd,5 ;初始化8279控制字
0000ef 9894 cbi portd,4
0000f0 e970 ldi r23,$90
0000f1 bb78 out portb,r23
0000f2 9a94 sbi portd,4
0000f3 9895 cbi portd,5
0000f4 e0f4 ldi zh,high(label*2) ;0~15通道号切换
0000f5 2fe1 mov zl,r17
0000f6 9938 sbic admux,0
0000f7 c001 rjmp dis1
0000f8 c001 rjmp dis0
0000f9 9638 dis1: adiw zl,$08
0000fa 95c8 dis0: lpm
0000fb ba08 out portb,r0
0000fc 9894 cbi portd,4
0000fd 0000 nop
0000fe 9a94 sbi portd,4
0000ff 2d07 mov r16,cnt2d
000100 9502 swap r16
000101 d010 rcall outpd
000102 e1e0 ldi zl,$10
000103 2d07 mov r16,cnt2d
000104 700f andi r16,$0f
000105 0fe0 add zl,r16
000106 95c8 lpm
000107 ba08 out portb,r0
000108 9894 cbi portd,4
000109 0000 nop
00010a 9a94 sbi portd,4
00010b 2d06 mov r16,cnt1d
00010c 9502 swap r16
00010d d004 rcall outpd
00010e 2d06 mov r16,cnt1d
00010f d002 rcall outpd
000110 9a95 sbi portd,5 ;向8279传送数据结束
000111 9508 ret
000112 e0e0 outpd: ldi zl,low(label*2)
000113 700f andi r16,$0f
000114 0fe0 add zl,r16
000115 95c8 lpm
000116 ba08 out portb,r0
000117 9894 cbi portd,4
000118 0000 nop
000119 9a94 sbi portd,4
00011a 9508 ret
;**** 延时子程序
00011b 934f delay: push r20 ;2t
00011c 934f l0: push r20 ;2t
00011d 934f l1: push r20 ;2t
00011e 934f l2: push r20 ;2t
00011f 954a l3: dec r20 ;1t
000120 f7f1 brne l3 ;1t/2t
000121 914f pop r20 ;2t
000122 954a dec r20 ;1t
000123 f7d1 brne l2 ;1t/2t
000124 914f pop r20 ;2t
000125 954a dec r20 ;1t
000126 f7b1 brne l1 ;1t/2t
000127 914f pop r20 ;2t
000128 954a dec r20 ;1t
000129 f791 brne l0 ;1T/2T
00012a 914f pop r20 ;2t
00012b 9508 ret ;4t
;**** 数据区
.cseg
.org $0200
.dw 0x063f,0x4f5b,0x6d66,0x077d
000200 063f
000201 4f5b
000202 6d66
000203 077d
.dw 0x6f7f,0x7c77,0x5e39,0x7179
000204 6f7f
000205 7c77
000206 5e39
000207 7179
.dw 0x86bf,0xcfdb,0xede6,0x87fd
000208 86bf
000209 cfdb
00020a ede6
00020b 87fd
.dw 0xefff00020c efff
Assembly complete with no errors.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -