51单片机+ADC0832一通道数据采集+Proteus仿真

51单片机+ADC0832一通道数据采集+Proteus仿真


在这里插入图片描述

主程序代码

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
#include <reg52.h>
#include <intrins.h>

/\*已知数据类型重新定义\*/
#define uchar unsigned char
#define uint unsigned int


/\*引脚定义\*/
//LCD1602
#define LCD1602\_DB P0 //LCD1602数据总线
sbit LCD1602_RS = P2^0; //RS端
sbit LCD1602_RW = P2^1; //RW端
sbit LCD1602_EN = P2^2; //EN端

//ADC0832
sbit cs = P1^0;//片选使能,低电平有效
sbit clk = P1^1;//芯片时钟输入
sbit dio = P1^2;//数据输入DI与输出DO

//延时2us
void Delay\_2us(void)
{
\_nop\_();
\_nop\_();
}
/\*=================================================
\*函数名称:Read\_Busy
\*函数功能:判断1602液晶忙,并等待
=================================================\*/
void Read\_Busy()
{
uchar busy;
LCD1602_DB = 0xff;//复位数据总线
LCD1602_RS = 0; //拉低RS
LCD1602_RW = 1; //拉高RW读
do
{
LCD1602_EN = 1;//使能EN
busy = LCD1602_DB;//读回数据
LCD1602_EN = 0; //拉低使能以便于下一次产生上升沿
}while(busy & 0x80); //判断状态字BIT7位是否为1,为1则表示忙,程序等待
}
/\*=================================================
\*函数名称:LCD1602\_Write\_Cmd
\*函数功能:写LCD1602命令
\*调用:Read\_Busy();
\*输入:cmd:要写的命令
=================================================\*/
void LCD1602\_Write\_Cmd(uchar cmd)
{
Read\_Busy(); //判断忙,忙则等待
LCD1602_RS = 0;
LCD1602_RW = 0; //拉低RS、RW操作时序情况1602课件下中文使用说明基本操作时序章节
LCD1602_DB = cmd;//写入命令
LCD1602_EN = 1; //拉高使能端 数据被传输到LCD1602内
LCD1602_EN = 0; //拉低使能以便于下一次产生上升沿
}
/\*=================================================
\*函数名称:LCD1602\_Write\_Dat
\*函数功能:写LCD1602数据
\*调用:Read\_Busy();
\*输入:dat:需要写入的数据
=================================================\*/
void LCD1602\_Write\_Dat(uchar dat)
{
Read\_Busy();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
LCD1602_EN = 1;
LCD1602_EN = 0;
}

/\*=================================================
\*函数名称:LCD1602\_Dis\_Str
\*函数功能:在指定位置显示字符串
\*调用:LCD1602\_Write\_Cmd(); LCD1602\_Write\_Dat();
\*输入:x:要显示的横坐标取值0-40,y:要显示的行坐标取值0-1(0为第一行,1为第二行)
\*str:需要显示的字符串
=================================================\*/
void LCD1602\_Dis\_Str(uchar x, uchar y, uchar \*str)
{
if(y) x |= 0x40;
x |= 0x80;
LCD1602\_Write\_Cmd(x);
while(\*str != '\0')
{
LCD1602\_Write\_Dat(\*str++);
}
}
/\*=================================================
\*函数名称:Init\_LCD1602
\*函数功能:1602初始化
\*调用: LCD1602\_Write\_Cmd();
=================================================\*/
void Init\_LCD1602()
{
LCD1602\_Write\_Cmd(0x38); // 设置16\*2显示,5\*7点阵,8位数据接口
LCD1602\_Write\_Cmd(0x0c); //开显示
LCD1602\_Write\_Cmd(0x06); //读写一字节后地址指针加1
LCD1602\_Write\_Cmd(0x01); //清除显示
}
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
函数简介:获取ADC0832数据
函数名称:ADC\_read\_data(bit channel)
参数说明:ch为入口参数,ch=0选择通道0,ch=1选择通道1
函数返回:返回读取到的二进制ADC数据,格式为unsigned char
当返回一直0时,转换数据有误
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
uchar ADC\_read\_data(bit channel)
{
uchar i,dat0=0,dat1=0;
//------第1次下降沿之前di置高,启动信号---------

cs=0; //片选信号置低,启动AD转换芯片
clk=0; //时钟置低平

dio=1; //开始信号为高电平
Delay\_2us();
clk=1; //产生一个正脉冲,在时钟上升沿,输入开始信号(DI=1)
Delay\_2us();
clk=0; //第1个时钟下降沿
dio=1;

Delay\_2us();
clk=1; // 第2个下降沿输入DI=1,表示双通道单极性输入
Delay\_2us();
//------在第2个下降沿,模拟信号输入模式选择(1:单模信号,0:双模差分信号)---------
clk=0;
dio=channel; // 第3个下降沿,设置DI,选择通道;
Delay\_2us();
clk=1;
Delay\_2us();

//------在第3个下降沿,模拟信号输入通道选择(1:通道CH1,0:通道CH0)------------

clk=0;
dio=1; //第四个下降沿之前,DI置高,准备接收数
Delay\_2us();
for(i=0;i<8;i++) //第4~11共8个下降沿读数据(MSB->LSB)
{
clk=1;
Delay\_2us();
clk=0;
Delay\_2us();
dat0=dat0<<1|dio;
}
for(i=0;i<8;i++) //第11~18共8个下降沿读数据(LSB->MSB)
{
dat1=dat1|((uchar)(dio)<<i);
clk=1;
Delay\_2us();
clk=0;
Delay\_2us();
}
cs=1;
return (dat0==dat1)?dat0:0; //判断dat0与dat1是否相等
}

void main()
{
uchar adc = 0;
uint voltage = 0;
uchar LED_buffer1[16] = {" ADC: "};//ADC显示缓冲
uchar LED_buffer2[16] = {"Voltage: V "};//电压显示缓冲
Init\_LCD1602();//1602初始化
while(1)
{
adc = ADC\_read\_data(0);//读取adc值
voltage = adc \* 500.0 / 255;//将adc值换算成电压

LED_buffer1[9] = adc / 100 + '0'; //取adc百位,整型转ASCII码lcd显示补0
LED_buffer1[10] = adc % 100 / 10 + '0'; //取adc十位
LED_buffer1[11] = adc % 10 + '0'; //取adc个位

LED_buffer2[9] = voltage / 100 + '0'; //取电压个位
LED_buffer2[10] = '.';//小数点
LED_buffer2[11] = voltage / 10 % 10 + '0'; //取电压十分位
LED_buffer2[12] = voltage % 10 + '0'; //取电压百分位

LCD1602\_Dis\_Str(0, 0, &LED_buffer1[0]); //显示字符串
LCD1602\_Dis\_Str(0, 1, &LED_buffer2[0]); //显示字符串
}
}

仿真资源和程序源码

1
2
3
链接:https://pan.baidu.com/s/1oHGT-6HFYlj4KtKVqvzONw 
提取码:mx1r