📄 ds1820.lst
字号:
1: //文件名:DS18B20.c
2: #define uchar unsigned char
3: #define uint unsigned int
4:
5: #define XF_MCU 1 //定义用哪一种单片机,1时,用于PIC; 0时,用于MSP430;
6:
7: #if XF_MCU==0
8: #include <msp430x14x.h>
9: #include "DS1820.h"
10: #else
11: #include <pic.h>
12: #include "DS1820.h"
13: uchar pa_out;
14: uchar pb_out;
15: uchar pc_out;
16: uchar pd_out;
17: uchar pe_out;
18: #endif
19:
20: const unsigned char digit[10] = {'0','1','2','3','4','5','6','7',
21: '8','9'};
22:
23: unsigned char temp_display [9] = {'x','0','0','0','.','0','0','0','\0'};
24:
25:
26: //定义
27: unsigned char Error = 0;
28: float Temper=0.0; //真正有效温度值
29: int temperature=0; //读取两字节温度数据
30: unsigned char symbol = 1 ; //温度正负符号
31:
32: //----------------------------------
33: //功能:us 级别延时
34: // n=10,则延时10*5+6=56uS
35: //----------------------------------
36: void DelayNus(unsigned int n)
37: {
38: while(n--){};
39: }
40: //-----------------------------------
41:
42:
43: //功能:写18B20
44: //-----------------------------------
45: void Write_18B20(unsigned char n)
46: {
47: unsigned char i;
48: for(i=0;i<8;i++)
49: {
50: DQ0;
51: _NOP();_NOP(); //延时5us
52: _NOP();_NOP();_NOP();
53: if((n&0X01)==0X01) //DQ=1
54: DQ1;
55: else
56: DQ0; //DQ=0
57: n=n>>1; //下一位
58: DelayNus(6); //延时50us 以上
59: DQ1;
60: }
61: }
62: //------------------------------------
63:
64:
65: //功能:读取18B20
66: //------------------------------------
67: unsigned char Read_18B20(void)
68: {
69: unsigned char i;
70: unsigned char temp;
71: for(i=0;i<8;i++)
72: {
73: temp=temp>>1; //移向下一位
74: DQ0;
75: _NOP(); //延时1us
76: DQ1;
77: _NOP();_NOP(); //延时5us
78: _NOP();
79:
80: DQIO_IN; //DQ口设为输入
81: if((DS_IN&DS_IT)==0) //DQ是否等于0
82: {
83: temp=temp&0x7F; //读入DQ为0
84: }
85: else
86: {
87: temp=temp|0x80; //读入DQ为1
88: }
89:
90: DelayNus(5); //延时40us
91: DQIO_OUT; //DQ口设为输出
92: DQ1; //DQ输出1
93: }
94: return temp; //返回一个数据
95: }
96: //-----------------------------------
97:
98:
99: //复位说明:复位要求主CPU将数据线下拉500us,然后释放,
100: //当DS18B20收到信号后等待16~60us左右,后发出60~240微秒的存在低脉冲,
101: //主CPU收到此信号表示复位成功。
102: //初始化DS18B20
103: void Init (void)
104: {
105: DQ0;
106: DelayNus(50); //延时500us
107: DQ1;
108: DelayNus(12); //延时16~60us
109:
110: DQIO_IN; //设DQ为输入
111: if((DS_IN&DS_IT)==DS_IT) //1000 0000b=1f,DQ是否为1
112: {
113: Error =1; //失败1
114: DQIO_OUT; //设DQ为输输出
115: }
116: else
117: {
118: Error = 0; //初始化成功
119: DQIO_OUT; //设DQ为输输出
120: DQ1;
121: }
122: }
123: //----------------------------------
124:
125: //指令描述:跳过ROM命令,指定代码为CCH,忽略64位ROM地址,直接向DS1820发温度变换
126: //命令,适用于单片机工作.
127: void Skip(void)
128: {
129: Write_18B20(0xcc);
130: }
131: //----------------------------------
132:
133: //指令描述:温度转换命令,指定代码为44H.启动DS1820进行温度转换,12位转换时最长
134: //为750ms(9位为93.75ms).结果存入内部9字节RAM中.
135: void Convert (void)
136: {
137: Write_18B20(0x44);
138: }
139: //----------------------------------
140:
141: //指令描述:读暂存器,指定代码为BEH.读内部RAM中9字节的内容.
142: void ReadDo (void)
143: {
144: Write_18B20(0xbe);
145: }
146: //----------------------------------
147:
148: //读取温度值
149: void ReadTemp (void)
150: {
151: char temp_low, temp_high; //温度值
152: temp_low = Read_18B20(); //读低位
153: temp_high = Read_18B20(); //读高位
154:
155: if((temp_high|positive)==positive)
156: symbol=1; //测到的温度为正
157: else
158: symbol=0; //测到的温度为负
159:
160: temperature=(temp_high&0x0f);//屏蔽高4位
161: temperature<<=8; //将temp_high部分数据移到temperature高8位
162: temperature|=temp_low; //将高低两字节内部合并成一个16位数据
163:
164: if(symbol==0) //是否为负温度
165: { temperature = (~temperature)+1; //将其取反后加1
166: }
167: Temper=temperature*0.0625; //计算真实温度值
168: }
169: //----------------------------------
170:
171: //MCU对DS18B20进行温度转换时,其操作必须满足以下过程:
172: // 1- 每一次读写之前都要对DS18B20进行复位.
173: // 2- 完成复位后发送一条ROM命令到DS18B20.
174: // 3- 最后发送一条RAM命令到DS18B20.
175: // 以上系列动作是根据DS18B20的通讯协议所得.
176: //读取温度
177: void GetTemp(void)
178: {
179: Init(); //DS1820初始化
180: Skip(); //跳过64位ROM(ROM命令)
181: Convert(); //转换(RAM命令)
182: DelayNus(60000); //60000x5us=0.3s
183: DelayNus(60000); //0.3s
184: DelayNus(60000); //0.3s
185: Init(); //DS1820初始化
186: Skip(); //跳过64位ROM
187: ReadDo(); //读暂存器
188: ReadTemp(); //读取温度值
189: }
190: //END--------------------------------------------------------------
191:
192: //另外,由于MSP430F14与44的DCO时钟有所不同,各位如要引用DS18B20程序时请加于注意操作时序。
193: //引用时可能出现过复位不成功或读到全为FF...
194: //这些大部分都是由于程序上的时序不能满足DS18B20所至。
195: //以下关于14与4系列的DCO默认时钟:
196: //4系列默认时钟 ACLK = LFXT1 = 32768Hz, MCLK = SMCLK = DCO = 32xACLK = 1048576Hz时钟周期为0.95us
197: //14系列默认时钟 ACLK= n/a, MCLK= SMCLK= default DCO ~800k 时钟周期为1.25us
198:
199:
200:
201:
202: //MC430F14 DS18B20实验主程序
203: void main(void)
204: {
205: #if XF_MCU==0
206: WDTCTL=WDTPW+WDTHOLD; //停止WDT
207: mcuinit(); //MSP430F14初始化
208: #else
209: LCM141_DIR_OUT;
210: #endif
211: while(1)
212: {
213: GetTemp(); //读取温度
214:
215: display_number(Temper); //数据变换
216: ;
217: }
218: }
219:
220:
221: //将温度值转换成可显示十进制值
222: //取数范围整数3位,小数点后3位.
223: void display_number(float f_data)
224: { unsigned long value;
225: float n;
226: n=f_data *1000;
227: value = (unsigned long int)n;
228:
229: temp_display[1] = digit[value/100000]; //100位
230: value = value%100000;
231:
232: temp_display[2] = digit[value/10000]; //10位
233: value = value%10000;
234:
235: temp_display[3] = digit[value/1000]; //1位
236: value = value%1000;
237:
238: temp_display[5] = digit[value/100]; //0.1位
239: value = value%100;
240:
241: temp_display[6] = digit[value/10]; //0.01位
242: value = value%10;
243:
244: temp_display[7] = digit[value/1]; //0.001位
245: }
246: //--------------------------------------------------------------------
247:
248:
249: //---------------------------------------------------------------------
250:
251: //MSP430F14初始化
252: void mcuinit(void)
253: {
254: DQIO_OUT; //设为输出
255: DQ1; //输出高电平;
256: }
257:
258: //---------------------------------------------------------------------
259:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -