📄 16ds18b20.lst
字号:
__text_start:
__start:
0051 EFCF LDI R28,0xFF
0052 E1D0 LDI R29,0x10
0053 BFCD OUT 0x3D,R28
0054 BFDE OUT 0x3E,R29
0055 51C0 SUBI R28,0x10
0056 40D0 SBCI R29,0
0057 EA0A LDI R16,0xAA
0058 8308 STD Y+0,R16
0059 2400 CLR R0
005A E1E5 LDI R30,0x15
005B E0F1 LDI R31,1
005C E011 LDI R17,1
005D 31E7 CPI R30,0x17
005E 07F1 CPC R31,R17
005F F011 BEQ 0x0062
0060 9201 ST R0,Z+
0061 CFFB RJMP 0x005D
0062 8300 STD Z+0,R16
0063 E8EC LDI R30,0x8C
0064 E0F0 LDI R31,0
0065 E0A0 LDI R26,0
0066 E0B1 LDI R27,1
0067 E010 LDI R17,0
0068 3AE1 CPI R30,0xA1
0069 07F1 CPC R31,R17
006A F021 BEQ 0x006F
006B 95C8 LPM
006C 9631 ADIW R30,1
006D 920D ST R0,X+
006E CFF9 RJMP 0x0068
006F 940E018A CALL _main
_exit:
0071 CFFF RJMP _exit
FILE: E:\ICCAVR\project\AVRMEG~3\icc\016-DS18B20-LED4\DS1820.C
(0001) /*
(0002) DS18B20操作模块
(0003)
(0004) 1、DS18B20的电源脚接到VCC及GND上面,数据线接到PA7口。
(0005) 2、晶振频率为内部1MHz。
(0006) 3、DS18B20由PA7口实现单总线访问,实现读取温度。
(0007) 4、函数中有对中断的保护处理,更具有实用价值。
(0008) 5、此文件可以直接嵌入到项目中使用。
(0009)
(0010) AVR mega16学习板
(0011) AVR_AFA
(0012) www.iccavr.com
(0013) 11:48 2007-6-30
(0014) */
(0015)
(0016) #include <iom128v.h>
(0017) #include <macros.h>
(0018)
(0019) #define DQ_IN DDRF &= ~(1 << PF2) /*设置输入*/
(0020) #define DQ_OUT DDRF |= (1 << PF2) /*设置输出*/
(0021) #define DQ_CLR PORTF &= ~(1 << PF2) /*置低电平*/
(0022) #define DQ_SET PORTF |= (1 << PF2) /*置高电平*/
(0023) #define DQ_R PINF & (1 << PF2) /*读了电平*/
(0024)
(0025) unsigned char flag; /*中断标志缓存*/
(0026)
(0027) /*
(0028) 延时函数
(0029)
(0030) 延时时间:i X 10 + 16uS。
(0031) CPU频率为:1MHz。
(0032) */
(0033) void delay_10us(unsigned char i) {
(0034)
(0035) if (i == 0) {
_delay_10us:
i --> R16
0072 2300 TST R16
0073 F429 BNE 0x0079
(0036) return ;
0074 C009 RJMP 0x007E
(0037) }
(0038) while (i--) {
(0039) NOP();
0075 0000 NOP
(0040) NOP();
0076 0000 NOP
(0041) NOP();
0077 0000 NOP
(0042) NOP();
0078 0000 NOP
0079 2E20 MOV R2,R16
007A 2433 CLR R3
007B 5001 SUBI R16,1
007C 2022 TST R2
007D F7B9 BNE 0x0075
007E 9508 RET
_ds1820_reset:
i --> R20
007F 940E0270 CALL push_gset1
(0043) }
(0044) }
(0045)
(0046) /*DS18B20复位函数*/
(0047) unsigned char ds1820_reset(void) {
(0048)
(0049) unsigned char i;
(0050) flag = SREG; /*中断保护*/
0081 B62F IN R2,0x3F
0082 92200115 STS flag,R2
(0051) CLI(); /*关中断*/
0084 94F8 BCLR 7
(0052) DQ_OUT;
0085 91800061 LDS R24,0x61
0087 6084 ORI R24,4
0088 93800061 STS 0x61,R24
(0053) DQ_CLR;
008A 91800062 LDS R24,0x62
008C 7F8B ANDI R24,0xFB
008D 93800062 STS 0x62,R24
(0054) delay_10us(49); /*延时500uS(480-960)*/
008F E301 LDI R16,0x31
0090 DFE1 RCALL _delay_10us
(0055) DQ_SET;
0091 91800062 LDS R24,0x62
0093 6084 ORI R24,4
0094 93800062 STS 0x62,R24
(0056) DQ_IN;
0096 91800061 LDS R24,0x61
0098 7F8B ANDI R24,0xFB
0099 93800061 STS 0x61,R24
(0057) delay_10us(7); /*延时80uS*/
009B E007 LDI R16,7
009C DFD5 RCALL _delay_10us
(0058) i = DQ_R;
009D B140 IN R20,0x00
009E 7044 ANDI R20,4
(0059) delay_10us(49); /*延时500uS(保持>480uS)*/
009F E301 LDI R16,0x31
00A0 DFD1 RCALL _delay_10us
(0060) if (flag & 0x80) { /*恢复中断状态*/
00A1 90200115 LDS R2,flag
00A3 FE27 SBRS R2,7
00A4 C001 RJMP 0x00A6
(0061) SEI();
00A5 9478 BSET 7
(0062) }
(0063) if (i) {
00A6 2344 TST R20
00A7 F011 BEQ 0x00AA
(0064) return 0x00;
00A8 2700 CLR R16
00A9 C001 RJMP 0x00AB
(0065) }
(0066) else {
(0067) return 0x01;
00AA E001 LDI R16,1
00AB 940E0273 CALL pop_gset1
00AD 9508 RET
_ds1820_read_byte:
value --> R20
i --> R22
00AE 940E026E CALL push_gset2
(0068) }
(0069) }
(0070)
(0071) /*DS18B20字节读取函数*/
(0072) unsigned char ds1820_read_byte(void) {
(0073)
(0074) unsigned char i;
(0075) unsigned char value = 0;
00B0 2744 CLR R20
(0076) flag = SREG; /*中断保护*/
00B1 B62F IN R2,0x3F
00B2 92200115 STS flag,R2
(0077) CLI(); /*关中断*/
00B4 94F8 BCLR 7
(0078) for (i = 8; i != 0; i--) {
00B5 E068 LDI R22,0x8
00B6 C029 RJMP 0x00E0
(0079) value >>= 1;
00B7 9546 LSR R20
(0080) DQ_OUT;
00B8 91800061 LDS R24,0x61
00BA 6084 ORI R24,4
00BB 93800061 STS 0x61,R24
(0081) DQ_CLR;
00BD 91800062 LDS R24,0x62
00BF 7F8B ANDI R24,0xFB
00C0 93800062 STS 0x62,R24
(0082) NOP(); /*延时4uS*/
00C2 0000 NOP
(0083) NOP();
00C3 0000 NOP
(0084) NOP();
00C4 0000 NOP
(0085) NOP();
00C5 0000 NOP
(0086) DQ_SET;
00C6 91800062 LDS R24,0x62
00C8 6084 ORI R24,4
00C9 93800062 STS 0x62,R24
(0087) DQ_IN;
00CB 91800061 LDS R24,0x61
00CD 7F8B ANDI R24,0xFB
00CE 93800061 STS 0x61,R24
(0088) NOP(); /*延时10uS*/
00D0 0000 NOP
(0089) NOP();
00D1 0000 NOP
(0090) NOP();
00D2 0000 NOP
(0091) NOP();
00D3 0000 NOP
(0092) NOP();
00D4 0000 NOP
(0093) NOP();
00D5 0000 NOP
(0094) NOP();
00D6 0000 NOP
(0095) NOP();
00D7 0000 NOP
(0096) NOP();
00D8 0000 NOP
(0097) NOP();
00D9 0000 NOP
(0098) if (DQ_R) {
00DA 9B02 SBIS 0x00,2
00DB C001 RJMP 0x00DD
(0099) value|=0x80;
00DC 6840 ORI R20,0x80
(0100) }
(0101) delay_10us(5); /*延时60uS*/
00DD E005 LDI R16,5
00DE DF93 RCALL _delay_10us
00DF 956A DEC R22
00E0 2366 TST R22
00E1 F6A9 BNE 0x00B7
(0102) }
(0103) if (flag & 0x80) { /*恢复中断状态*/
00E2 90200115 LDS R2,flag
00E4 FE27 SBRS R2,7
00E5 C001 RJMP 0x00E7
(0104) SEI();
00E6 9478 BSET 7
(0105) }
(0106) return(value);
00E7 2F04 MOV R16,R20
00E8 940E0265 CALL pop_gset2
00EA 9508 RET
_ds1820_write_byte:
i --> R20
value --> R22
00EB 940E026E CALL push_gset2
00ED 2F60 MOV R22,R16
(0107) }
(0108)
(0109) /*DS18B20字节写入函数*/
(0110) void ds1820_write_byte(unsigned char value) {
(0111)
(0112) unsigned char i;
(0113) flag = SREG; /*中断保护*/
00EE B62F IN R2,0x3F
00EF 92200115 STS flag,R2
(0114) CLI(); /*关中断*/
00F1 94F8 BCLR 7
(0115) for (i = 8; i != 0; i--) {
00F2 E048 LDI R20,0x8
00F3 C01E RJMP 0x0112
(0116) DQ_OUT;
00F4 91800061 LDS R24,0x61
00F6 6084 ORI R24,4
00F7 93800061 STS 0x61,R24
(0117) DQ_CLR;
00F9 91800062 LDS R24,0x62
00FB 7F8B ANDI R24,0xFB
00FC 93800062 STS 0x62,R24
(0118) NOP(); /*延时4uS*/
00FE 0000 NOP
(0119) NOP();
00FF 0000 NOP
(0120) NOP();
0100 0000 NOP
(0121) NOP();
0101 0000 NOP
(0122) if (value & 0x01) {
0102 FF60 SBRS R22,0
0103 C005 RJMP 0x0109
(0123) DQ_SET;
0104 91800062 LDS R24,0x62
0106 6084 ORI R24,4
0107 93800062 STS 0x62,R24
(0124) }
(0125) delay_10us(7); /*延时80uS*/
0109 E007 LDI R16,7
010A DF67 RCALL _delay_10us
(0126) DQ_SET; /*位结束*/
010B 91800062 LDS R24,0x62
010D 6084 ORI R24,4
010E 93800062 STS 0x62,R24
(0127) value >>= 1;
0110 9566 LSR R22
0111 954A DEC R20
0112 2344 TST R20
0113 F701 BNE 0x00F4
(0128) }
(0129) if (flag & 0x80) { /*恢复中断状态*/
0114 90200115 LDS R2,flag
0116 FE27 SBRS R2,7
0117 C001 RJMP 0x0119
(0130) SEI();
0118 9478 BSET 7
(0131) }
0119 940E0265 CALL pop_gset2
011B 9508 RET
(0132) }
(0133)
(0134) /*启动ds1820转换*/
(0135) void ds1820_start(void) {
(0136)
(0137) ds1820_reset();
_ds1820_start:
011C DF62 RCALL _ds1820_reset
(0138) ds1820_write_byte(0xCC); /*勿略地址*/
011D EC0C LDI R16,0xCC
011E DFCC RCALL _ds1820_write_byte
(0139) ds1820_write_byte(0x44); /*启动转换*/
011F E404 LDI R16,0x44
0120 DFCA RCALL _ds1820_write_byte
0121 9508 RET
_ds1820_read_temp:
buf --> Y+0
i --> R20
0122 940E0270 CALL push_gset1
0124 9729 SBIW R28,0x9
(0140) }
(0141)
(0142) /*DS8B20读取温度信息*/
(0143) unsigned int ds1820_read_temp(void) {
(0144)
(0145) unsigned int i;
(0146) unsigned char buf[9];
(0147)
(0148) ds1820_reset();
0125 DF59 RCALL _ds1820_reset
(0149) ds1820_write_byte(0xCC); /*勿略地址*/
0126 EC0C LDI R16,0xCC
0127 DFC3 RCALL _ds1820_write_byte
(0150) ds1820_write_byte(0xBE); /*读取温度*/
0128 EB0E LDI R16,0xBE
0129 DFC1 RCALL _ds1820_write_byte
(0151) for (i = 0; i < 9; i++) {
012A 2744 CLR R20
012B 2755 CLR R21
012C C008 RJMP 0x0135
(0152) buf[i] = ds1820_read_byte();
012D DF80 RCALL _ds1820_read_byte
012E 01CE MOVW R24,R28
012F 01FA MOVW R30,R20
0130 0FE8 ADD R30,R24
0131 1FF9 ADC R31,R25
0132 8300 STD Z+0,R16
0133 5F4F SUBI R20,0xFF
0134 4F5F SBCI R21,0xFF
0135 3049 CPI R20,0x9
0136 E0E0 LDI R30,0
0137 075E CPC R21,R30
0138 F3A0 BCS 0x012D
(0153) }
(0154) i = buf[1];
0139 8149 LDD R20,Y+1
013A 2755 CLR R21
(0155) i <<= 8;
013B 2F54 MOV R21,R20
013C 2744 CLR R20
(0156) i |= buf[0];
013D 8028 LDD R2,Y+0
013E 2433 CLR R3
013F 2942 OR R20,R2
0140 2953 OR R21,R3
(0157)
(0158) return i;
0141 018A MOVW R16,R20
0142 9629 ADIW R28,0x9
0143 940E0273 CALL pop_gset1
0145 9508 RET
_delay_ms:
b --> R20
i --> R16
0146 940E0270 CALL push_gset1
FILE: E:\ICCAVR\project\AVRMEG~3\icc\016-DS18B20-LED4\main.c
(0001) /*
(0002) 实验十六:
(0003)
(0004) DS18B20实验,动态LED数据管显示温度。
(0005) 1、AVR单片机读取DS18B20实验,并通过学习板上在LED数码管显示温度。
(0006) 2、晶振频率为内部1MHz。
(0007) 3、DS18B20由PA7口实现单总线访问,实现读取温度。
(0008) 4、低层驱动函数中带有中断保护,程序可直接用于商业产品中。
(0009) 5、LED数码管显示采用定时器中断方式,全中断驱动,不需要主程序管理,
(0010) 只要把要显示的内部放到显示缓存区就行了。
(0011) 6、进行此实验请插上SPI短路块。
(0012) 7、DS18B20的电源脚接到VCC及GND上面,数据线接到PF2口。
(0013)
(0014) AVR mega128学习板
(0015) AVR_AFA
(0016) www.iccavr.com
(0017) 11:48 2007-10-170
(0018) */
(0019)
(0020) #include "iom128v.h" /*包含相关头文件*/
(0021) #include "ds1820.h"
(0022) #include "led4.h"
(0023)
(0024) /*
(0025) 延时函数
(0026)
(0027) 延时单位为:mS。
(0028) CPU频率为:1MHz。
(0029) */
(0030) void delay_ms(unsigned int i) {
0148 C005 RJMP 0x014E
(0031)
(0032) unsigned char b;
(0033) while (i --) {
(0034) for (b = 1; b; b++);
0149 E041 LDI R20,1
014A C001 RJMP 0x014C
014B 9543 INC R20
014C 2344 TST R20
014D F7E9 BNE 0x014B
014E 0118 MOVW R2,R16
014F 5001 SUBI R16,1
0150 4010 SBCI R17,0
0151 2022 TST R2
0152 F7B1 BNE 0x0149
0153 2033 TST R3
0154 F7A1 BNE 0x0149
0155 940E0273 CALL pop_gset1
0157 9508 RET
(0035) }
(0036) }
(0037)
(0038) /*IO口初始化函数*/
(0039) void io_init(void) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -