关于DS18B20电子温度器件可查看单片机练习 - DS18B20温度转换与显示 .
本文主要讲述如何使用LCD. 具体过程解释可查看代码注释.
程序代码:
1602LCD
1
//1602液晶显示程序, TX-1B实验板上的1602LCD的R/W读写端接地, 即始终只写, 不读数据
2
//使用1602LCD显示DS18B20转换的温度值
3
#include <reg52.H>
4
#include <intrins.H>
5
#include <math.H>
6
7
#define uchar unsigned char
8
#define uint unsigned int
9
sbit dula = P2^6;
10
sbit wela = P2^7;
11
12
sbit RS = P3^5; //数据/命令选择端(H/L)
13
sbit LCDEN = P3^4; //使能端
14
15
void delayUs()
16
{
17
_nop_();
18
}
19
20
void delayMs(uint a)
21
{
22
uint i, j;
23
for(i = a; i > 0; i--)
24
for(j = 100; j > 0; j--);
25
}
26
27
//第一行开始地址为0x80, 第二行开始地址为0xc0;
28
//写命令:RS=0, RW=0;
29
void writeComm(uchar comm)
30
{
31
RS = 0;
32
P0 = comm;
33
LCDEN = 1;
34
delayUs();
35
LCDEN = 0;
36
delayMs(1);
37
}
38
39
//写数据:RS=1, RW=0;
40
void writeData(uchar dat)
41
{
42
RS = 1;
43
P0 = dat;
44
LCDEN = 1;
45
delayUs();
46
LCDEN = 0;
47
delayMs(1);
48
}
49
50
//初始化
51
//显示模式, 固定指令为00111000=0x38, 16*2显示, 5*7点阵,8位数据接口
52
//显示开/关及光标设置
53
//指令1: 00001DCB : D:开显示/关显示(H/L); C:显示光标/不显示(H/L), B:光标闪烁/不闪烁(H/L)
54
//指令2: 000001NS :
55
//N=1, 当读/写一个字符后地址指针加1, 且光标也加1; N=0则相反
56
//S=1, 当写一个字符, 整屏显示左移(N=1)或右移(N=0), 但光标不移动; S=0, 整屏不移动
57
void init()
58
{
59
//先关闭数码管, 使两个锁存器锁存, 因开了数码管, USB电压驱动不够, 将无法使LCD正常工作
60
dula = wela = 0;
61
writeComm(0x38); //显示模式
62
writeComm(0x0c); //开显示, 关光标
63
writeComm(0x06); //写字符后地址加1, 光标加1
64
writeComm(0x01); //清屏
65
}
66
67
void writeString(uchar * str, uchar length)
68
{
69
uchar i;
70
for(i = 0; i < length; i++)
71
{
72
writeData(str[i]);
73
}
74
}
75
76
/*****************************DS18B20*******************************/
77
sbit ds = P2^2;
78
//初始化DS18B20
79
//让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动
80
void dsInit()
81
{
82
//对于11.0592MHz时钟, unsigned int型的i, 作一个i++操作的时间大于为8us
83
unsigned int i;
84
ds = 0;
85
i = 100; //拉低约800us, 符合协议要求的480us以上
86
while(i>0) i--;
87
ds = 1; //产生一个上升沿, 进入等待应答状态
88
i = 4;
89
while(i>0) i--;
90
}
91
92
void dsWait()
93
{
94
unsigned int i;
95
while(ds);
96
while(~ds); //检测到应答脉冲
97
i = 4;
98
while(i > 0) i--;
99
}
100
101
//向DS18B20读取一位数据
102
//读一位, 让DS18B20一小周期低电平, 然后两小周期高电平,
103
//之后DS18B20则会输出持续一段时间的一位数据
104
bit readBit()
105
{
106
unsigned int i;
107
bit b;
108
ds = 0;
109
i++; //延时约8us, 符合协议要求至少保持1us
110
ds = 1;
111
i++; i++; //延时约16us, 符合协议要求的至少延时15us以上
112
b = ds;
113
i = 8;
114
while(i>0) i--; //延时约64us, 符合读时隙不低于60us要求
115
return b;
116
}
117
118
//读取一字节数据, 通过调用readBit()来实现
119
unsigned char readByte()
120
{
121
unsigned int i;
122
unsigned char j, dat;
123
dat = 0;
124
for(i=0; i<8; i++)
125
{
126
j = readBit();
127
//最先读出的是最低位数据
128
dat = (j << 7) | (dat >> 1);
129
}
130
return dat;
131
}
132
133
//向DS18B20写入一字节数据
134
void writeByte(unsigned char dat)
135
{
136
unsigned int i;
137
unsigned char j;
138
bit b;
139
for(j = 0; j < 8; j++)
140
{
141
b = dat & 0x01;
142
dat >>= 1;
143
//写"1", 将DQ拉低15us后, 在15us~60us内将DQ拉高, 即完成写1
144
if(b)
145
{
146
ds = 0;
147
i++; i++; //拉低约16us, 符号要求15~60us内
148
ds = 1;
149
i = 8; while(i>0) i--; //延时约64us, 符合写时隙不低于60us要求
150
}
151
else //写"0", 将DQ拉低60us~120us
152
{
153
ds = 0;
154
i = 8; while(i>0) i--; //拉低约64us, 符号要求
155
ds = 1;
156
i++; i++; //整个写0时隙过程已经超过60us, 这里就不用像写1那样, 再延时64us了
157
}
158
}
159
}
160
161
//向DS18B20发送温度转换命令
162
void sendChangeCmd()
163
{
164
dsInit(); //初始化DS18B20, 无论什么命令, 首先都要发起初始化
165
dsWait(); //等待DS18B20应答
166
delayMs(1); //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号
167
writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
168
writeByte(0x44); //写入温度转换命令字 Convert T
169
}
170
171
//向DS18B20发送读取数据命令
172
void sendReadCmd()
173
{
174
dsInit();
175
dsWait();
176
delayMs(1);
177
writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
178
writeByte(0xbe); //写入读取数据令字 Read Scratchpad
179
}
180
181
//获取当前温度值
182
int getTmpValue()
183
{
184
unsigned int tmpvalue;
185
int value; //存放温度数值
186
float t;
187
unsigned char low, high;
188
sendReadCmd();
189
//连续读取两个字节数据
190
low = readByte();
191
high = readByte();
192
//将高低两个字节合成一个整形变量
193
//计算机中对于负数是利用补码来表示的
194
//若是负值, 读取出来的数值是用补码表示的, 可直接赋值给int型的value
195
tmpvalue = high;
196
tmpvalue <<= 8;
197
tmpvalue |= low;
198
value = tmpvalue;
199
200
//使用DS18B20的默认分辨率12位, 精确度为0.0625度, 即读回数据的最低位代表0.0625度
201
t = value * 0.0625;
202
//将它放大100倍, 使显示时可显示小数点后两位, 并对小数点后第三进行4舍5入
203
//如t=11.0625, 进行计数后, 得到value = 1106, 即11.06 度
204
//如t=-11.0625, 进行计数后, 得到value = -1106, 即-11.06 度
205
value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5
206
return value;
207
}
208
209
void display(int v)
210
{
211
unsigned char count;
212
unsigned char datas[] = {0, 0, 0, 0, 0};
213
unsigned int tmp = abs(v);
214
datas[0] = tmp / 10000;
215
datas[1] = tmp % 10000 / 1000;
216
datas[2] = tmp % 1000 / 100;
217
datas[3] = tmp % 100 / 10;
218
datas[4] = tmp % 10;
219
writeComm(0xc0+3);
220
if(v < 0)
221
{
222
writeString("- ", 2);
223
}
224
else
225
{
226
writeString("+ ", 2);
227
}
228
if(datas[0] != 0)
229
{
230
writeData(\'0\'+datas[0]);
231
}
232
for(count = 1; count != 5; count++)
233
{
234
writeData(\'0\'+datas[count]);
235
if(count == 2)
236
{
237
writeData(\'.\');
238
}
239
}
240
}
241
/*****************************DS18B20*******************************/
242
243
void main()
244
{
245
uchar table[] = "Now Temperature:";
246
sendChangeCmd();
247
init();
248
writeComm(0x80);
249
writeString(table, 16);
250
while(1)
251
{
252
delayMs(1000); //温度转换时间需要750ms以上
253
writeComm(0xc0);
254
display(getTmpValue());
255
sendChangeCmd();
256
}
257
}
效果图1:

效果图2:
本文主要讲述如何使用LCD. 具体过程解释可查看代码注释.
程序代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

效果图1:

效果图2:
