📄 ds18b20.lst
字号:
0120 912F POP R18
0121 2C4A MOV R4,R10
0122 2455 CLR R5
0123 0C24 ADD R2,R4
0124 1C35 ADC R3,R5
0125 E086 LDI R24,6
0126 E090 LDI R25,0
0127 932F PUSH R18
0128 933F PUSH R19
0129 019C MOVW R18,R24
012A 0181 MOVW R16,R2
012B 940E027B CALL mod16s
012D 01F8 MOVW R30,R16
012E 913F POP R19
012F 912F POP R18
0130 0FE6 ADD R30,R22
0131 1FF7 ADC R31,R23
0132 8100 LDD R16,0+Z
0133 DF96 RCALL _One_smg_display
(0073) Delayus(2000); //调整显示时间和亮度(时间越长亮度越高,但是太长数码管就闪了)
0134 ED00 LDI R16,0xD0
0135 E017 LDI R17,7
0136 DF3F RCALL _Delayus
0137 94A3 INC R10
0138 2D8A MOV R24,R10
0139 3086 CPI R24,6
013A F2C0 BCS 0x0113
013B 9543 INC R20
013C 3F40 CPI R20,0xF0
013D F298 BCS 0x0111
(0074) }
(0075) }
(0076) } 013E 940E04A1 CALL pop_gset3
0140 9508 RET
FILE: C:\icc\examples.avr\AVR_PQ1A_DEMO\11_DS18B20\DS18B20.C
(0001) /*******************************************
(0002) 文件:DS18B20.C
(0003) 环境:编译为ICC AVR6.25A,仿真为AVR Studio4.10
(0004) 硬件:ATMEGA16芯片
(0005) 日期:2006年12月10日
(0006) 功能:驱动开发板上的温度传感器DS18B20(作者只做了正温度值的显示,负温度值的显示读者可自行编写)。
(0007) 备注:参考《AVR系列单片机C语言编程与应用实例》(清华大学出版社)
(0008) /******************************************/
(0009) #include <iom16v.h> //包含型号头文件
(0010) #include <macros.h> //包含"位"操作头文件
(0011) #include <stdio.h> //标准输入输出头文件
(0012) #include <AVR_PQ1A.h> //包含自定义常量头文件
(0013) #include "SMG.C" //包含数码管显示函数
(0014)
(0015) /*******************************************
(0016) 函数名称: B20_init
(0017) 功 能: 复位DS18B20
(0018) 参 数: 无
(0019) 返回值 : 无
(0020) /********************************************/
(0021) void B20_init(void)
(0022) {
(0023) DDRA|=BIT(DS18B20); //配置为输出
_B20_init:
0141 9AD5 SBI P1A,5
(0024) PORTA&=~BIT(DS18B20); //拉低
0142 98DD CBI P1B,5
(0025) Delayus(600); //等待600微秒
0143 E508 LDI R16,0x58
0144 E012 LDI R17,2
0145 DF30 RCALL _Delayus
(0026) PORTA|=BIT(DS18B20); //释放总线
0146 9ADD SBI P1B,5
(0027) Delayus(60); //等待60微秒
0147 E30C LDI R16,0x3C
0148 E010 LDI R17,0
0149 DF2C RCALL _Delayus
(0028) DDRA&=~BIT(DS18B20); //配置为输入
014A 98D5 CBI P1A,5
(0029) while((PINA&(BIT(DS18B20)))); //等待DS18B20拉低
014B 99CD SBIC P19,5
014C CFFE RJMP 0x014B
(0030) while(!(PINA&(BIT(DS18B20)))); //等待DS18B20释放总线
014D 9BCD SBIS P19,5
014E CFFE RJMP 0x014D
(0031) }
014F 9508 RET
_B20_readB:
retd --> R20
i --> R22
0150 940E0496 CALL push_gset2
(0032) /*******************************************
(0033) 函数名称: B20_readB
(0034) 功 能: 读取一个字节的数据
(0035) 参 数: 无
(0036) 返回值 : retd--返回的一个字节数据
(0037) /********************************************/
(0038) uchar B20_readB(void)
(0039) {
(0040) uchar i,retd=0;
0152 2744 CLR R20
(0041) for(i=0;i<8;i++) //位计数值
0153 2766 CLR R22
0154 C00F RJMP 0x0164
(0042) {
(0043) retd>>=1; //右移,准备接受新的数据位
0155 9546 LSR R20
(0044) DDRA|=BIT(DS18B20); //配置为输出
0156 9AD5 SBI P1A,5
(0045) PORTA&=~BIT(DS18B20); //拉低,启动读数据位
0157 98DD CBI P1B,5
(0046) PORTA|=BIT(DS18B20); //释放总线
0158 9ADD SBI P1B,5
(0047) Delayus(5); //等待5微秒
0159 E005 LDI R16,5
015A E010 LDI R17,0
015B DF1A RCALL _Delayus
(0048) DDRA&=~BIT(DS18B20); //配置为输入,开始读取数据位
015C 98D5 CBI P1A,5
(0049) if(PINA&BIT(DS18B20)) //该位是否为高
015D 9BCD SBIS P19,5
015E C001 RJMP 0x0160
(0050) {
(0051) retd|=0x80; //是就将此位置高
015F 6840 ORI R20,0x80
(0052) }
(0053) Delayus(50); //等待50微秒
0160 E302 LDI R16,0x32
0161 E010 LDI R17,0
0162 DF13 RCALL _Delayus
0163 9563 INC R22
0164 3068 CPI R22,0x8
0165 F378 BCS 0x0155
(0054) }
(0055) return retd; //将读到的一个字节返回
0166 2F04 MOV R16,R20
0167 940E049E CALL pop_gset2
0169 9508 RET
_B20_writeB:
i --> R20
wrd --> R22
016A 940E0496 CALL push_gset2
016C 2F60 MOV R22,R16
(0056) }
(0057) /*******************************************
(0058) 函数名称: B20_writeB
(0059) 功 能: 写入一个字节的数据
(0060) 参 数: wrd--要写入的数据
(0061) 返回值 : 无
(0062) /********************************************/
(0063) void B20_writeB(uchar wrd)
(0064) {
(0065) uchar i;
(0066) for(i=0;i<8;i++) //位计数值
016D 2744 CLR R20
016E C010 RJMP 0x017F
(0067) {
(0068) DDRA|=BIT(DS18B20); //配置为输出
016F 9AD5 SBI P1A,5
(0069) PORTA&=~BIT(DS18B20); //拉低,启动写数据位
0170 98DD CBI P1B,5
(0070) Delayus(1); //等待1微秒
0171 E001 LDI R16,1
0172 E010 LDI R17,0
0173 DF02 RCALL _Delayus
(0071) if(wrd&0x01) //此位数据是否为高
0174 FF60 SBRS R22,0
0175 C002 RJMP 0x0178
(0072) {
(0073) PORTA|=BIT(DS18B20); //是高则将单总线拉高
0176 9ADD SBI P1B,5
(0074) }
0177 C001 RJMP 0x0179
(0075) else
(0076) {
(0077) PORTA&=~BIT(DS18B20); //是低则将单总线拉低
0178 98DD CBI P1B,5
(0078) }
(0079) Delayus(50); //等待50微秒
0179 E302 LDI R16,0x32
017A E010 LDI R17,0
017B DEFA RCALL _Delayus
(0080) PORTA|=BIT(DS18B20); //释放总线
017C 9ADD SBI P1B,5
(0081) wrd>>=1; //右移,为写入新的数据位做准备
017D 9566 LSR R22
017E 9543 INC R20
017F 3048 CPI R20,0x8
0180 F370 BCS 0x016F
(0082) }
(0083) Delayus(50); //等待50微秒
0181 E302 LDI R16,0x32
0182 E010 LDI R17,0
0183 DEF2 RCALL _Delayus
(0084) }
0184 940E049E CALL pop_gset2
0186 9508 RET
_Read_temp:
temp --> R20
temph --> R22
templ --> R20
0187 940E0496 CALL push_gset2
(0085) /*******************************************
(0086) 函数名称: Read_temp
(0087) 功 能: 读取温度值
(0088) 参 数: 无
(0089) 返回值 : rettemp--返回的温度值
(0090) /********************************************/
(0091) uint Read_temp(void)
(0092) {
(0093) uchar templ,temph;
(0094) uint temp;
(0095) B20_init(); //初始化,每次写命令都从初始化开始
0189 DFB7 RCALL _B20_init
(0096) B20_writeB(0xcc); //跳过ROM
018A EC0C LDI R16,0xCC
018B DFDE RCALL _B20_writeB
(0097) B20_writeB(0x44); //启动温度转换
018C E404 LDI R16,0x44
018D DFDC RCALL _B20_writeB
(0098) B20_init(); //初始化,每次写命令都从初始化开始
018E DFB2 RCALL _B20_init
(0099) B20_writeB(0xcc); //跳过ROM
018F EC0C LDI R16,0xCC
0190 DFD9 RCALL _B20_writeB
(0100) B20_writeB(0xbe); //读寄存器
0191 EB0E LDI R16,0xBE
0192 DFD7 RCALL _B20_writeB
(0101) templ=B20_readB(); //读温度低字节
0193 DFBC RCALL _B20_readB
0194 2F40 MOV R20,R16
(0102) temph=B20_readB(); //读温度高字节
0195 DFBA RCALL _B20_readB
0196 2F60 MOV R22,R16
(0103) temp=templ+temph*256;//将温度整理成16位变量
0197 2F26 MOV R18,R22
0198 2733 CLR R19
0199 E000 LDI R16,0
019A E011 LDI R17,1
019B 940E0298 CALL empy16s
019D 2E24 MOV R2,R20
019E 2433 CLR R3
019F 0E20 ADD R2,R16
01A0 1E31 ADC R3,R17
01A1 01A1 MOVW R20,R2
(0104) return temp; //返回16位变量
01A2 2D02 MOV R16,R2
01A3 2D13 MOV R17,R3
01A4 940E049E CALL pop_gset2
01A6 9508 RET
_Num_BCD:
rept --> R20
chr --> Y+0
i --> R22
num --> R10
01A7 940E049A CALL push_gset3
01A9 0158 MOVW R10,R16
01AA 9723 SBIW R28,3
(0105) }
(0106) /*******************************************
(0107) 函数名称: Num_BCD
(0108) 功 能: 将一个字节的整数转换成三位BCD码
(0109) 参 数: num--需要转换的整数
(0110) 返回值 : chr--三位BCD码数组指针
(0111) /********************************************/
(0112) uchar* Num_BCD(uint num)
(0113) {
(0114) uchar i,chr[3];
(0115) uchar *rept;
(0116) rept=&(chr[0]); //返回指针指向BCD码数组
01AB 01AE MOVW R20,R28
(0117) for(i=0;i<3;i++)
01AC 2766 CLR R22
01AD C016 RJMP 0x01C4
(0118) {
(0119) chr[2-i]=num%10; //对10取余数(其实是求模,但是对于正数,取余与求模是相等的)
01AE 2E26 MOV R2,R22
01AF 2433 CLR R3
01B0 E0E2 LDI R30,2
01B1 E0F0 LDI R31,0
01B2 19E2 SUB R30,R2
01B3 09F3 SBC R31,R3
01B4 01CE MOVW R24,R28
01B5 0FE8 ADD R30,R24
01B6 1FF9 ADC R31,R25
01B7 E02A LDI R18,0xA
01B8 E030 LDI R19,0
01B9 0185 MOVW R16,R10
01BA 940E025F CALL mod16u
01BC 8300 STD R16,0+Z
(0120) num/=10; //除以10,为取出下一位做准备
01BD E02A LDI R18,0xA
01BE E030 LDI R19,0
01BF 0185 MOVW R16,R10
01C0 940E0261 CALL div16u
01C2 0158 MOVW R10,R16
01C3 9563 INC R22
01C4 3063 CPI R22,3
01C5 F340 BCS 0x01AE
(0121) }
(0122) return rept; //返回指针
01C6 2F04 MOV R16,R20
01C7 2F15 MOV R17,R21
01C8 9623 ADIW R28,3
01C9 940E04A1 CALL pop_gset3
01CB 9508 RET
_main:
t --> R22
temppt --> R10
temp --> Y+0
i --> R20
01CC 9727 SBIW R28,7
(0123) }
(0124) /*******************************************
(0125) 函数名称: main
(0126) 功 能: 完成温度的读取与显示
(0127) 参 数: 无
(0128) 返回值 : 无
(0129) /********************************************/
(0130) void main(void)
(0131) {
(0132) uint t;
(0133) uchar *temppt;
(0134) uchar i,temp[3];
(0135) Board_init( ); //初始化开发板
01CD DED6 RCALL _Board_init
01CE C08D RJMP 0x025C
(0136) while(1)
(0137) {
(0138) t=Read_temp(); //读取温度值
01CF DFB7 RCALL _Read_temp
01D0 01B8 MOVW R22,R16
(0139) t*=0.625; //转换成实际温度的10倍
01D1 E90C LDI R16,0x9C
01D2 E010 LDI R17,0
01D3 940E04A4 CALL lpm32
01D5 933A ST R19,-Y
01D6 932A ST R18,-Y
01D7 931A ST R17,-Y
01D8 930A ST R16,-Y
01D9 E908 LDI R16,0x98
01DA E010 LDI R17,0
01DB 940E04A4 CALL lpm32
01DD 933A ST R19,-Y
01DE 932A ST R18,-Y
01DF 931A ST R17,-Y
01E0 930A ST R16,-Y
01E1 018B MOVW R16,R22
01E2 9516 LSR R17
01E3 9507 ROR R16
01E4 940E02A8 CALL int2fp
01E6 933A ST R19,-Y
01E7 932A ST R18,-Y
01E8 931A ST R17,-Y
01E9 930A ST R16,-Y
01EA 940E0400 CALL empy32fs
01EC 018B MOVW R16,R22
01ED 7001 ANDI R16,1
01EE 7010 ANDI R17,0
01EF 940E02A8 CALL int2fp
01F1 933A ST R19,-Y
01F2 932A ST R18,-Y
01F3 931A ST R17,-Y
01F4 930A ST R16,-Y
01F5 940E032F CALL add32fs
01F7 940E0403 CALL empy32f
01F9 01FE MOVW R30,R28
01FA 8303 STD R16,3+Z
01FB 8314 STD R17,4+Z
01FC 8325 STD R18,5+Z
01FD 8336 STD R19,6+Z
01FE 8023 LDD R2,3+Z
01FF 8034 LDD R3,4+Z
0200 8045 LDD R4,5+Z
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -