51单片机简易数字电压表设计:使用ET2046芯片实现电压测量和显示

本示例演示了如何使用51单片机、ET2046 A/D、D/A芯片和LCD1602实现一个简易的数字电压表。程序利用单片机的ADC功能进行电压采样,通过D/A芯片输出电压,并使用LCD显示测量结果。

代码实现

#include <reg51.h>
#include <intrins.h>

#define LCD_RS P3_0
#define LCD_RW P3_1
#define LCD_EN P3_2
#define LCD_DATA P2

sbit ADC_CS = P1^0;
sbit DAC_CS = P1^1;
sbit ADC_CLK = P1^2;
sbit ADC_DIN = P1^3;
sbit ADC_DOUT = P1^4;
sbit DAC_CLK = P1^5;
sbit DAC_DIN = P1^6;

void delay_us(unsigned int us) {
    while (us--) {
        _nop_();
        _nop_();
        _nop_();
        _nop_();
    }
}

void delay_ms(unsigned int ms) {
    while (ms--) {
        delay_us(1000);
    }
}

void LCD_WriteCmd(unsigned char cmd) {
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_DATA = cmd;
    LCD_EN = 1;
    delay_us(1);
    LCD_EN = 0;
    delay_ms(2);
}

void LCD_WriteData(unsigned char dat) {
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_DATA = dat;
    LCD_EN = 1;
    delay_us(1);
    LCD_EN = 0;
    delay_ms(2);
}

void LCD_Init() {
    LCD_WriteCmd(0x38); // 8位数据接口,2行显示,5x7点阵字符
    LCD_WriteCmd(0x0C); // 开显示,不显示光标
    LCD_WriteCmd(0x06); // 显示地址自动加1
    LCD_WriteCmd(0x01); // 清屏
}

void LCD_DisplayVoltage(unsigned int voltage) {
    unsigned char str[5];
    sprintf(str, "%4d", voltage);
    LCD_WriteCmd(0x80); // 设置显示位置为第一行第一个字符
    LCD_WriteData(str[0]);
    LCD_WriteData(str[1]);
    LCD_WriteData(str[2]);
    LCD_WriteData(str[3]);
    LCD_WriteData('V');
}

unsigned int ADC_Read() {
    unsigned int val = 0;
    unsigned char i;
    
    ADC_CS = 0;
    ADC_CLK = 0;
    ADC_DIN = 0;
    delay_us(1);
    ADC_CLK = 1;
    delay_us(1);
    ADC_CLK = 0;
    delay_us(1);
    
    for (i = 0; i < 12; i++) {
        ADC_CLK = 1;
        val <<= 1;
        ADC_CLK = 0;
        delay_us(1);
        val |= ADC_DOUT;
        delay_us(1);
    }
    
    ADC_CS = 1;
    return val;
}

void DAC_Write(unsigned int val) {
    unsigned char i;
    
    DAC_CS = 0;
    DAC_CLK = 0;
    
    for (i = 0; i < 12; i++) {
        DAC_DIN = (val & 0x8000) ? 1 : 0;
        val <<= 1;
        delay_us(1);
        DAC_CLK = 1;
        delay_us(1);
        DAC_CLK = 0;
        delay_us(1);
    }
    
    DAC_CS = 1;
}

void main() {
    unsigned int voltage;
    
    LCD_Init();
    
    while (1) {
        voltage = ADC_Read();
        DAC_Write(voltage);
        LCD_DisplayVoltage(voltage);
        delay_ms(1000);
    }
}

代码解释

  1. 硬件连接: 需要将51单片机、ET2046 A/D、D/A芯片和LCD1602按照设计要求连接。
  2. 引脚定义: 程序中定义了各个芯片的引脚映射关系,需要根据实际连接修改。
  3. 初始化: LCD_Init() 函数初始化LCD1602,包括设置数据接口、显示模式、光标等。
  4. ADC读数: ADC_Read() 函数读取A/D芯片的转换结果,得到电压值。
  5. DAC输出: DAC_Write() 函数将电压值写入D/A芯片,控制电压输出。
  6. LCD显示: LCD_DisplayVoltage() 函数将电压值转换成字符串并在LCD上显示。
  7. 主循环: 主循环中不断进行电压采样、输出和显示,实现实时电压测量。

注意

  • 程序中引脚定义和初始化代码需根据实际硬件连接情况修改。
  • 需要根据具体的A/D和D/A芯片的规格书调整程序中的时序和控制信号操作。
  • 可以根据实际需要修改程序中的延时时间和显示格式。

应用

本程序可以用在各种需要实时监测电压的应用中,例如电池电量显示、电源电压监测等。


原文地址: https://www.cveoy.top/t/topic/o1zF 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录