📄 no3b.asm
字号:
ret
csbsfb: cpi r24,$b ;显示凝节水温度
brne csbsfc
ldi r16,$78 ;'t'
rcall outxs
ldi r16,$5b ;'2'
rcall outxs
rcall jy
ret
csbsfc: cpi r24,$c ;通讯站号
brne csbsfd
ldi r16,$6d ;'s'
rcall outxs
ldi r16,$40 ;'-'
rcall outxs
ldi r16,$37 ;'n'
rcall outxs
ldi r16,$00 ;''
rcall outxs
ldi r16,$00 ;''
rcall outxs
ret
csbsfd: cpi r24,$d ;通讯传输频率
brne csbsfe
ldi r16,$3e ;'u'
rcall outxs
ldi r16,$7c ;'b'
rcall outxs
ldi r16,$70 ;'r'
rcall outxs
ldi r16,$70 ;'r'
rcall outxs
ldi r16,$00 ;''
rcall outxs
ret
csbsfe: cpi r24,$e ;运行模式
brne tcret
ldi r16,$77 ;'a'
rcall outxs
ldi r16,$1c ;'u'
rcall outxs
ldi r16,$78 ;'t'
rcall outxs
ldi r16,$5c ;'o'
rcall outxs
ldi r16,$00 ;''
rcall outxs
tcret: ret
;***** 参数计算子程序
cansujs:ldi yl,$48
ldi yh,$01 ;Y >>>0X0148
ldi zl,$90
ldi zh,$00 ;Z >>>0X0090
ld r6,y ;P1 l
ldd r7,y+1 ;P1 h
rcall btoh
st z,r4 ;P1 L>>>0X0090
std z+1,r5 ;P1 H>>>0X0091
ldd r12,y+2 ;I1 l
ldd r13,y+3 ;I1 h
ldd r8,y+4 ;D1 l
ldd r9,y+5 ;D1 h
rcall can01 ;I1+D1+1
ld r6,z ;P1 L<<<0X0090
ldd r7,z+1 ;P1 H<<<0X0091
rcall can02 ;保留两位小数
std z+2,r6 ;A1 L>>>0X0092
std z+3,r7 ;A1 H>>>0X0093
ldd r8,y+4 ;D1 l
ldd r9,y+5 ;D1 h
mov r12,r8
mov r13,r9
rcall can01 ;D1+D1+1
ld r6,z ;P1 L<<<0X0090
ldd r7,z+1 ;P1 H<<<0X0091
rcall can02 ;保留两位小数
std z+4,r6 ;B1 L>>>0X0094
std z+5,r7 ;B1 H>>>0X0095
ldd r6,y+4 ;D1 l
ldd r7,y+5 ;D1 h
rcall btoh
ld r6,z ;P1 L<<<0X0090
ldd r7,z+1 ;P1 H<<<0X0091
rcall can02 ;保留两位小数
std z+6,r6 ;C1 L>>>0X0096
std z+7,r7 ;C1 H>>>0X0097
ldd r6,y+6 ;P2 l
ldd r7,y+7 ;P2 h
rcall btoh
std z+8,r4 ;P2 L>>>0X0098
std z+9,r5 ;P2 H>>>0X0099
ldd r12,y+8 ;I2 l
ldd r13,y+9 ;I2 h
ldd r8,y+10 ;D2 l
ldd r9,y+11 ;D2 h
rcall can01 ;I2+D2+1
ldd r6,z+8 ;P2 L<<<0X0098
ldd r7,z+9 ;P2 H<<<0X0099
rcall can02 ;保留两位小数
std z+10,r6 ;A2 L>>>0X009a
std z+11,r7 ;A2 H>>>0X009b
ldd r8,y+10 ;D2 l
ldd r9,y+11 ;D2 h
mov r12,r8
mov r13,r9
rcall can01 ;D2+D2+1
ldd r6,z+8 ;P2 L<<<0X0098
ldd r7,z+9 ;P2 H<<<0X0099
rcall can02 ;保留两位小数
std z+12,r6 ;B2 L>>>0X009c
std z+13,r7 ;B2 H>>>0X009d
ldd r6,y+10 ;D2 l
ldd r7,y+11 ;D2 h
rcall btoh
ldd r6,z+8 ;P2 L<<<0X0098
ldd r7,z+9 ;P2 H<<<0X0099
rcall can02 ;保留两位小数
std z+14,r6 ;C2 L>>>0X009e
std z+15,r7 ;C2 H>>>0X009f
ret
can01: clr r15
clr r14
clr r11
clr r10
rcall adbcd ;I1+D1
clr r11
clr r10
clr r9
clr r8
inc r9
rcall adbcd ;I1+D1+1
mov r6,r12
mov r7,r13
rcall btoh
ret
can02: rcall mul16 ;P1*D1
clr r5
ldi r16,$64
mov r4,r16
rcall div16 ;除100,保留两位小数
ret
;**********************
;********主程序********
;**********************
;.cseg
;.org 0x01b6
RESET:
SYS: ldi R16,low(RAMEND) ;设置堆栈
out SPL,R16
ldi R16,high(RAMEND)
out SPH,R16
;wdr ;看门狗复位
;ldi R16,$0F ;0b00001111
;out WDTCR,R16 ;狗周期2048MS
sbi ddrd,6
cbi portd,6
ldi R16,$F8 ;0B11111000
out DDRA,R16 ;A口0~2输入,3~7输出
sbi porta,2
ldi R16,$FA ;0B11111110
out DDRD,R16 ;D口0/2输入,1/3~7输出
ldi R16,$FF ;0B11111111
out DDRC,R16 ;C口输出
out DDRB,R16 ;B口输出
ldi r16,$28 ;8279写控制寄存器
out portd,r16
ldi r16,$d1 ;清8279寄存器
out portb,r16
sbi portd,4
clr r16
out ddrb,r16
ldi r16,$30
out portd,r16
wait: sbis portb,7 ;等待清除结束
rjmp wait
cbi portd,4
sbi portd,3
ser r16
out ddrb,r16
clr R16
out admux,R16 ;ADC 0通道
ldi R16,$85 ;设置ADC转换,中断触发,ADC为单次模式且32M分频
out adcsr,R16
sbi adcsr,adif ;写1复位中断为0
sbi adcsr,6 ;启动ADC
clr r24 ;把EEP中的参数映射到SRAM的0X0140~0X014E处
ldi r27,$01
ldi r26,$40
EEpRead:sbic EECR,EEWE ;if EEWE not clear
rjmp EEpRead
ldi r16,$01
out EEARH,r16 ;output address high for 8515
out EEARL,r24 ;output address low for 8515
sbi EECR,EERE ;set EEPROM Read strobe
in r16,EEDR ;get data
st x+,r16
inc r24
cpi r24,$0f
brne EEpRead
rcall cansujs ;^^^^^^^^^^^^^^^^^^^^
ldi r16,$98 ;初始化COM
out ucr,r16 ;设置UART控制寄存器---UCR
ldi r26,$5a ;波特率在SRAM的0x015a处
ld r16,x
;ldi r16,25
out ubrr,r16 ;设置UART波特率
ldi r16,$3 ;INT0上升沿触发 0b00000011
out mcucr,r16
ldi r16,$40
out GIMSK,R16 ;INT0可用,INT1屏蔽 0b01000000
out GIFR,r16
sei
cbi portd,4
ldi r16,$00 ;8279键盘显示方式初始
out portb,r16
sbi portd,4
nop
cbi portd,4
ldi r16,$22 ;8279时钟分频=2
out portb,r16
sbi portd,4
rcall cs8279 ;显示字符
ldi r16,$40 ;'-'
rcall outxs
ldi r20,$41 ;调用延时
rcall delay
ldi r16,$40 ;'-'
rcall outxs
ldi r20,$41 ;调用延时
rcall delay
ldi r16,$40 ;'-'
rcall outxs
ldi r20,$41 ;调用延时
rcall delay
ldi r16,$40 ;'-'
rcall outxs
ldi r20,$41 ;调用延时
rcall delay
ldi r16,$40 ;'-'
rcall outxs
ldi r20,$41 ;调用延时
rcall delay
ldi r16,$40 ;'-'
rcall outxs
sbi portd,5
ldi r20,$41 ;调用延时
rcall delay
rcall beep
ldi r20,$41 ;调用延时
rcall delay
rcall beep
clr r17 ;ADIN 4051地址计数
clr r25 ;setup键计数器
;rcall ADC1
main: sbis adcsr,adif ;转换结束 ADC中断发生跳行否则等待 ADC1:
rjmp main
in r2,adcl ;把转换结果送r2,r3
in r3,adch
sbic pina,2 ;读开关量
ldi r18,$0 ;开关量关
ldi r18,$1 ;开关量开
ldi r27,$01 ;传数据到SRAM 0100 处
mov r26,r17
st x,r18 ;传开关量到 0100
sbic admux,0
rjmp admux1
adiw r26,$10 ;传A0数据到SRAM 0110 处
rjmp chuan
admux1: adiw r26,$20 ;传A1数据到SRAM 0120 处
chuan: st x+,r2 ;传低位数据
st x,r3 ;传高位数据
rcall zhcwsd ;转换成温度
sbrc r17,0 ;r17的0位清0跳行
rcall zhcsd ;转换成湿度
mov res1,R15 ;00000000000000000000
mov res2,R16 ;00000000000000000000
rcall htd3 ;16进制转10进制
sbrc r17,0 ;r17的0位清0跳行
rjmp main0 ;1\3\5\7 通道为湿度
rjmp main1 ;0\2\4\6 通道为温度
main0: ldi r16,$10 ;湿度补偿10%
add cnt2d,r16
main1: cpi r25,$0 ;setup键计数器为0
brne main2
rcall display ;调用显示子程序
main2: cpi r17,$07
brne addre1 ;不等于7则跳转
clr r17 ;等于7
sbic admux,0 ;内地址
rjmp addre2 ;如果admux=1则置0
sbi admux,0 ;如果admux=0则置1
rjmp addre3
addre2: cbi admux,0
rjmp addre3
addre1: inc r17
addre3: mov r18,r17
andi r18,$01
cpi r18,$01
brne addre4
sbi porta,3
rjmp addre5
addre4: cbi porta,3
addre5: mov r18,r17
andi r18,$02
cpi r18,$02
brne addre6
sbi porta,4
rjmp addre7
addre6: cbi porta,4
addre7: mov r18,r17
andi r18,$04
cpi r18,$04
brne addre8
sbi porta,5
rjmp addre9
addre8: cbi porta,5
addre9: ldi r20,0X56 ;延时1秒
rcall Delay
sbi adcsr,6 ;启动ADC
rjmp main ;
;********* 子程序区 *********
;**** ADC转换子程序
;ADC1: sbis adcsr,adif ;转换结束 ADC中断发生跳行否则等待
; rjmp ADC1
; in r2,adcl ;把转换结果送r2,r3
; in r3,adch
; sbic pina,2 ;读开关量
; ldi r18,$0 ;开关量关
; ldi r18,$1 ;开关量开
;
; ldi r27,$01 ;传数据到SRAM 0100 处
; mov r26,r17
; st x,r18 ;传开关量到 0100
; sbic admux,0
; rjmp admux1
; adiw r26,$10 ;传A0数据到SRAM 0110 处
; rjmp chuan
;admux1: adiw r26,$20 ;传A1数据到SRAM 0120 处
;chuan: st x+,r2 ;传低位数据
; st x,r3 ;传高位数据
; ret
;**** 数据转换成温湿度
zhcwsd: rcall div16
ret
zhcsd: ;湿度10~90%,应多乘2
rcall MUL16
ret
;**** 四字节压缩BCD码相加子程序(R15,R14,R13,R12)+(R11,R10,R9,R8)→R15,R14,R13,R12
ADBCD: add R12,R8 ;最低位字节相加
mov R20,R12
rcall ADAA ;在R20里进行加法十进制调整
mov R12,R20 ;调整后结果送回
adc R13,R9 ;对高位字节也照此处理
mov R20,R13
rcall ADAA
mov R13,R20
adc R14,R10
mov R20,R14
rcall ADAA
mov R14,R20
adc R15,R11
mov R20,R15
rcall ADAA
mov R15,R20 ;最高位字节相加调整完毕
ret
;**** BCD码相加或左移十进制调整子程序
ADAA: in R7,SREG ;BCD码相加十进制调整子程序,先保存相加后的状态
ldi R22,$66
add R20,R22 ;予加$66
in R6,SREG ;存加$66后的状态
or R6,R7 ;将新旧两状态或起来(只用C,H两位)
sbrs R6,0 ;若进位C置位,跳过下条指令
subi R20,$60 ;否则减去$60
sbrs R6,5 ;若半进位H置位,跳过下条指令
subi R20,6 ;否则减去6
out SREG,R6 ;恢复进位C,以保证高位字节正确相加
ret
;**** 四字节压缩BCD码相加子程序(R15,R14,R13,R12)-(R11,R10,R9,R8)→R15,R14,R13,R12
SUBCD: sub R12,R8 ;最低位字节相减
mov R20,R12
rcall SDAA ;在R20里进行减法十进制调整
mov R12,R20
sbc R13,R9
mov R20,R13
rcall SDAA
mov R13,R20
sbc R14,R10
mov R20,R14
rcall SDAA
mov R14,R20
sbc R15,R11
mov R20,R15
rcall SDAA
mov R15,R20 ;最高位字节相减调整完毕并回送
ret
;**** 十进制减法调整子程序
SDAA: brcc SBD1 ;进位位清除,跳转
brhc SBD2 ;半进位清除,跳转
subi R20,$66 ;否则将差减去$66
sec ;并恢复借位C
ret
SBD1: brhc SBD3 ;半进位也清除,返回(不须调整)
subi R20,$6 ;否则将差减去6
ret
SBD2: subi R20,$60 ;将差减去$60
sec ;并恢复借位C
SBD3: ret
;**** 定点整数乘法子程序 (R5,R4)×(R7,R6)→R9,R8,R7,R6
MUL16: ldi R18,$11 ;循环右移17次
clr R9
clr R8 ;积高位部分予清除
clc ;第一次只移位
MLOP: brcc MUL1 ;进位位被清除,跳转
add R8,R4
adc R9,R5 ;否则,被乘数加入部分积
MUL1: ror R9
ror R8
ror R7
ror R6 ;并将部分积(及乘数)带进位右移
dec R18
brne MLOP ;相加右移16次,结束
ret
;**** 定点整数除法子程序 R7,R6←(R9,R8,R7,R6)÷(R5,R4)
DIV16: ldi R18,$10 ;循环左移16次
DLOP: lsl R6
rol R7
rol R8
rol R9 ;被除数算数左移一位
brcc DIV1 ;进位清除,跳转
sub R8,R4
sbc R9,R5
rjmp DIV2 ;否则将被除数(比除数多1位)减去除数并转记商1
DIV1: sub R8,R4
sbc R9,R5 ;相减试商
brcc DIV2 ;进位被清除(够减),本位商为1
add R8,R4
adc R9,R5
rjmp DIV3 ;不够减,恢复被减数,本位商为0
DIV2: inc R6 ;记商1
DIV3: dec R18
brne DLOP ;16次循环,除法结束
ret
;**** HEX TO BCD 子程序
htd3: ldi temp,24
mov count,temp
clr temp
clr cnt1d
clr cnt2d
clr cnt3d
clc
htd31: rol res1
rol res2
rol res3
rol cnt1d
rol cnt2d
rol cnt3d
dec count
brne htd32
ret
htd32: push count
mov count,cnt1d
rcall htd33
mov cnt1d,count
mov count,cnt2d
rcall htd33
mov cnt2d,count
mov count,cnt3d
rcall htd33
mov cnt3d,count
pop count
rjmp htd31
htd33: ldi temp,3
add temp,count
sbrc temp,3
mov count,temp
ldi temp,$30
add temp,count
sbrc temp,7
mov count,temp
ret
;**** BCD TO HEX 子程序
btoh: clr r4
clr r5
ldi r19,$03
ldi r18,$e8
mov r16,r7
swap r16
andi r16,$0f
breq btoh03
btoh01: add r5,r19
add r4,r18
cp r4,r18
brsh btoh02
inc r5
btoh02: dec r16
brne btoh01
btoh03: ldi r18,$64
mov r16,r7
andi r16,$0f
breq btoh06
btoh04: add r4,r18
cp r4,r18
brsh btoh05
inc r5
btoh05: dec r16
brne btoh04
btoh06: ldi r18,$0a
mov r16,r6
swap r16
andi r16,$0f
breq btoh09
btoh07: add r4,r18
cp r4,r18
brsh btoh08
inc r5
btoh08: dec r16
brne btoh07
btoh09: mov r16,r6
andi r16,$0f
breq btoh11
btoh10: add r4,r16
cp r4,r16
brsh btoh11
inc r5
btoh11: ret
;**** LED数显子程序
display:sbi portd,5 ;初始化8279控制字
cbi portd,4
sbi portd,3
ldi r23,$90
out portb,r23
nop
sbi portd,4
cbi portd,5
ldi zh,high(label*2);0~15通道号切换
mov zl,r17
sbic admux,0
adiw zl,8
lpm
out portb,r0
cbi portd,4
nop
sbi portd,4
mov r16,cnt2d
swap r16
rcall outpd
ldi zl,$10
mov r16,cnt2d
andi r16,$0f
add zl,r16
lpm
out portb,r0
cbi portd,4
nop
sbi portd,4
mov r16,cnt1d
swap r16
rcall outpd
mov r16,cnt1d
rcall outpd
sbi portd,5 ;向8279传送数据结束
ret
outpd: ldi zl,low(label*2)
andi r16,$0f
add zl,r16
lpm
out portb,r0
cbi portd,4
nop
sbi portd,4
ret
;**** 延时子程序
;delay: ret
delay: push r20 ;2t
l0: push r20 ;2t
l1: push r20 ;2t
l2: push r20 ;2t
l3: dec r20 ;1t
brne l3 ;1t/2t
pop r20 ;2t
dec r20 ;1t
brne l2 ;1t/2t
pop r20 ;2t
dec r20 ;1t
brne l1 ;1t/2t
pop r20 ;2t
dec r20 ;1t
brne l0 ;1T/2T
pop r20 ;2t
ret ;4t
;**** 数据区
.cseg
.org $0600
.dw 0x063f,0x4f5b,0x6d66,0x077d
.dw 0x6f7f,0x7c77,0x5e39,0x7179
.dw 0x86bf,0xcfdb,0xede6,0x87fd
.dw 0xefff
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -