.module DS18B20.C
.area text(rom, con, rel)
.dbfile D:\MY_COMPUTER\d\avr16\atmegal16\DS18B20.C
.dbfunc e crccheck _crccheck fc
; j -> R20
; r -> R14
; cbit -> y+0
; bit0 -> R8
; byte -> R10
; i -> R12
; temp -> R22
; len -> R6
; p -> R4,R5
.even
_crccheck::
xcall push_gset5
mov R6,R18
movw R4,R16
sbiw R28,1
.dbline -1
.dbline 24
; /********************************************************************
; ATmega16L开发板18B20测试程序
; 晶振频率: 4MHz
; 编译: ICCAVR 6.31
; 编写: QINDAOTANG
; ********************************************************************/
;
; #include
; #include
; #include "DS18B20.H"
; //硬件连接与PD6
; #define DQ 1 ; #define true 0
; #define false 1
; float temperature;
; /*===================================================================
; // 函数功能: DS18B20数据校验函数
; // 形参: void
; // 返回: unsigned char 校验结果
; // 编写: 2004/8/25
; // 备注: CRC公式为:CRC = X^8 + X^5 + X^4 + 1
; ===================================================================*/
; unsigned char crccheck(unsigned char *p,unsigned char len)
; {
.dbline 26
; unsigned char bit0,cbit,r,temp,i,j,byte;
; temp = 0;
clr R22
.dbline 27
; for(j = 0; j < len; j++)
clr R20
xjmp L5
L2:
.dbline 28
; {
.dbline 29
; byte = p[j];
mov R30,R20
clr R31
add R30,R4
adc R31,R5
ldd R10,z+0
.dbline 30
; for(i = 0; i < 8; i++)
clr R12
xjmp L9
L6:
.dbline 31
; {
.dbline 32
; cbit = temp & 0x01;
mov R24,R22
andi R24,1
std y+0,R24
.dbline 33
; bit0 = byte&0x01;
mov R24,R10
andi R24,1
mov R8,R24
.dbline 34
; temp >>= 1;
lsr R22
.dbline 35
; r = cbit ^ bit0;
ldd R14,y+0
eor R14,R24
.dbline 36
; if(r == 1)
mov R24,R14
cpi R24,1
brne L10
.dbline 37
; temp ^= 0x8c;
ldi R24,140
ldi R25,0
mov R2,R22
clr R3
eor R2,R24
eor R3,R25
mov R22,R2
L10:
.dbline 38
lsr R10
.dbline 39
L7:
.dbline 30
inc R12
L9:
.dbline 30
mov R24,R12
cpi R24,8
brlo L6
.dbline 40
L3:
.dbline 27
inc R20
L5:
.dbline 27
cp R20,R6
brlo L2
.dbline 41
; byte >>= 1;
; }
; }
; return temp;
mov R16,R22
.dbline -2
L1:
adiw R28,1
xcall pop_gset5
.dbline 0 ; func end
ret
.dbsym r j 20 c
.dbsym r r 14 c
.dbsym l cbit 0 c
.dbsym r bit0 8 c
.dbsym r byte 10 c
.dbsym r i 12 c
.dbsym r temp 22 c
.dbsym r len 6 c
.dbsym r p 4 pc
.dbend
.dbfunc e delay_us _delay_us fV
; time -> R16,R17
.even
_delay_us::
.dbline -1
.dbline 50
; }
; /*===================================================================
; // 函数功能: us延时函数
; // 形参: void
; // 返回: void
; // 编写: 2004/8/25
; ===================================================================*/
; void delay_us(unsigned int time)
; {
L13:
.dbline 52
; do
; {
.dbline 53
; time--;
subi R16,1
sbci R17,0
.dbline 54
; }
L14:
.dbline 55
; while (time>1);
ldi R24,1
ldi R25,0
cp R24,R16
cpc R25,R17
brlo L13
.dbline -2
.dbline 56
; }
L12:
.dbline 0 ; func end
ret
.dbsym r time 16 i
.dbend
.dbfunc e ds1820_ack _ds1820_ack fc
; ack -> R20
.even
_ds1820_ack::
xcall push_gset1
.dbline -1
.dbline 65
;
; /*===================================================================
; // 函数功能: 判断总线应答
; // 形参: void
; // 返回: unsigned char true为应答
; // 编写: 2004/8/25
; ===================================================================*/
; unsigned char ds1820_ack(void)
; {
.dbline 67
; unsigned char ack;
; DDRD |= DQ;
sbi 0x11,6
.dbline 68
; PORTD &= ~DQ;
in R24,0x12
andi R24,128
out 0x12,R24
.dbline 69
; delay_us(300); //480US以上 // reset
ldi R16,300
ldi R17,1
xcall _delay_us
.dbline 70
; PORTD |= DQ;
sbi 0x12,6
.dbline 71
; DDRD &= ~DQ;
in R24,0x11
andi R24,128
out 0x11,R24
.dbline 72
; delay_us(25);
ldi R16,25
ldi R17,0
xcall _delay_us
.dbline 73
; ack = DQ & PIND;
in R20,0x10
andi R20,64
.dbline 74
; delay_us(300); // host receive
ldi R16,300
ldi R17,1
xcall _delay_us
.dbline 75
; if(ack)
tst R20
breq L17
.dbline 76
; return false;
ldi R16,1
xjmp L16
L17:
.dbline 78
; else
; return true;
clr R16
.dbline -2
L16:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r ack 20 c
.dbend
.dbfunc e read_byte _read_byte fc
; value -> R20
; i -> R22
.even
_read_byte::
xcall push_gset2
.dbline -1
.dbline 88
; }
;
; /*===================================================================
; // 函数功能: 从 1-wire 总线上读取一个字节
; // 形参: void
; // 返回: unsigned char 读到的值
; // 编写: 2004/8/25
; ===================================================================*/
; unsigned char read_byte(void)
; {
.dbline 90
; unsigned char i;
; unsigned char value = 0;
clr R20
.dbline 91
; for(i = 8; i > 0; i--)
ldi R22,8
xjmp L23
L20:
.dbline 92
; {
.dbline 93
; value >>= 1; // low bit first
lsr R20
.dbline 94
; DDRD |= DQ;
sbi 0x11,6
.dbline 95
; PORTD &= ~DQ; // pull DQ low to start timeslot
in R24,0x12
andi R24,128
out 0x12,R24
.dbline 96
; delay_us(2);
ldi R16,2
ldi R17,0
xcall _delay_us
.dbline 97
; PORTD|= DQ;
sbi 0x12,6
.dbline 98
; DDRD &= ~DQ; // release bus
in R24,0x11
andi R24,128
out 0x11,R24
.dbline 99
; delay_us(5);
ldi R16,5
ldi R17,0
xcall _delay_us
.dbline 100
; if(DQ & PIND)
sbis 0x10,6
rjmp L24
.dbline 101
; value|=0x80;
ori R20,128
L24:
.dbline 102
ldi R16,100
ldi R17,0
xcall _delay_us
.dbline 103
sbi 0x11,6
.dbline 104
ldi R16,3
ldi R17,0
xcall _delay_us
.dbline 105
L21:
.dbline 91
dec R22
L23:
.dbline 91
clr R2
cp R2,R22
brlo L20
.dbline 106
; delay_us(100);
; DDRD |= DQ;
; delay_us(3); // time interval
; }
; return(value);
mov R16,R20
.dbline -2
L19:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r value 20 c
.dbsym r i 22 c
.dbend
.dbfunc e write_byte _write_byte fV
; i -> R20
; value -> R22
.even
_write_byte::
xcall push_gset2
mov R22,R16
.dbline -1
.dbline 118
; }
;
;
;
; /*===================================================================
; // 函数功能: 向 1-WIRE 总线上写一个字节
; // 形参: value 写到总线上的值
; // 返回: void
; // 编写: 2004/8/25
; ===================================================================*/
; void write_byte(unsigned char value)
; {
.dbline 120
; unsigned char i;
; DDRD|= DQ;
sbi 0x11,6
.dbline 121
; for(i = 8; i > 0; i--)
ldi R20,8
xjmp L30
L27:
.dbline 122
; {
.dbline 123
; if(value & 0x01)
sbrs R22,0
rjmp L31
.dbline 124
; {
.dbline 125
; PORTD &= ~DQ; // pull DQ low to start timeslot
in R24,0x12
andi R24,128
out 0x12,R24
.dbline 126
; delay_us(5);
ldi R16,5
ldi R17,0
xcall _delay_us
.dbline 127
; PORTD |= DQ;
sbi 0x12,6
.dbline 128
; delay_us(50);
ldi R16,50
ldi R17,0
xcall _delay_us
.dbline 129
; }
xjmp L32
L31:
.dbline 131
; else
; {
.dbline 132
; PORTD&= ~DQ; // pull DQ low to start timeslot
in R24,0x12
andi R24,128
out 0x12,R24
.dbline 133
; delay_us(50);
ldi R16,50
ldi R17,0
xcall _delay_us
.dbline 134
; PORTD|= DQ;
sbi 0x12,6
.dbline 135
; delay_us(5);
ldi R16,5
ldi R17,0
xcall _delay_us
.dbline 136
; }
L32:
.dbline 137
lsr R22
.dbline 138
L28:
.dbline 121
dec R20
L30:
.dbline 121
clr R2
cp R2,R20
brlo L27
.dbline -2
.dbline 139
; value >>= 1;
; }
; }
L26:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r i 20 c
.dbsym r value 22 c
.dbend
.dbfunc e Read_Temperature _Read_Temperature fc
; t -> R20,R21
; temporary -> y+0
; i -> R20
.even
_Read_Temperature::
xcall push_gset1
sbiw R28,9
.dbline -1
.dbline 149
;
;
; /*===================================================================
; // 函数功能: 读取温度
; // 形参: *temperature 温度存储空间
; // 返回: unsigned char true为有效
; // 编写: 2004/8/25
; ===================================================================*/
; unsigned char Read_Temperature(void)
; {
.dbline 154
; unsigned char i;
; unsigned int t;
; unsigned char temporary[9];
;
; ds1820_ack();
xcall _ds1820_ack
.dbline 155
; write_byte(0xCC); // Skip ROM
ldi R16,204
xcall _write_byte
.dbline 156
; write_byte(0x44); // Start Conversion
ldi R16,68
xcall _write_byte
.dbline 157
; for(i = 0; i < 5; i++)
clr R20
xjmp L37
L34:
.dbline 158
ldi R16,50000
ldi R17,195
xcall _delay_us
L35:
.dbline 157
inc R20
L37:
.dbline 157
cpi R20,5
brlo L34
.dbline 159
; delay_us(50000);
; ds1820_ack();
xcall _ds1820_ack
.dbline 160
; write_byte(0xCC); // Skip ROM
ldi R16,204
xcall _write_byte
.dbline 161
; write_byte(0xBE); // Read Scratch Pad
ldi R16,190
xcall _write_byte
.dbline 162
; for(i = 0; i < 9; i++)
clr R20
xjmp L41
L38:
.dbline 163
xcall _read_byte
movw R24,R28
mov R30,R20
clr R31
add R30,R24
adc R31,R25
std z+0,R16
L39:
.dbline 162
inc R20
L41:
.dbline 162
cpi R20,9
brlo L38
.dbline 164
; temporary[i] = read_byte();
; if(crccheck(temporary,9))
ldi R18,9
movw R16,R28
xcall _crccheck
tst R16
breq L42
.dbline 165
; return false;
ldi R16,1
xjmp L33
L42:
.dbline 167
; else
; {
.dbline 168
; t=temporary[0]+temporary[1]*256;
ldd R18,y+1
clr R19
ldi R16,256
ldi R17,1
xcall empy16s
ldd R20,y+0
clr R21
add R20,R16
adc R21,R17
.dbline 169
; if(temporary[1]>0xf)
ldi R24,15
ldd R2,y+1
cp R24,R2
brsh L45
.dbline 170
; temperature=(~t+1)*0.0625;
movw R24,R20
com R24
com R25
adiw R24,1
movw R2,R24
ldi R16, ldi R17,>L48
xcall lpm32
st -y,R19
st -y,R18
st -y,R17
st -y,R16
ldi R16, ldi R17,>L49
xcall lpm32
st -y,R19
st -y,R18
st -y,R17
st -y,R16
movw R16,R2
lsr R17
ror R16
xcall int2fp
st -y,R19
st -y,R18
st -y,R17
st -y,R16
xcall empy32fs
movw R16,R2
andi R16,1
andi R17,0
xcall int2fp
st -y,R19
st -y,R18
st -y,R17
st -y,R16
xcall add32fs
xcall empy32f
sts _temperature+1,R17
sts _temperature,R16
sts _temperature+2+1,R19
sts _temperature+2,R18
xjmp L46
L45:
.dbline 172
; else
; {
.dbline 173
; temperature=t*0.0625;
ldi R16, ldi R17,>L48
xcall lpm32
st -y,R19
st -y,R18
st -y,R17
st -y,R16
ldi R16, ldi R17,>L49
xcall lpm32
st -y,R19
st -y,R18
st -y,R17
st -y,R16
movw R16,R20
lsr R17
ror R16
xcall int2fp
st -y,R19
st -y,R18
st -y,R17
st -y,R16
xcall empy32fs
movw R16,R20
andi R16,1
andi R17,0
xcall int2fp
st -y,R19
st -y,R18
st -y,R17
st -y,R16
xcall add32fs
xcall empy32f
sts _temperature+1,R17
sts _temperature,R16
sts _temperature+2+1,R19
sts _temperature+2,R18
.dbline 174
; }
L46:
.dbline 176
;
; return true;
clr R16
.dbline -2
L33:
adiw R28,9
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r t 20 i
.dbsym l temporary 0 A[9:9]c
.dbsym r i 20 c
.dbend
.dbfunc e Read_RomCode _Read_RomCode fc
; temp -> R20,R21
.even
_Read_RomCode::
xcall push_gset1
movw R20,R16
.dbline -1
.dbline 187
; }
; }
;
; /*===================================================================
; // 函数功能: 读取Rom Code
; // 形参: *temp DS18B20的Rom Code存储空间
; // 返回: unsigned char true为有效
; // 编写: 2004/8/25
; ===================================================================*/
; unsigned char Read_RomCode(unsigned char *temp)
; {
.dbline 188
; ds1820_ack();
xcall _ds1820_ack
.dbline 189
; write_byte(0x33);
ldi R16,51
xcall _write_byte
.dbline 190
; temp[0] = read_byte();
xcall _read_byte
movw R30,R20
std z+0,R16
.dbline 191
; temp[1] = read_byte();
xcall _read_byte
movw R30,R20
std z+1,R16
.dbline 192
; temp[2] = read_byte();
xcall _read_byte
movw R30,R20
std z+2,R16
.dbline 193
; temp[3] = read_byte();
xcall _read_byte
movw R30,R20
std z+3,R16
.dbline 194
; temp[4] = read_byte();
xcall _read_byte
movw R30,R20
std z+4,R16
.dbline 195
; temp[5] = read_byte();
xcall _read_byte
movw R30,R20
std z+5,R16
.dbline 196
; temp[6] = read_byte();
xcall _read_byte
movw R30,R20
std z+6,R16
.dbline 197
; temp[7] = read_byte();
xcall _read_byte
movw R30,R20
std z+7,R16
.dbline 198
; if(crccheck(temp,8))
ldi R18,8
movw R16,R20
xcall _crccheck
tst R16
breq L51
.dbline 199
; return false;
ldi R16,1
xjmp L50
L51:
.dbline 201
; else
; return true;
clr R16
.dbline -2
L50:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r temp 20 pc
.dbend
.dbfunc e ds1820_match _ds1820_match fV
; i -> R20
; p -> R22,R23
.even
_ds1820_match::
xcall push_gset2
movw R22,R16
.dbline -1
.dbline 211
; }
;
; /*===================================================================
; // 函数功能: 匹配DS18B20
; // 形参: *p DS18B20的Rom Code
; // 返回: void
; // 编写: 2004/8/25
; ===================================================================*/
; void ds1820_match(unsigned char *p)
; {
.dbline 213
; unsigned char i;
; ds1820_ack();
xcall _ds1820_ack
.dbline 214
; write_byte(0x55);
ldi R16,85
xcall _write_byte
.dbline 215
; for(i=0;i clr R20
xjmp L57
L54:
.dbline 216
mov R30,R20
clr R31
add R30,R22
adc R31,R23
ldd R16,z+0
xcall _write_byte
L55:
.dbline 215
inc R20
L57:
.dbline 215
cpi R20,8
brlo L54
.dbline -2
.dbline 217
; write_byte(p[i]);
; }
L53:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r i 20 c
.dbsym r p 22 pc
.dbend
.area bss(ram, con, rel)
.dbfile D:\MY_COMPUTER\d\avr16\atmegal16\DS18B20.C
_temperature::
.blkb 4
.dbsym e temperature _temperature D
.area lit(rom, con, rel)
L49:
.word 0x0,0x4000
L48:
.word 0x0,0x3d80