📄 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 : {{removed according to contest rules}}
10:io/lm75.c **** | -> circuitcellar.com avr design contest 2006
11:io/lm75.c **** | -> Entry #AT2616
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 sts 113,__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 sts 112,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 0006 8093 7000 .LM4:
71:io/lm75.c **** 75_state = LM75_STATE_IDLE;
72:io/lm75.c ****
104 r24,lo8(64)
105 ldi r25,hi8(64)
106 000a 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 0010 90E0 .LM5:
111 0012 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 001a 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 001c FC01 brne .+2
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 .L8
131 cpi r24,lo8(4)
132 001e 8091 0000 brsh .L13
133 0022 8330 cpi r24,lo8(1)
134 0024 01F4 breq .L6
135 0026 00C0 cpi r24,lo8(2)
136 0028 8430 brsh .L7
137 002a 00F4 rjmp .L44
138 002c 8130 .L13:
139 002e 01F0 cpi r24,lo8(5)
140 0030 8230 brne .+2
141 0032 00F4 rjmp .L10
142 0034 00C0 cpi r24,lo8(5)
143 brsh .+2
144 0036 8530 rjmp .L9
145 0038 01F4 cpi r24,lo8(6)
146 003a 00C0 brne .+2
147 003c 8530 rjmp .L11
148 003e 00F4 cpi r24,lo8(8)
149 0040 00C0 brne .+2
150 0042 8630 rjmp .L12
151 0044 01F4 ldi r25,lo8(0)
152 0046 00C0 rjmp .L14
153 0048 8830 .L44:
154 004a 01F4 .LBB18:
155 004c 00C0 .LBB19:
157 0050 00C0 .LM8:
158 ldi r24,lo8(-92)
159 sts 116,r24
160 .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 **** }
161 M9:
162 lds r24,116
163 0052 84EA sbrs r24,7
164 0054 8093 7400 rjmp .L15
165 .LBE19:
218:io/lm75.c **** char addr){
166 8:
168 0058 8091 7400 .LM10:
169 005c 87FF lds r24,113
170 005e 00C0 andi r24,lo8(-8)
171 cpi r24,lo8(8)
172 breq .+2
173 rjmp .L43
174 .L16:
176 0064 887F .LM11:
177 0066 8830 ldi r24,lo8(1)
178 0068 01F0 rjmp .L40
179 006a 00C0 .L6:
180 .LBB20:
181 .LBB21:
183 006c 81E0 .LM12:
184 006e 00C0 ldi r24,lo8(-112)
185 sts 115,r24
187 .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 ****
188 s 116,r24
189 .L18:
191 0072 8093 7300 .LM14:
229:io/lm75.c **** = (1 << TWINT) | (1 << TWEN);
192 r24,116
193 sbrs r24,7
194 0076 84E8 rjmp .L18
195 0078 8093 7400 .LBE21:
196 .LBE20:
230:io/lm75.c **** + write/read flag)
197 bn 68,0,99,.LM15-.LFBB2
198 .LM15:
199 007c 8091 7400 lds r24,113
200 0080 87FF andi r24,lo8(-8)
201 0082 00C0 cpi r24,lo8(24)
202 breq .+2
203 rjmp .L43
204 .L19:
206 0084 8091 7100 .LM16:
207 0088 887F ldi r24,lo8(2)
208 008a 8831 rjmp .L40
209 008c 01F0 .L7:
210 008e 00C0 .LBB22:
211 .LBB23:
213 .LM17:
214 0090 82E0 sts 115,__zero_reg__
216 .LM18:
217 ldi r24,lo8(-124)
218 sts 116,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);
219 ,.LM19-.LFBB2
220 .LM19:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -