51单片机:Proteus仿真——用LCD1602显示ADC0834获得的数据

一、数据手册

ADC083x数据手册

二、时序分析及通道选择

1、拉低CS信号,启动ADC0834。

2、选择通道。

按照下表输入DI,就可以选择所需要的通道

3、获得数据。

ADC0834会在八个下降沿获得数据,并通过DO输出。

4、更换通道。

当需要更换通道时,将CS信号先拉高,在拉低重新配置就可以啦!

三、Proteus仿真电路图及结果

四、程序代码

#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;
}

五、一个小白的话

本人也是小白一个,哪里写的不好需要改进的地方还请批评指正。

我想,如果你能收藏本篇文章或关注我的话,我会很开心的😜^~^!!!

非常感谢你的支持!!!

  • 10
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

堂钰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值