📄 no3a1.asm
字号:
ldi r16,$5b ;'2'
rcall outxs
rcall jy
ret
csbsf4: cpi r24,$04 ;显示P1
brne csbsf5
ldi r16,$73 ;'p'
rcall outxs
ldi r16,$06 ;'1'
rcall outxs
rcall jy
ret
csbsf5: cpi r24,$05 ;显示I1
brne csbsf6
ldi r16,$30 ;'i'
rcall outxs
ldi r16,$06 ;'1'
rcall outxs
rcall jy
ret
csbsf6: cpi r24,$06 ;显示D1
brne csbsf7
ldi r16,$5e ;'d'
rcall outxs
ldi r16,$06 ;'1'
rcall outxs
rcall jy
ret
csbsf7: cpi r24,$07 ;显示P2
brne csbsf8
ldi r16,$73 ;'p'
rcall outxs
ldi r16,$5b ;'2'
rcall outxs
rcall jy
ret
csbsf8: cpi r24,$08 ;显示I2
brne csbsf9
ldi r16,$30 ;'i'
rcall outxs
ldi r16,$5b ;'2'
rcall outxs
rcall jy
ret
csbsf9: cpi r24,$09 ;显示D2
brne csbsfa
ldi r16,$5e ;'d'
rcall outxs
ldi r16,$5b ;'2'
rcall outxs
rcall jy
ret
csbsfa: cpi r24,$a ;显示压力
brne csbsfb
ldi r16,$73 ;'p'
rcall outxs
ldi r16,$70 ;'r'
rcall outxs
rcall jy
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
;**********************
;********主程序********
;**********************
;.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
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
subi r26,$02
ld r16,x
;ldi r16,25
out ubrr,r16 ;设置UART波特率
clr r1
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
sbi ddrd,6
sbi portd,6
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地址计数
main: rcall ADC1
rcall zhcwsd ;转换成温度
sbrc r17,0 ;r17的0位清0跳行
rcall zhcsd ;转换成湿度
mov res1,m16ua
mov res2,m16ub
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: rcall display ;调用显示子程序
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: mov mc16ul,r2 ;T=D*40/1023=D*50/11*10/3*4/31*2
mov mc16uh,r3
clr mp16uh
ldi mcnt16u,50
mov mp16ul,mcnt16u
rcall mpy16u
mov mp16ul,m16ua
mov mp16uh,m16ub
ldi mcnt16u,11
mov mc16ul,mcnt16u
clr mc16uh
rcall div16u
mov mc16ul,m16ua
mov mc16uh,m16ub
ldi mcnt16u,10
mov mp16ul,mcnt16u
clr mp16uh
rcall mpy16u
mov mp16ul,m16ua
mov mp16uh,m16ub
ldi mcnt16u,3
mov mc16ul,mcnt16u
clr mc16uh
rcall div16u
mov mc16ul,m16ua
mov mc16uh,m16ub
ldi mcnt16u,4
mov mp16ul,mcnt16u
clr mp16uh
rcall mpy16u
mov mp16ul,m16ua
mov mp16uh,m16ub
ldi mcnt16u,31
mov mc16ul,mcnt16u
clr mc16uh
rcall div16u
zhcsd: mov mc16ul,m16ua ;湿度10~90%,应多乘2
mov mc16uh,m16ub
ldi mcnt16u,2
mov mp16ul,mcnt16u
clr mp16uh
rcall mpy16u
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 ;循环计数
mpy16u: clr m16u3 ;清2.3
clr m16u2
ldi mcnt16u,16 ;
lsr mp16uH
ror mp16uL
m16u_1: brcc noad8 ;C清零转
add m16u2,mc16uL ;加被乘数到2
adc m16u3,mc16uH ;加被乘数到3
noad8: ror m16u3 ;带进位右循环
ror m16u2 ;带进位右循环
ror m16ub ;带进位右循环
ror m16ua ;带进位右循环
dec mcnt16u ;计数减1
brne m16u_1 ;不为零转
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
div16u: clr drem16uL ;清除余数低位
sub drem16uH,drem16uH ;清除余数高位
ldi dcnt16u,17 ;循环计数
d16u_1: rol dd16uL ;带进位左移
rol dd16uH
dec dcnt16u ;decrement counter
brne d16u_2 ;不为0转
ret ;return
d16u_2: rol drem16uL ;shift dividend into remainder
rol drem16uH
sub drem16uL,dv16uL ;remainder = remainder - divisor
sbc drem16uH,dv16uH ;
brcc d16u_3 ;if result negative
add drem16uL,dv16uL ;restore remainder
adc drem16uH,dv16uH
clc ;clear carry to be shifted into result
rjmp d16u_1 ;else
d16u_3: sec ;set carry to be shifted into result
rjmp d16u_1
;**** 16进制转10进制子程序
htd3: ldi temp,16
mov count,temp
clr temp
clr cnt1d
clr cnt2d
clc
loopd:
rol res1
rol res2
rol cnt1d
rol cnt2d
dec count
brne c
ret
c: rcall adjn
rjmp loopd
adjn:
push count
mov count,cnt1d
rcall adjd1
mov cnt1d,count
mov count,cnt2d
rcall adjd1
mov cnt2d,count
pop count
ret
adjd1:
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
;**** 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
rjmp dis1
rjmp dis0
dis1: adiw zl,$08
dis0: 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 $0400
.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 + -