📄 wend.lst
字号:
C51 COMPILER V8.02 WEND 05/10/2008 20:26:25 PAGE 1
C51 COMPILER V8.02, COMPILATION OF MODULE WEND
OBJECT MODULE PLACED IN wend.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE wend.c BROWSE DEBUG OBJECTEXTEND
line level source
1 #include<reg52.H> //使用1602LCD显示DS18B20转换的温度值,12MHz,
2 #include<intrins.H>
3 #include<math.H>
4
5 #define uchar unsigned char //定义无符号字符为 uchar,方便书写
6 #define uint unsigned int
7
8 sbit RS=P3^3; // 数据/命令选择端(H/L)
9 sbit LCDEN=P3^5;//使能端,RW读写端接地
10
11
12
13 void delayUs()
14 {
15 1 _nop_();
16 1 }
17 //写命令:RS=0, RW=0;
18 //第一行开始地址为0x80, 第二行开始地址为0xc0;
19 void delayMs(uint a)
20 {
21 1 uint i,j;
22 1 for(i=a;i>0;i--)
23 1 for(j=100;j>0;j--);
24 1 }
25
26
27 void writeComm(uchar comm)
28 {
29 1 RS=0;
30 1 P1=comm;
31 1 LCDEN=1;
32 1 delayUs();
33 1 LCDEN=0;
34 1 delayMs(1);
35 1 }
36 // 写数据:RS=1, RW=0;
37 void writeData(uchar dat)
38 {
39 1 RS=1;
40 1 P1=dat;
41 1 LCDEN=1;
42 1 delayUs();
43 1 LCDEN=0;
44 1 delayMs(1);
45 1 }
46 //初始化
47 void init()
48 {
49 1
50 1 writeComm(0x38); //显示模式,固定指令为00111000=0x38, 16*2显示, 5*7点阵,8位数据接口
51 1 writeComm(0x0c); //开显示, 关光标,指令1: 00001DCB : D:开显示/关显示(H/L);
52 1 //C:显示光标/不显示(H/L), B:光标闪烁/不闪烁(H/L)
53 1 writeComm(0x06); //写字符后地址加1, 光标加1
54 1 writeComm(0x01); //清屏
55 1 }
C51 COMPILER V8.02 WEND 05/10/2008 20:26:25 PAGE 2
56
57 void writeString(uchar * str,uchar length)
58 {
59 1 uchar i;
60 1 for(i=0;i<length;i++)
61 1 {
62 2 writeData(str[i]);
63 2 }
64 1 }
65
66 sbit ds=P3^7;
67 //让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动
68 //初始化DS18B20
69 void dsInit()
70 {
71 1 unsigned int i; // 对于12MHz时钟, unsigned int型的i, 作一个i++操作的时间大约为8us
72 1 ds=0;
73 1 i=100; // 拉低约800us, 符合协议要求的480us以上
74 1 while(i>0)i--; //产生一个上升沿, 进入等待应答状态
75 1 ds=1;
76 1 i=4;
77 1 while(i>0)i--;
78 1 }
79
80 void dsWait()
81 {
82 1 unsigned int i;
83 1 while(ds);
84 1 while(~ds);//检测到应答脉冲
85 1 i=4;
86 1 while(i>0)i--;
87 1 }
88 // 向DS18B20读取一位数据
89 //读一位, 让DS18B20一小周期低电平, 然后两小周期高电平,
90 //之后DS18B20则会输出持续一段时间的一位数据
91 bit readBit()
92 {
93 1 unsigned int i;
94 1 bit b;
95 1 ds=0;
96 1 i++; //延时约8us, 符合协议要求至少保持1us
97 1 ds=1;
98 1 i++;i++;//延时约16us, 符合协议要求的至少延时15us以上
99 1 b=ds;
100 1 i=8;
101 1 while(i>0)i--; //延时约64us, 符合读时隙不低于60us要求
102 1 return b;
103 1 }
104 //读取一字节数据, 通过调用readBit()来实现
105 unsigned char readByte()
106 {
107 1 unsigned int i;
108 1 unsigned char j,dat;
109 1 dat=0;
110 1 for(i=0;i<8;i++)
111 1 {
112 2 j=readBit(); //最先读出的是最低位数据
113 2 dat=(j<<7)|(dat>>1);
114 2 }
115 1 return dat;
116 1 }
117 //向DS18B20写入一字节数据
C51 COMPILER V8.02 WEND 05/10/2008 20:26:25 PAGE 3
118 void writeByte(unsigned char dat)
119 {
120 1 unsigned int i;
121 1 unsigned char j;
122 1 bit b;
123 1 for(j=0;j<8;j++)
124 1 {
125 2 b=dat&0x01;
126 2 dat>>=1; //写"1", 将DQ拉低15us后, 在15us~60us内将DQ拉高, 即完成写1
127 2 if(b)
128 2 {
129 3 ds=0;
130 3 i++;i++; // 拉低约16us, 符号要求15~60us内
131 3 ds=1;
132 3 i=8;while(i>0)i--; //延时约64us, 符合写时隙不低于60us要求
133 3 }
134 2 else //写"0", 将DQ拉低60us~120us
135 2 {
136 3 ds=0;
137 3 i=8;while(i>0)i--; // 拉低约64us, 符号要求
138 3 ds=1;
139 3 i++;i++; //整个写0时隙过程已经超过60us, 这里就不用像写1那样, 再延时64us了
140 3 }
141 2 }
142 1 }
143 // 向DS18B20发送温度转换命令
144 void sendChangeCmd()
145 {
146 1 dsInit(); // 初始化DS18B20, 无论什么命令, 首先都要发起初始化
147 1 dsWait(); //等待DS18B20应答
148 1 delayMs(1); //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号
149 1 writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
150 1 writeByte(0x44); // 写入温度转换命令字 Convert T
151 1 }
152 // 向DS18B20发送读取数据命令
153 void sendReadCmd()
154 {
155 1 dsInit();
156 1 dsWait();
157 1 delayMs(1);
158 1 writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
159 1 writeByte(0xbe); //写入读取数据令字 Read Scratchpad
160 1 }
161 // 获取当前温度值
162 int getTmpValue()
163 {
164 1 unsigned int tmpvalue;
165 1 int value; // 存放温度数值
166 1 float t;
167 1 unsigned char low,high;
168 1 sendReadCmd(); //连续读取两个字节数据
169 1
170 1 low=readByte();
171 1 high=readByte();
172 1
173 1 tmpvalue=high; // 若是负值, 读取出来的数值是用补码表示的, 可直接赋值给int型的value
174 1 tmpvalue<<=8;
175 1 tmpvalue|=low; //计算机中对于负数是利用补码来表示的
176 1 value=tmpvalue; //将高低两个字节合成一个整形变量,将高低两个字节合成一个整形变量
177 1 t=value*0.0625; //使用DS18B20的默认分辨率12位, 精确度为0.0625度,
178 1 // 即读回数据的最低位代表0.0625度
179 1 value=t*100+(value>0?0.5:-0.5); //将它放大100倍, 使显示时可显示小数点后两位, 并对小数点后第三进行4舍5入
C51 COMPILER V8.02 WEND 05/10/2008 20:26:25 PAGE 4
180 1 // 如t=11.0625, 进行计数后, 得到value = 1106, 即11.06 度
181 1 //如t=-11.0625, 进行计数后, 得到value = -1106, 即-11.06 度大于0加0.5, 小于0减0.5
182 1 return value;
183 1 }
184
185 void display(int v)
186 {
187 1 unsigned char count;
188 1 unsigned char datas[]={0,1,2,3,4};
189 1 unsigned int tmp=abs(v);
190 1 datas[0]=tmp/10000; //最高位
191 1 datas[1]=tmp%10000/1000;
192 1 datas[2]=tmp%1000/100;
193 1 datas[3]=tmp%100/10;
194 1 datas[4]=tmp%10; //最低位
195 1
196 1
197 1 writeComm(0xc0+1); //0xc0=1100 0011 ->DDRAM地址设置,两行显示,第二行开始地址,距头1个距离
198 1 if(v<0) //温度的符号判断
199 1 {
200 2 writeString("- ",2); //注意符号后有一个空格
201 2 }
202 1 else
203 1 {
204 2 writeString("+ ",2);
205 2 }
206 1 if(datas[0]!=0)
207 1 {
208 2 writeData('0'+datas[0]); //输入字符0,1,2,3,4,5,6,7,8,9
209 2 }
210 1 for(count=1;count!=5;count++) // 依次显示由高到低位
211 1 {
212 2 writeData('0'+datas[count]);
213 2 if(count==2) //两高位之后小数点
214 2 {
215 3 writeData('.');
216 3 }
217 2 }
218 1
219 1 }
220
221 void main()
222 {
223 1 uchar table[]="Now Temperature:";
224 1 sendChangeCmd(); //先放入温度传感指令再液晶驱动,将顺序执行,没有检测到温度传感则无数据输出
225 1 init();
226 1 writeComm(0x80);
227 1 writeString(table,16);
228 1
229 1 while(1)
230 1 {
231 2 delayMs(1000); //温度转换时间需要750ms以上
232 2 writeComm(0xc0);
233 2 display(getTmpValue());
234 2 sendChangeCmd();
235 2 }
236 1 }
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 720 ----
CONSTANT SIZE = 28 ----
C51 COMPILER V8.02 WEND 05/10/2008 20:26:25 PAGE 5
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = ---- 35
IDATA SIZE = ---- ----
BIT SIZE = ---- 2
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -