C51单片机-示例代码成品(2)——多外设PC串口查询系统

一、功能说明

在室温、板载电压、ROM密钥等目标中选定PC串口查询系统的功能

二、main.c文件

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
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
#include <REGX52.H>
#include "DS18B20.h"
#include "XPT2046.h"
#include "AT24C02.h"
code unsigned char *whatADJ = "Now the ADJ is ";
code unsigned char *whatNTC = "Now the NTC is ";
code unsigned char *whatGR = "Now the GR is ";
unsigned char strIndex;
unsigned char getStr[20];
unsigned char Timer_count;
unsigned int AD_Num;
unsigned char continue_show_type;
unsigned char ADisMore;
unsigned int ADValue;
float tem;
unsigned char *tempStr;

// 进行字符串的相等判断
unsigned char StrEqual(unsigned char *str) {
unsigned char i = 0;
while(*str!='\0'){
if (*str != getStr[i]) {
return 0;
}
str++;
i++;
}
return 1;
}

void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}

// 发送一位字符
void UART_SendByte(unsigned char byte) {
SBUF = byte;
while(TI == 0);
TI = 0;
}

// 发送一个数字
void UART_SendNum(unsigned int num) {
unsigned char nums[5];
unsigned char i = 0;
while (num != 0) {
nums[i] = num % 10;
num /= 10;
i++;
}
while (i--) {
UART_SendByte(nums[i] + '0');
}
}


// 发送一行字符串
void UART_SendStringLine(unsigned char *str) {
unsigned char i = 0;
while(*str!='\0'){
SBUF = *str;
while(TI == 0);
TI = 0;
str++;
i++;

}
i = 36 * (i / 36 + 1) - i;
while (i != 0) {
UART_SendByte(' ');
i--;
}
}

// 发送一行字符串以及数字
void UART_SendStringAndNumLine(unsigned char *str, unsigned int num) {
unsigned char i = 0;
unsigned char j = 0;
while(*str!='\0'){
SBUF = *str;
while(TI == 0);
TI = 0;
str++;
i++;
}
UART_SendNum(num);
while (num != 0) {
num /= 10;
j++;
}
i = 34 - i - j;;
while (i != 0) {
UART_SendByte(' ');
i--;
}


// if (num > 999) {
// UART_SendByte(48 + num / 1000);
// num = num % 1000;
// i++;
// if(num < 10) {
// UART_SendByte(48 + 0);
// UART_SendByte(48 + 0);
// i = i + 2;
// }
// else if (num < 100) {
// UART_SendByte(48 + 0);
// i++;
// }
// }
// if (num > 99) {
// UART_SendByte(48 + num / 100);
// num = num % 100;
// if (num < 10) {
// UART_SendByte(48 + 0);
// i++;
// }
// i++;
// }
// if (num > 9) {
// UART_SendByte(48 + num / 10);
// num = num % 10;
// i++;
// }
//
// UART_SendByte(48 + num);
// i++;
// i = 36 * (i / 36 + 1) - i;
// while (i != 0) {
// UART_SendByte(' ');
// i--;
// }
}

unsigned int get_AD_Num(unsigned char showAD)
{
unsigned int type;
if (showAD % 10 == 1) type = XPT2046_XP;
else if (showAD % 10 == 2) type = XPT2046_YP;
else if (showAD % 10 == 3) type = XPT2046_VBAT;
if (showAD / 10 == 1) type = type & 0xF7;
return XPT2046_ReadAD(type);
}

void show_line(unsigned char printLines, unsigned char type){
unsigned char i = 8 - printLines - 1;
unsigned char nulls = 28;
if (type == 1) {
AD_Num = get_AD_Num(1 + 10*ADisMore);

AT24C02_WriteByte(0,AD_Num%256);
Delay(5);
AT24C02_WriteByte(1,AD_Num/256);
Delay(5);

UART_SendStringAndNumLine(whatADJ, AD_Num);
AD_Num = get_AD_Num(2 + 10*ADisMore);

AT24C02_WriteByte(2,AD_Num%256);
Delay(5);
AT24C02_WriteByte(3,AD_Num/256);
Delay(5);

UART_SendStringAndNumLine(whatNTC, AD_Num);
AD_Num = get_AD_Num(3 + 10*ADisMore);

AT24C02_WriteByte(4,AD_Num%256);
Delay(5);
AT24C02_WriteByte(5,AD_Num/256);
Delay(5);

UART_SendStringAndNumLine(whatGR, AD_Num);
i--;
if (continue_show_type == 1) {
while (i--) {
UART_SendStringLine(" ");
}
}
} else if (type == 2) {
DS18B20_ConvertT();
tem = DS18B20_ReadT();
if (tem <0) {
UART_SendByte('-');
tem = -tem;
}
else
{
UART_SendByte('+');
}

UART_SendNum(tem);


UART_SendByte('.');

UART_SendNum((unsigned long)(tem*10000)%10000);



while (nulls--) UART_SendByte(' ');
UART_SendStringLine(" ");
}

}

void ReadRom(void)
{
unsigned int Num;
Num=AT24C02_ReadByte(0);
Num|=AT24C02_ReadByte(1)<<8;
UART_SendStringAndNumLine("ADJ:", Num);
Num=AT24C02_ReadByte(2);
Num|=AT24C02_ReadByte(3)<<8;
UART_SendStringAndNumLine("NTC:", Num);
Num=AT24C02_ReadByte(4);
Num|=AT24C02_ReadByte(5)<<8;
UART_SendStringAndNumLine("GR:", Num);
UART_SendStringLine(" ");
}


void Timer0Init(void)
{
TMOD &= 0xF0;
TMOD |= 0x01;
TL0 = 0x18;
TH0 = 0xFC;
TF0 = 0;
TR0 = 1;
ET0=1;
EA=1;
PT0=0;
}

void Timer0_Routine() interrupt 1
{
if(Timer_count == 10) // 相隔一定时间进行一次输出
{
if (continue_show_type == 1)
{
show_line(3,continue_show_type);
}
else if (continue_show_type == 2)
{
show_line(1,continue_show_type);
}
Timer_count = 0;
}
else Timer_count++;

}




void UART_Init(void) //4800bps@11.0592MHz
{
PCON |= 0x80; //
SCON = 0x50; //
TMOD &= 0x0F; //
TMOD |= 0x20; //
TL1 = 0xF4; //
TH1 = 0xF4; //
ET1 = 0; //
TR1 = 1; //
EA = 1;
ES = 1;
}





void UART_Get() {
char num;

EA = 0;
if (continue_show_type == 0) // 如果此时不是处于持续输出的状态
{
if (StrEqual("show AD;") == 1)
{
show_line(3,1);
}
else if (StrEqual("continue show AD;") == 1)
{
Timer0Init();
continue_show_type = 1;
}
else if (StrEqual("show AD more;") == 1)
{
ADisMore = 1;
show_line(3,1);
ADisMore = 0;
}

else if (StrEqual("Temper;") == 1)
{
show_line(1,2);
}
else if (StrEqual("continue show Temper;") == 1)
{
Timer0Init();
continue_show_type = 2;
}
else if (StrEqual("read rom;") == 1) {
ReadRom();
}

else
{
UART_SendStringLine("INPUT ERROR!");
}

}
else if (StrEqual("end;") == 1)
{
TR0 = 0;
continue_show_type = 0;
UART_SendStringLine("END SUCCESSFULLY");
}
else
{
UART_SendStringLine("INPUT ERROR!");
}
strIndex = 0;
EA = 1;
}


void UART_Routine() interrupt 4
{
if (RI == 1) { //
if (SBUF == ';') {
getStr[strIndex] = SBUF;
RI = 0;
UART_Get();
return;
}
getStr[strIndex] = SBUF;
RI = 0; //
strIndex++;
if (strIndex == 20) {
UART_SendStringLine("INPUT TO MANY!");
strIndex = 0;
}
}

}



void main(void)
{
UART_Init();
DS18B20_ConvertT();
Delay(1000);
while(1)
{

}
}

三、温度传感器DS18B20

3.1 DS18B20.c

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
#include <REGX52.H>
#include "OneWire.h"

//DS18B20指令
#define DS18B20_SKIP_ROM 0xCC
#define DS18B20_CONVERT_T 0x44
#define DS18B20_READ_SCRATCHPAD 0xBE

/**
* @brief DS18B20开始温度变换
* @param 无
* @retval 无
*/
void DS18B20_ConvertT(void)
{
OneWire_Init();
OneWire_SendByte(DS18B20_SKIP_ROM);
OneWire_SendByte(DS18B20_CONVERT_T);
}

/**
* @brief DS18B20读取温度
* @param 无
* @retval 温度数值
*/
float DS18B20_ReadT(void)
{
unsigned char TLSB,TMSB;
int Temp;
float T;
OneWire_Init();
OneWire_SendByte(DS18B20_SKIP_ROM);
OneWire_SendByte(DS18B20_READ_SCRATCHPAD);
TLSB=OneWire_ReceiveByte();
TMSB=OneWire_ReceiveByte();
Temp=(TMSB<<8)|TLSB;
T=Temp/16.0;
return T;
}

3.2 DS18B20.h

1
2
3
4
5
6
7
8
#ifndef __DS18B20_H__
#define __DS18B20_H__

void DS18B20_ConvertT(void);
float DS18B20_ReadT(void);

#endif

3.3 OneWire.c

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
#include <REGX52.H>

//引脚定义
sbit OneWire_DQ=P3^7;

/**
* @brief 单总线初始化
* @param 无
* @retval 从机响应位,0为响应,1为未响应
*/
unsigned char OneWire_Init(void)
{
unsigned char i;
unsigned char AckBit;
OneWire_DQ=1;
OneWire_DQ=0;
i = 247;while (--i); //Delay 500us
OneWire_DQ=1;
i = 32;while (--i); //Delay 70us
AckBit=OneWire_DQ;
i = 247;while (--i); //Delay 500us
return AckBit;
}

/**
* @brief 单总线发送一位
* @param Bit 要发送的位
* @retval 无
*/
void OneWire_SendBit(unsigned char Bit)
{
unsigned char i;
OneWire_DQ=0;
i = 4;while (--i); //Delay 10us
OneWire_DQ=Bit;
i = 24;while (--i); //Delay 50us
OneWire_DQ=1;
}

/**
* @brief 单总线接收一位
* @param 无
* @retval 读取的位
*/
unsigned char OneWire_ReceiveBit(void)
{
unsigned char i;
unsigned char Bit;
OneWire_DQ=0;
i = 2;while (--i); //Delay 5us
OneWire_DQ=1;
i = 2;while (--i); //Delay 5us
Bit=OneWire_DQ;
i = 24;while (--i); //Delay 50us
return Bit;
}

/**
* @brief 单总线发送一个字节
* @param Byte 要发送的字节
* @retval 无
*/
void OneWire_SendByte(unsigned char Byte)
{
unsigned char i;
for(i=0;i<8;i++)
{
OneWire_SendBit(Byte&(0x01<<i));
}
}

/**
* @brief 单总线接收一个字节
* @param 无
* @retval 接收的一个字节
*/
unsigned char OneWire_ReceiveByte(void)
{
unsigned char i;
unsigned char Byte=0x00;
for(i=0;i<8;i++)
{
if(OneWire_ReceiveBit()){Byte|=(0x01<<i);}
}
return Byte;
}

3.4 OneWire.h

1
2
3
4
5
6
7
8
9
10
11
#ifndef __ONEWIRE_H__
#define __ONEWIRE_H__

unsigned char OneWire_Init(void);
void OneWire_SendBit(unsigned char Bit);
unsigned char OneWire_ReceiveBit(void);
void OneWire_SendByte(unsigned char Byte);
unsigned char OneWire_ReceiveByte(void);

#endif

四、模数转换器XPT2046

4.1 XPT2046.c

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
#include <REGX52.H>
#include <INTRINS.H>

//引脚定义
sbit XPT2046_DIN=P3^4;
sbit XPT2046_CS=P3^5;
sbit XPT2046_DCLK=P3^6;
sbit XPT2046_DOUT=P3^7;

/**
* @brief ZPT2046读取AD值
* @param Command 命令字,范围:头文件内定义的宏,结尾的数字表示转换的位数
* @retval AD转换后的数字量,范围:8位为0~255,12位为0~4095
*/
unsigned int XPT2046_ReadAD(unsigned char Command)
{
unsigned char i;
unsigned int Data=0;
XPT2046_DCLK=0; // 初始化clk置零
XPT2046_CS=0; // 启用XPT2046
for(i=0;i<8;i++)
{ // 依次发出command中八位信息
XPT2046_DIN=Command&(0x80>>i);
XPT2046_DCLK=1;
XPT2046_DCLK=0;
}
for(i=0;i<16;i++)
{
XPT2046_DCLK=1;
XPT2046_DCLK=0;
if(XPT2046_DOUT){Data|=(0x8000>>i);} // 如果得到的数据为1则对应data位置加1
}
XPT2046_CS=1; // 位选信息CS置高,结束程序
if(Command &0x08)
return Data>>8;
else
return Data>>4;
}

4.2 XPT2046.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef __XPT2046_H__
#define __XPT2046_H__

#define XPT2046_VBAT 0xAC // 1010 1100
#define XPT2046_AUX 0xEC
#define XPT2046_XP 0x9C
#define XPT2046_YP 0xDC

#define XPT2046_VBAT_12 0xA4 // 1010 0100 1111 0111
#define XPT2046_AUX_12 0xE4
#define XPT2046_XP_12 0x94
#define XPT2046_YP_12 0xD4

unsigned int XPT2046_ReadAD(unsigned char Command);

#endif

五、ROM存储器AT24C02

5.1 AT24C02.c

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
#include <REGX52.H>
#include "I2C.h"

#define AT24C02_ADDRESS 0xA0

/**
* @brief AT24C02写入一个字节
* @param WordAddress 要写入字节的地址
* @param Data 要写入的数据
* @retval 无
*/
void AT24C02_WriteByte(unsigned char WordAddress,Data)
{
I2C_Start();
I2C_SendByte(AT24C02_ADDRESS);
I2C_ReceiveAck();
I2C_SendByte(WordAddress);
I2C_ReceiveAck();
I2C_SendByte(Data);
I2C_ReceiveAck();
I2C_Stop();
}

/**
* @brief AT24C02读取一个字节
* @param WordAddress 要读出字节的地址
* @retval 读出的数据
*/
unsigned char AT24C02_ReadByte(unsigned char WordAddress)
{
unsigned char Data;
I2C_Start();
I2C_SendByte(AT24C02_ADDRESS);
I2C_ReceiveAck();
I2C_SendByte(WordAddress);
I2C_ReceiveAck();
I2C_Start();
I2C_SendByte(AT24C02_ADDRESS|0x01);
I2C_ReceiveAck();
Data=I2C_ReceiveByte();
I2C_SendAck(1);
I2C_Stop();
return Data;
}

5.2 AT24C02.h

1
2
3
4
5
6
7
8
9
#ifndef __AT24C02_H__
#define __AT24C02_H__

void AT24C02_WriteByte(unsigned char WordAddress,Data);
unsigned char AT24C02_ReadByte(unsigned char WordAddress);


#endif

5.3 I2C.c

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
#include <REGX52.H>

sbit I2C_SCL=P2^1;
sbit I2C_SDA=P2^0;

/**
* @brief I2C开始
* @param 无
* @retval 无
*/
void I2C_Start(void)
{
I2C_SDA=1;
I2C_SCL=1;
I2C_SDA=0;
I2C_SCL=0;
}

/**
* @brief I2C停止
* @param 无
* @retval 无
*/
void I2C_Stop(void)
{
I2C_SDA=0;
I2C_SCL=1;
I2C_SDA=1;
}

/**
* @brief I2C发送一个字节
* @param Byte 要发送的字节
* @retval 无
*/
void I2C_SendByte(unsigned char Byte)
{
unsigned char i;
for(i=0;i<8;i++)
{
I2C_SDA=Byte&(0x80>>i);
I2C_SCL=1;
I2C_SCL=0;
}
}

/**
* @brief I2C接收一个字节
* @param 无
* @retval 接收到的一个字节数据
*/
unsigned char I2C_ReceiveByte(void)
{
unsigned char i,Byte=0x00;
I2C_SDA=1;
for(i=0;i<8;i++)
{
I2C_SCL=1;
if(I2C_SDA){Byte|=(0x80>>i);}
I2C_SCL=0;
}
return Byte;
}

/**
* @brief I2C发送应答
* @param AckBit 应答位,0为应答,1为非应答
* @retval 无
*/
void I2C_SendAck(unsigned char AckBit)
{
I2C_SDA=AckBit;
I2C_SCL=1;
I2C_SCL=0;
}

/**
* @brief I2C接收应答位
* @param 无
* @retval 接收到的应答位,0为应答,1为非应答
*/
unsigned char I2C_ReceiveAck(void)
{
unsigned char AckBit;
I2C_SDA=1;
I2C_SCL=1;
AckBit=I2C_SDA;
I2C_SCL=0;
return AckBit;
}

5.4 I2C.h

1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef __I2C_H__
#define __I2C_H__

void I2C_Start(void);
void I2C_Stop(void);
void I2C_SendByte(unsigned char Byte);
unsigned char I2C_ReceiveByte(void);
void I2C_SendAck(unsigned char AckBit);
unsigned char I2C_ReceiveAck(void);


#endif