📄 lm75.lst
字号:
1 .file "lm75.c"
2 __SREG__ = 0x3f
3 __SP_H__ = 0x3e
4 __SP_L__ = 0x3d
5 __CCP__ = 0x34
6 __tmp_reg__ = 0
7 __zero_reg__ = 1
8 .global __do_copy_data
9 .global __do_clear_bss
11 .text
12 .Ltext0:
89 .global lm75_init
91 lm75_init:
1:io/lm75.c **** /*
2:io/lm75.c **** ,-----------------------------------------------------------------------------------------.
3:io/lm75.c **** | io/lm75
4:io/lm75.c **** |-----------------------------------------------------------------------------------------
5:io/lm75.c **** | this file supports temperature reading of an i2c temp sensor
6:io/lm75.c **** | - supports LM75 & clones, adjust LM75_DEVICE_ID in config.h !!
7:io/lm75.c **** | - does not check for ACK/NACK/ERROR !
8:io/lm75.c **** |
9:io/lm75.c **** | Author : Simon Schulz / avr{AT}auctionant.de
10:io/lm75.c **** |
11:io/lm75.c **** |
12:io/lm75.c **** |
13:io/lm75.c **** |-----------------------------------------------------------------------------------------
14:io/lm75.c **** | License:
15:io/lm75.c **** | This program is free software; you can redistribute it and/or modify it under
16:io/lm75.c **** | the terms of the GNU General Public License as published by the Free Software
17:io/lm75.c **** | Foundation; either version 2 of the License, or (at your option) any later
18:io/lm75.c **** | version.
19:io/lm75.c **** | This program is distributed in the hope that it will be useful, but
20:io/lm75.c **** |
21:io/lm75.c **** | WITHOUT ANY WARRANTY;
22:io/lm75.c **** |
23:io/lm75.c **** | without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
24:io/lm75.c **** | PURPOSE. See the GNU General Public License for more details.
25:io/lm75.c **** |
26:io/lm75.c **** | You should have received a copy of the GNU General Public License along with
27:io/lm75.c **** | this program; if not, write to the Free Software Foundation, Inc., 51
28:io/lm75.c **** | Franklin St, Fifth Floor, Boston, MA 02110, USA
29:io/lm75.c **** |
30:io/lm75.c **** | http://www.gnu.de/gpl-ger.html
31:io/lm75.c **** `-----------------------------------------------------------------------------------------*/
32:io/lm75.c ****
33:io/lm75.c **** #include "lm75.h"
34:io/lm75.c **** #include "main.h"
35:io/lm75.c ****
36:io/lm75.c **** //ACTIVATE DEBUG by editing this file:
37:io/lm75.c **** #include "debug.h"
38:io/lm75.c ****
39:io/lm75.c **** #include <avr/delay.h>
40:io/lm75.c ****
41:io/lm75.c **** #define LM75_READ 1
42:io/lm75.c **** #define LM75_WRITE 0
43:io/lm75.c ****
44:io/lm75.c **** #define LM75_STATE_IDLE 0
45:io/lm75.c **** #define LM75_STATE_DEVICE_ADDRESS 1
46:io/lm75.c **** #define LM75_STATE_WRITE_CMD0 2
47:io/lm75.c **** #define LM75_STATE_START2 3
48:io/lm75.c **** #define LM75_STATE_DEVICE_ADDRESS2 4
49:io/lm75.c **** #define LM75_STATE_DATA_HI 5
50:io/lm75.c **** #define LM75_STATE_DATA_LO 6
51:io/lm75.c **** #define LM75_STATE_STOP 7
52:io/lm75.c **** #define LM75_STATE_ERROR 8
53:io/lm75.c ****
54:io/lm75.c **** #define LM75_ANSWER_START 0x08
55:io/lm75.c **** #define LM75_ANSWER_RESTART 0x10
56:io/lm75.c **** #define LM75_ANSWER_SLAVE_W_ACK 0x18
57:io/lm75.c **** #define LM75_ANSWER_SLAVE_R_ACK 0x40
58:io/lm75.c **** #define LM75_ANSWER_DATA_ACK 0x28
59:io/lm75.c **** #define LM75_ANSWER_DATA_NACK 0x58
60:io/lm75.c ****
61:io/lm75.c **** volatile unsigned char lm75_state;
62:io/lm75.c **** volatile unsigned int lm75_temp_tmp;
63:io/lm75.c **** void lm75_init(void) {
92 tabn 68,0,67,.LM1-.LFBB1
93 .LM1:
94 out 33-32,__zero_reg__
96 .LM2:
64:io/lm75.c **** d(TWPS0)
65:io/lm75.c **** //has prescaler (mega128 & newer)
66:io/lm75.c **** TWSR = 0;//0;
67:io/lm75.c **** #endif
97 r24,lo8(20)
98 out 32-32,r24
68:io/lm75.c **** low...
69:io/lm75.c **** TWBR = 20; //f(SCL) = F_CPU / (16+2*TWBR)*4^TWPS)
70:io/lm75.c ****
100 3:
101 sts lm75_state,__zero_reg__
103 0004 80B9 .LM4:
71:io/lm75.c **** 75_state = LM75_STATE_IDLE;
72:io/lm75.c ****
104 r24,lo8(64)
105 ldi r25,hi8(64)
106 0006 1092 0000 sts (lm75_temp_tmp)+1,r25
73:io/lm75.c **** m75_temp_tmp = (32<<1);
74:io/lm75.c **** }
107 s lm75_temp_tmp,r24
108 /* epilogue start */
110 000c 90E0 .LM5:
111 000e 9093 0000 ret
113 .Lscope1:
75:io/lm75.c **** /do a nonblocking read. this function must be called
114 "lm75_nonblocking_temp_read:F(0,11)",36,0,0,lm75_nonblocking_temp_read
116 0016 0895 .global lm75_nonblocking_temp_read
118 lm75_nonblocking_temp_read:
120 .LM6:
121 .LFBB2:
122 /* prologue: function */
123 /* frame size = 0 */
76:io/lm75.c **** / ? times in order to read a value.
77:io/lm75.c **** // returns 1 if new value measured, otherwise 0
78:io/lm75.c **** unsigned char lm75_nonblocking_temp_read(unsigned char *data){
79:io/lm75.c **** unsigned char retval = 0;
80:io/lm75.c ****
124 r24
126 .LM7:
127 lds r24,lm75_state
128 cpi r24,lo8(3)
129 0018 FC01 breq .L8
81:io/lm75.c **** ch(lm75_state){
82:io/lm75.c **** //send start cmd & wait for TWI to send it:
83:io/lm75.c **** case(LM75_STATE_IDLE):
130 24,lo8(4)
131 brsh .L13
132 001a 8091 0000 cpi r24,lo8(1)
133 001e 8330 breq .L6
134 0020 01F0 cpi r24,lo8(2)
135 0022 8430 brsh .L7
136 0024 00F4 rjmp .L44
137 0026 8130 .L13:
138 0028 01F0 cpi r24,lo8(5)
139 002a 8230 brne .+2
140 002c 00F4 rjmp .L10
141 002e 00C0 cpi r24,lo8(5)
142 brlo .L9
143 0030 8530 cpi r24,lo8(6)
144 0032 01F4 brne .+2
145 0034 00C0 rjmp .L11
146 0036 8530 cpi r24,lo8(8)
147 0038 00F0 brne .+2
148 003a 8630 rjmp .L12
149 003c 01F4 ldi r25,lo8(0)
150 003e 00C0 rjmp .L14
151 0040 8830 .L44:
152 0042 01F4 .LBB18:
153 0044 00C0 .LBB19:
155 0048 00C0 .LM8:
156 ldi r24,lo8(-92)
157 out 86-32,r24
158 .L15:
84:io/lm75.c **** lm75_send_start();
85:io/lm75.c **** //check for error:
86:io/lm75.c **** if ((TWSR & 0xF8) != LM75_ANSWER_START)
87:io/lm75.c **** lm75_state = LM75_STATE_ERROR;
88:io/lm75.c **** else
89:io/lm75.c **** lm75_state = LM75_STATE_DEVICE_ADDRESS;
90:io/lm75.c **** break;
91:io/lm75.c ****
92:io/lm75.c **** //send device address:
93:io/lm75.c **** case(LM75_STATE_DEVICE_ADDRESS):
94:io/lm75.c **** lm75_send_device_address(LM75_DEVICE_ID | LM75_WRITE);
95:io/lm75.c ****
96:io/lm75.c **** //check for error:
97:io/lm75.c **** if ((TWSR & 0xF8) != LM75_ANSWER_SLAVE_W_ACK)
98:io/lm75.c **** lm75_state = LM75_STATE_ERROR;
99:io/lm75.c **** else
100:io/lm75.c **** lm75_state = LM75_STATE_WRITE_CMD0;
101:io/lm75.c **** break;
102:io/lm75.c ****
103:io/lm75.c **** //send "set temp pointer" cmd
104:io/lm75.c **** case(LM75_STATE_WRITE_CMD0):
105:io/lm75.c **** lm75_send_byte(0x00);
106:io/lm75.c ****
107:io/lm75.c **** //check for error:
108:io/lm75.c **** if ((TWSR & 0xF8) != LM75_ANSWER_DATA_ACK)
109:io/lm75.c **** lm75_state = LM75_STATE_ERROR;
110:io/lm75.c **** else
111:io/lm75.c **** lm75_state = LM75_STATE_START2;
112:io/lm75.c **** break;
113:io/lm75.c ****
114:io/lm75.c **** //send a second start:
115:io/lm75.c **** case(LM75_STATE_START2):
116:io/lm75.c **** lm75_send_start();
117:io/lm75.c ****
118:io/lm75.c **** //check for error:
119:io/lm75.c **** if ((TWSR & 0xF8) != LM75_ANSWER_RESTART)
120:io/lm75.c **** lm75_state = LM75_STATE_ERROR;
121:io/lm75.c **** else
122:io/lm75.c **** lm75_state = LM75_STATE_DEVICE_ADDRESS2;
123:io/lm75.c **** break;
124:io/lm75.c ****
125:io/lm75.c **** //send address again:
126:io/lm75.c **** case(LM75_STATE_DEVICE_ADDRESS2):
127:io/lm75.c **** lm75_send_device_address(LM75_DEVICE_ID | LM75_READ);
128:io/lm75.c ****
129:io/lm75.c **** //check for error:
130:io/lm75.c **** if ((TWSR & 0xF8) != LM75_ANSWER_SLAVE_R_ACK)
131:io/lm75.c **** lm75_state = LM75_STATE_ERROR;
132:io/lm75.c **** else
133:io/lm75.c **** lm75_state = LM75_STATE_DATA_HI;
134:io/lm75.c **** break;
135:io/lm75.c ****
136:io/lm75.c **** //read data hi:
137:io/lm75.c **** case(LM75_STATE_DATA_HI):
138:io/lm75.c **** lm75_temp_tmp = (lm75_read()<<8);
139:io/lm75.c ****
140:io/lm75.c **** //check for error:
141:io/lm75.c **** if ((TWSR & 0xF8) != LM75_ANSWER_DATA_NACK)
142:io/lm75.c **** lm75_state = LM75_STATE_ERROR;
143:io/lm75.c **** else
144:io/lm75.c **** lm75_state = LM75_STATE_DATA_LO;
145:io/lm75.c **** break;
146:io/lm75.c ****
147:io/lm75.c **** //read data lo:
148:io/lm75.c **** case(LM75_STATE_DATA_LO):
149:io/lm75.c **** lm75_temp_tmp |= lm75_read();
150:io/lm75.c ****
151:io/lm75.c **** //is temp negative ? -> convert
152:io/lm75.c **** if (lm75_temp_tmp&0x8000){
153:io/lm75.c **** //convert from 2s complement:
154:io/lm75.c **** lm75_temp_tmp = (0xFFFF-lm75_temp_tmp)|0x8000;
155:io/lm75.c **** }
156:io/lm75.c ****
157:io/lm75.c **** //tttt tttt t000 0000 -> 0000 000t tttt tttt
158:io/lm75.c **** lm75_temp_tmp = lm75_temp_tmp>>7;
159:io/lm75.c ****
160:io/lm75.c **** //now convert temperature to an 8 bit value.
161:io/lm75.c **** //-> we are interested in -32.0 to +96.5 degrees
162:io/lm75.c **** lm75_temp_tmp = lm75_temp_tmp + (32<<1);
163:io/lm75.c ****
164:io/lm75.c **** //limit range 1:
165:io/lm75.c **** if (lm75_temp_tmp < 0)
166:io/lm75.c **** lm75_temp_tmp = 0;
167:io/lm75.c ****
168:io/lm75.c **** //limit range 2:
169:io/lm75.c **** if (lm75_temp_tmp >= 255){
170:io/lm75.c **** lm75_temp_tmp = 255;
171:io/lm75.c **** return 0;
172:io/lm75.c **** }
173:io/lm75.c ****
174:io/lm75.c **** /*
175:io/lm75.c **** //convert to temp vale. 205 = 20.5 °C
176:io/lm75.c **** //tttt tttt t000 0000 -> 0000 000t tttt tttt
177:io/lm75.c **** lm75_temp_tmp = lm75_temp_tmp>>7;
178:io/lm75.c ****
179:io/lm75.c **** //convert to temp vale. 205 = 20.5 °C
180:io/lm75.c **** (*data) = ((lm75_temp_tmp>>1)&0x007F)*10;
181:io/lm75.c ****
182:io/lm75.c **** //add 0.5°C step:
183:io/lm75.c **** if (lm75_temp_tmp&0x0001)
184:io/lm75.c **** *data = (*data) + 5;
185:io/lm75.c **** //is temp negative ?
186:io/lm75.c **** if (lm75_temp_tmp&0x0100)
187:io/lm75.c **** *data = -(*data);
188:io/lm75.c **** */
189:io/lm75.c **** (*data) = (lm75_temp_tmp)&0xFF;
190:io/lm75.c **** //success:
191:io/lm75.c **** retval = 1;
192:io/lm75.c ****
193:io/lm75.c **** //dont check for error, next state is always stop:
194:io/lm75.c **** case(LM75_STATE_STOP):
195:io/lm75.c **** default:
196:io/lm75.c **** lm75_send_stop();
197:io/lm75.c **** lm75_state = LM75_STATE_IDLE;
198:io/lm75.c **** break;
199:io/lm75.c **** case(LM75_STATE_ERROR):
200:io/lm75.c **** #if LM75_DEBUG
201:io/lm75.c **** softuart_puts_progmem("LM75: error in state ");
202:io/lm75.c **** softuart_put_uint8(lm75_state);
203:io/lm75.c **** softuart_puts_progmem(" TWSR=");
204:io/lm75.c **** softuart_put_uint8(TWSR);
205:io/lm75.c **** softuart_putnewline();
206:io/lm75.c **** #endif
207:io/lm75.c **** lm75_state = LM75_STATE_STOP;
208:io/lm75.c **** }
209:io/lm75.c ****
210:io/lm75.c **** return retval;
211:io/lm75.c **** }
212:io/lm75.c ****
213:io/lm75.c **** void lm75_send_start(){
214:io/lm75.c **** //start cond.
215:io/lm75.c **** TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
216:io/lm75.c **** while (!(TWCR & (1 << TWINT)));
217:io/lm75.c **** }
159 .LM9:
160 in __tmp_reg__,86-32
161 004a 84EA sbrs __tmp_reg__,7
162 004c 86BF rjmp .L15
163 .LBE19:
218:io/lm75.c **** char addr){
164 8:
166 004e 06B6 .LM10:
167 0050 07FE in r24,33-32
168 0052 00C0 andi r24,lo8(-8)
169 cpi r24,lo8(8)
170 breq .+2
171 rjmp .L43
172 .L16:
174 0056 887F .LM11:
175 0058 8830 ldi r24,lo8(1)
176 005a 01F0 rjmp .L40
177 005c 00C0 .L6:
178 .LBB20:
179 .LBB21:
181 005e 81E0 .LM12:
182 0060 00C0 ldi r24,lo8(-112)
183 out 35-32,r24
185 .LM13:
219:io/lm75.c **** N) | (1 << TWSTO);
220:io/lm75.c **** }
221:io/lm75.c ****
222:io/lm75.c **** void lm75_send_device_address(unsigned char addr){
223:io/lm75.c **** //send device address (including pge offset + write/read flag)
224:io/lm75.c **** TWDR = addr;
225:io/lm75.c **** TWCR = (1 << TWINT) | (1 << TWEN);
226:io/lm75.c **** while (!(TWCR & (1 << TWINT)));
227:io/lm75.c **** }
228:io/lm75.c ****
186 t 86-32,r24
187 .L18:
189 0064 83B9 .LM14:
229:io/lm75.c **** = (1 << TWINT) | (1 << TWEN);
190 __tmp_reg__,86-32
191 sbrs __tmp_reg__,7
192 0066 84E8 rjmp .L18
193 0068 86BF .LBE21:
194 .LBE20:
230:io/lm75.c **** + write/read flag)
195 bn 68,0,99,.LM15-.LFBB2
196 .LM15:
197 006a 06B6 in r24,33-32
198 006c 07FE andi r24,lo8(-8)
199 006e 00C0 cpi r24,lo8(24)
200 brne .L43
201 .L19:
203 .LM16:
204 0070 81B1 ldi r24,lo8(2)
205 0072 887F rjmp .L40
206 0074 8831 .L7:
207 0076 01F4 .LBB22:
208 .LBB23:
210 .LM17:
211 0078 82E0 out 35-32,__zero_reg__
213 .LM18:
214 ldi r24,lo8(-124)
215 out 86-32,r24
231:io/lm75.c **** addr){
232:io/lm75.c **** //send device address (including pge offset + write/read flag)
233:io/lm75.c **** TWDR = addr;
234:io/lm75.c **** TWCR = (1 << TWINT) | (1 << TWEN);
216 6,.LM19-.LFBB2
217 .LM19:
218 007c 13B8 in __tmp_reg__,86-32
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -