STC89C51单片机与ADC0832通信详解

文章目录

  • 简介
  • ADC0832的介绍
  • 硬件连接
  • 应用
  • 简介

    ADC0832是一种常用的8位模数转换器,它可以将模拟信号转换为数字信号,以供单片机进行处理。STC89C51系列单片机是一款常见的8位单片机,具有强大的处理能力和丰富的外设资源,可以与ADC0832通信,实现模拟信号采集的功能。

    本文将介绍如何使用STC89C51单片机与ADC0832通信,并通过代码演示具体实现过程。本文的代码示例基于Keil C51开发环境,使用的是STC89C52单片机,但与STC89C51单片机的通信方式相同。

    ADC0832的介绍

    ADC0832是一种8位串行模数转换器,具有以下特点:

  • 输入电压范围为0-5V;
  • 8位分辨率,可以将模拟信号转换为8位数字信号;
  • 支持单通道和双通道转换;
  • 采用串行通信接口,只需要3根信号线即可与单片机通信。
  • 硬件连接

    在使用STC89C51单片机与ADC0832通信之前,需要先将它们连接起来。连接方式如下:

  • 将ADC0832的VCC引脚连接到单片机的VCC电源引脚;
  • 将ADC0832的GND引脚连接到单片机的GND电源引脚;
  • 将ADC0832的CS引脚连接到单片机的P1.0引脚;
  • 将ADC0832的CLK引脚连接到单片机的P1.1引脚;
  • 将ADC0832的DOUT引脚连接到单片机的P1.2引脚;
  • 将ADC0832的AIN0引脚连接到待测量信号的正极;
  • 将ADC0832的AIN1引脚连接到待测量信号的负极。
    连接完成后,就可以开始编写程序实现通信了。
  • 编程实现
    ADC0832的通信过程比较简单,只需要通过单片机的IO口向它发送指令和时钟信号,即可完成数据转换。下面我们将详细介绍STC89C51单片机与ADC0832通信的具体实现过程。

    #include <reg52.h>      // 导入头文件
    
    sbit CS = P1^0;          // 定义ADC的片选信号引脚
    sbit RD = P1^1;          // 定义ADC的读取信号引脚
    sbit INTR = P1^2;        // 定义ADC的中断引脚
    
    unsigned char ADC_val;   // 定义存储ADC值的变量
    
    void delay(unsigned int t);  // 延时函数
    
    void main()
    {
        while(1)
        {
            CS = 0;             // 使片选信号为低电平
            RD = 1;             // 读取信号为高电平
    
            INTR = 1;           // 开始转换
    
            delay(1);           // 等待转换结束
            RD = 0;             // 读取数据
            ADC_val = P1;       // 读取P1口的值
            CS = 1;             // 使片选信号为高电平
    
            // 将ADC值传送到LCD显示
            // ...
    
            // 将ADC值传送到串口输出
            // ...
        }
    }
    
    // 延时函数
    void delay(unsigned int t)
    {
        unsigned int i, j;
        for (i = 0; i < t; i++)
        {
            for (j = 0; j < 125; j++);
        }
    }
    
    

    在这个例子中,我们首先定义了P1口的第0位作为片选信号,第1位作为读取信号,P3口的第4位作为中断信号。我们还定义了一个ADC_val变量来存储ADC的值。然后,在while(1)循环中,我们使用了一些简单的控制语句来完成ADC的读取和转换。

    我们首先将片选信号设为低电平,将读取信号设为高电平,并且设置了中断信号。然后我们使用一个简单的延时函数来等待转换的完成,然后我们将读取信号设为低电平,并将P1口的值读取到ADC_val变量中。最后,我们将片选信号设置为高电平,以完成读取。

    这个例子还没有展示如何将ADC值传送到LCD或串口输出,这部分可以根据具体应用进行修改。

    应用

    以下是一份使用STC89C51单片机与ADC0832模数转换器通信并通过串口输出的示例程序。

    #include <reg52.h>
    
    #define FOSC 11059200L
    #define BAUD 9600
    #define T1MS (65536-FOSC/12/1000)
    
    sbit ADC_CS = P2^0;
    sbit ADC_OUT = P2^1;
    sbit ADC_CLK = P2^2;
    
    void initUart();
    void initTimer1();
    void sendChar(char c);
    void sendString(char* s);
    void delay(unsigned int t);
    
    void main()
    {
        unsigned char ch;
        unsigned int temp;
    
        initUart();
        initTimer1();
    
        while(1)
        {
            ADC_CS = 0;     // 开始转换
            delay(1);
            ADC_CS = 1;     // 结束转换
    
            ADC_CLK = 1;
            ADC_CLK = 0;
            temp = 0;
            for(ch = 0; ch < 8; ch++)
            {
                ADC_CLK = 1;
                temp |= ADC_OUT;
                temp <<= 1;
                ADC_CLK = 0;
            }
            temp >>= 1;
    
            sendString("ADC value is:");
            sendChar((temp/1000)+'0');
            sendChar((temp%1000/100)+'0');
            sendChar((temp%100/10)+'0');
            sendChar((temp%10)+'0');
            sendString("\r\n");
    
            delay(100);
        }
    }
    
    void initUart()
    {
        TMOD |= 0x20;   //设置定时器1为模式2
        TH1 = TL1 = T1MS / 256;
        TR1 = 1;        //启动定时器1
        SCON = 0x50;    //设置串口为工作模式1
        PCON = 0x00;    //波特率不加倍
        ES = 1;         //使能串口中断
        EA = 1;         //总中断使能
    }
    
    void initTimer1()
    {
        TMOD &= 0xF0;   //清零低四位
        TMOD |= 0x01;   //设定为定时器模式
        TH0 = 0x0B;     //设定定时时间
        TL0 = 0xDC;
        ET0 = 1;        //开启定时器0中断
        TR0 = 1;        //开启定时器0
    }
    
    void sendChar(char c)
    {
        SBUF = c;
        while(TI == 0);
        TI = 0;
    }
    
    void sendString(char* s)
    {
        while(*s != '\0')
        {
            sendChar(*s);
            s++;
        }
    }
    
    void delay(unsigned int t)
    {
        unsigned int i, j;
    
        for(i = 0; i < t; i++)
            for(j = 0; j < 120; j++);
    }
    
    void uart() interrupt 4
    {
        if(RI == 1)
        {
            RI = 0;
        }
    }
    
    

    上述代码中的ADC_CS、ADC_OUT、ADC_CLK三个引脚分别连接到了STC89C51单片机的P2.0、P2.1、P2.2口。通过控制这三个引脚的电平,串口引脚P30、P31,晶振11.0952MHZ,波特率9600。

    当然,我们也可以将读取到的 ADC 值转换为电压值,主函数做一下修改:

    float V_vlaue;
    
    void main()
    {
        unsigned char ch;
        unsigned int temp;
    
        initUart();
        initTimer1();
    
        while(1)
        {
            ADC_CS = 0;     // 开始转换
            delay(1);
            ADC_CS = 1;     // 结束转换
    
            ADC_CLK = 1;
            ADC_CLK = 0;
            temp = 0;
            for(ch = 0; ch < 8; ch++)
            {
                ADC_CLK = 1;
                temp |= ADC_OUT;
                temp <<= 1;
                ADC_CLK = 0;
            }
            temp >>= 1;
    
    		V_vlaue=(float)temp/255*5;
            sendString("ADC value is:");
            sendChar((temp/1000)+'0');
            sendChar((temp%1000/100)+'0');
            sendChar((temp%100/10)+'0');
            sendChar((temp%10)+'0');
            sendString("\r\n");
    
            delay(100);
        }
    }
    
    

    以上程序实现了 STC89C51 与 ADC0832 的通信,读取了 ADC 的值并通过串口输出。整个过程中,我们需要注意以下几点:

    1. ADC0832 的输出数据是采用串行通信方式传输的,需要按照规定的时序进行读取。

    2. ADC0832 的输入引脚需要外部提供参考电压,通常为 5V,以确保准确测量。

    3. 读取到的 ADC 值需要根据公式进行转换,才能得到实际的输入电压值。

    4. STC89C51 的串口通信需要进行波特率配置,以确保与外部设备的通信稳定。

    综上,以上程序是一个比较完整的 STC89C51 与 ADC0832 的通信程序,可以作为参考实现类似应用的开发。

    物联沃分享整理
    物联沃-IOTWORD物联网 » STC89C51单片机与ADC0832通信详解

    发表回复