一、数据手册
二、时序分析及通道选择
1、拉低CS信号,启动ADC0834。
![](https://i-blog.csdnimg.cn/blog_migrate/6d3d41581fb8e4f1ed37679fe7cc0375.jpeg)
2、选择通道。
![](https://i-blog.csdnimg.cn/blog_migrate/830b0e0fc438d7b77f36c68ff6ef7661.jpeg)
按照下表输入DI,就可以选择所需要的通道
![](https://i-blog.csdnimg.cn/blog_migrate/1fe27ba84d5f5a1753516b01b3fe6b81.jpeg)
3、获得数据。
![](https://i-blog.csdnimg.cn/blog_migrate/69236b50120a875515c60e496a37b6e0.jpeg)
ADC0834会在八个下降沿获得数据,并通过DO输出。
4、更换通道。
当需要更换通道时,将CS信号先拉高,在拉低重新配置就可以啦!
三、Proteus仿真电路图及结果
![](https://i-blog.csdnimg.cn/blog_migrate/fffb4ec8ebdacc40790b55d1dfab95ac.jpeg)
四、程序代码
#include <reg52.h>
#include <intrins.h>
#define NOP _nop_()
#define noACK 0
#define ACK 1
#define uint unsigned int
#define uchar unsigned char
/**************************位定义区**************************/
sbit E=P3^0; //LCD使能端口定义
sbit RW=P3^1; //LCD读写使能端口定义
sbit RS=P3^2; //LCD数据/命令选择方式端口定义
sbit bflag=P2^7; //LCD忙指示端口,高电平为忙
sbit CS=P1^1;
sbit CLK=P1^0;
sbit DI=P1^4;
sbit DO=P1^5;
/**************************子函数声明区**************************/
unsigned char adc_0834(int channel); //函数功能:返回通道channel的数据,channel可以是:0、1、2、3
void lcd_pos(unsigned char pos) ; //函数功能:指定数据显示地址
void busy_1602(); //判忙LCD忙闲
void init_1602(); //LCD1602初始化子函数
void wreg_1602(unsigned char com); //函数功能:写指令函数
void wdata_1602(unsigned char dat); //函数功能:写数据函数
void main(void)
{
init_1602(); //LCD1602初始化
while(1)
{
lcd_pos(0x00); //第一行
//通道CH0
wdata_1602(adc_0834(0)/100+'0'); //显示百位上的数
wdata_1602(adc_0834(0)%100/10+'0'); //显示十位上的数
wdata_1602(adc_0834(0)%10+'0'); //显示个位上的数
wdata_1602(' '); //两个数据间用空格隔开
//通道CH1
wdata_1602(adc_0834(1)/100+'0'); //显示百位上的数
wdata_1602(adc_0834(1)%100/10+'0'); //显示十位上的数
wdata_1602(adc_0834(1)%10+'0'); //显示个位上的数
lcd_pos(0x40); //换到第二行
//通道CH2
wdata_1602(adc_0834(2)/100+'0'); //显示百位上的数
wdata_1602(adc_0834(2)%100/10+'0'); //显示十位上的数
wdata_1602(adc_0834(2)%10+'0'); //显示个位上的数
wdata_1602(' '); //两个数据间用空格隔开
//通道CH3
wdata_1602(adc_0834(3)/100+'0'); //显示百位上的数
wdata_1602(adc_0834(3)%100/10+'0'); //显示十位上的数
wdata_1602(adc_0834(3)%10+'0'); //显示个位上的数
}
}
void busy_1602() //判忙LCD忙闲?
{
do
{
P2=0xff;
RS=0; //RS=0,RW=1时才可读忙信号
RW=1;
E=0;
_nop_();
//读取P2口数据,读取bflag
E=1;
}while(bflag); //当其值为0时,表示不忙,才可以接收命令或者数据信号
}
void wreg_1602(unsigned char com) //函数功能:写指令函数
{
busy_1602();
RS=0; //当RS=0,RW=0时,表明写入的是命令
RW=0;
E=1;
P2=com; //当使能由高到低时,LCD执行相应命令
E=0;
}
void wdata_1602(unsigned char dat) //函数功能:写数据函数
{
busy_1602();
RS=1; //当RS=1,RW=0时,表明写入的是数据
RW=0;
E=1;
P2=dat; //当使能由高到低时,LCD执行相应命令
E=0;
}
void lcd_pos(unsigned char pos) //函数功能:指定数据显示地址
{
wreg_1602(pos | 0x80); //命令8,最高位必须为1,第一行最左边地址为0x00;第二行为0x40 指令8
}
void init_1602() //函数功能:设置LCD_1602的开显示 光标不闪烁等的功能
{
wreg_1602(0x38); //指令6,8位数据总线,双行显示,每位采用5*7点阵 指令6
wreg_1602(0x08); //指令4,关显示,关光标,无闪烁 指令4
wreg_1602(0x06); //指令3,光标自动右移,文字不移动 指令3
wreg_1602(0x01); //指令1,清显示 指令1
wreg_1602(0x0c); //指令4,开显示 指令4
}
unsigned char adc_0834(int channel) //channel:要选择的通道————0,1,2,3
{
unsigned char i,com;
unsigned int CH[4][4] = {{1,1,0,0},{1,1,1,0},{1,1,0,1},{1,1,1,1}};
CS=1;
CS=0; _nop_(); _nop_(); //CS置低,启动转换
CLK=0; _nop_(); _nop_();
//选择通道——根据Table4 修改DI值,选择不同的通道
//以下代码是选择的CH0
//上升沿1——start bit
DI=CH[channel][0]; _nop_(); _nop_(); //启动,准备输出数据
CLK=1; _nop_(); _nop_();
CLK=0; _nop_(); _nop_();
//上升沿2——SGL/DIF
DI=CH[channel][1];
CLK=1; _nop_(); _nop_();
CLK=0; _nop_(); _nop_();
//上升沿3——ODD/SIGN
DI=CH[channel][2];
CLK=1; _nop_(); _nop_();
CLK=0; _nop_(); _nop_();
//上升沿4——SELECT
DI=CH[channel][3];
CLK=1; _nop_(); _nop_();
//下降沿 准备开始采集数据
DI=1;
CLK=0; _nop_(); _nop_();
CLK=1; _nop_(); _nop_();
for(i=8;i>0;i--){
CLK=0; //下降沿 采集数据
com<<=1; //左移,先采最高位
if(DO)com=com|0x01; //采当前数据
CLK=1;
_nop_();
_nop_();
}
CS=1;
return com;
}
五、一个小白的话
本人也是小白一个,哪里写的不好需要改进的地方还请批评指正。
我想,如果你能收藏本篇文章或关注我的话,我会很开心的😜^~^!!!
非常感谢你的支持!!!