⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adc0832.c

📁 用ADC0832芯片来做的数字电压表程序
💻 C
字号:

/********************************************************************/
/*                                                                  */
/* ME300B单片机开发系统演示程序 - ADC0832电压表                     */
/*                                                                  */
/* LCD1602显示                                                      */
/* 参考电压接至5V电源                                               */
/* 最小输出电压:0.00V  最大输出电压:5.00V  分辨率:0.02V          */
/*                                                                  */
/* 邮箱:  gguoqing@willar.com                                       */
/* 网站: http://www.willar.com                                     */
/* 作者: gguoqing                                                  */
/* 时间: 2006/01/20                                                */
/*                                                                  */
/*                                                                  */
/*【版权】Copyright(C)伟纳电子 www.willar.com  All Rights Reserved  */
/*【声明】此程序仅用于学习与参考,引用请注明版权和作者信息!        */
/*                                                                  */
/********************************************************************/

#include"reg51.h"
#include"intrins.h"

#define uchar unsigned char
#define uint  unsigned int

#define disdata  P0       //显示数据码输出口

#define channel_0  0x02   //单通道0输入选择
#define channel_1  0x03   //单通道1输入选择

sbit ADC_CS = P3^4;        //片选端
sbit ADC_CLK= P1^0;        //时钟端
sbit ADC_DI = P1^1;        //数据输入输出复用
sbit ADC_DO = P1^1;        //DI和DO端都接在P1.1

sbit  ACC0=ACC^0;          //通道与输入方式控制字
sbit  ACC1=ACC^1;          //通道与输入方式控制字

sbit LCD_RS = P2^0;             
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;

uint data dis[4]={0x00,0x00,0x00,0x00}; 
                          //定义3个显示数据单元和一个数据存储单元

uchar code dis4[] = {"DIGITALVOLTMETER"};
uchar code dis5[] = {" VOLTAGE:  .  V "};

/********************************************************************/
/*                                                                  */
/*  延时函数                                                        */
/*                                                                  */
/********************************************************************/

void delay(uchar ms)
{
    while(ms--)
	{
      uchar i;
	  for(i=0;i<250;i++)  
	   {
	    _nop_();			   
		_nop_();
		_nop_();
		_nop_();
	   }
	}
}		

/********************************************************************/
/*                                                                  */
/*检查LCD忙状态                                                     */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。       */
/*                                                                  */
/********************************************************************/ 

bit lcd_busy()
 {                          
    bit result;
    LCD_RS = 0;
    LCD_RW = 1;
    LCD_EN = 1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    result = (bit)(P0&0x80);
    LCD_EN = 0;
    return result; 
 }

/********************************************************************/
/*                                                                  */
/*写指令数据到LCD                                                   */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。                              */
/*                                                                  */
/********************************************************************/

void lcd_wcmd(uchar cmd)

{                          
   while(lcd_busy());
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_EN = 0;
    _nop_();
    _nop_(); 
    P0 = cmd;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    LCD_EN = 1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    LCD_EN = 0;  
}

/********************************************************************/
/*                                                                  */
/*写显示数据到LCD                                                   */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。                                */
/*                                                                  */
/********************************************************************/

void lcd_wdat(uchar dat)
{                          
   while(lcd_busy());
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_EN = 0;
    P0 = dat;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    LCD_EN = 1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    LCD_EN = 0; 
}

/********************************************************************/
/*                                                                  */
/*  LCD初始化设定                                                   */
/*                                                                  */
/********************************************************************/

void lcd_init()
{                        
    lcd_wcmd(0x38);      //16*2显示,5*7点阵,8位数据
    delay(5);
    lcd_wcmd(0x38);         
    delay(5);
    lcd_wcmd(0x38);         
    delay(5);

    lcd_wcmd(0x0c);      //显示开,关光标
    delay(5);
    lcd_wcmd(0x06);      //移动光标
    delay(5);
    lcd_wcmd(0x01);      //清除LCD的显示内容
    delay(5);
}

/********************************************************************/
/*                                                                  */
/*  设定显示位置                                                    */
/*                                                                  */
/********************************************************************/

void lcd_pos(uchar pos)
{                          
  lcd_wcmd(pos | 0x80);  //数据指针=80+地址变量
}

/********************************************************************/
/*                                                                  */
/*  启动ADC转换                                                     */
/*                                                                  */
/********************************************************************/

void ADC_start() 
{
    ADC_CS=1;         //一个转换周期开始
    _nop_(); 
    ADC_CLK=0;
    _nop_();
    ADC_CS=0;         //CS置0,片选有效
    _nop_();
    ADC_DI=1;         //DI置1,起始位
    _nop_();
    ADC_CLK=1;        //第一个脉冲
    _nop_();
    ADC_DI=0;         //在负跳变之前加一个DI反转操作
    _nop_();
    ADC_CLK=0;      
    _nop_();      
}
 
/********************************************************************/
/*                                                                  */
/*AD转换函数                                                        */
/*选择输入通道,输入信号的模式《单端输入,或差分输入》              */
/*模数转换                                                          */
/*                                                                  */
/********************************************************************/
int ADC_read(uchar mode)
{
    uchar i;
    ADC_start();      //启动转换开始
    ACC=mode;
    ADC_DI=ACC1;      //输出控制位1,DI=1,单通道输入,DI=0,差分输入。
    ADC_CLK=1;        //第二个脉冲
    _nop_();
    ADC_DI=0;
    ADC_CLK=0;
    _nop_();
    ADC_DI=ACC0;      //输出控制位0,DI=0,通道0输入,DI=1,通道1输入。
    ADC_CLK=1;        //第三个脉冲
    _nop_();
    ADC_DI=1;
    ADC_CLK=0;        //输入模式和通道号已经选择完。

    ADC_CLK=1;        //第四个脉冲
    ACC=0;                 
    
    for(i=8;i>0;i--)  //读取8位数据
  {                      
    ADC_CLK=0;        //脉冲下降沿
   
    ACC=ACC<<1;
    ACC0=ADC_DO;      //读取DO端数据
    _nop_();
    _nop_();                
    ADC_CLK=1;                   
  }
    ADC_CS=1;         //CS=1,片选无效。
    return(ACC);
}

/********************************************************************/
/*                                                                  */
/* 数据处理与显示                                                   */
/* 将采集到的数据进行16进制转换为ASCLL码,并送显示。                */
/*                                                                  */
/********************************************************************/

show_value(uchar ad_data)

{   
    dis[2]=ad_data/51;   //AD值转换为3为BCD码,最大为5.00V。
    dis[2]=dis[2]+0x30;
    dis[3]=ad_data%51;   //余数暂存
    dis[3]=dis[3]*10;    //计算小数第一位
    dis[1]=dis[3]/51;
    dis[1]=dis[1]+0x30;
    dis[3]=dis[3]%51;
    dis[3]=dis[3]*10;    //计算小数第二位
    dis[0]=dis[3]/51;                                                                             //
    dis[0]=dis[0]+0x30;

    lcd_pos(0x4a);             
    lcd_wdat(dis[2]);    //整数位显示
    lcd_pos(0x4c);             
    lcd_wdat(dis[1]);    //第一位小数显示 
    lcd_pos(0x4d);             
    lcd_wdat(dis[0]);    //第二位小数显示                   
} 

/********************************************************************/
/*                                                                  */
/*  主程序                                                          */
/*                                                                  */
/********************************************************************/

void main()
{
    uchar i,n;
    delay(10);                 //延时
    lcd_init();                //初始化LCD             
        
    lcd_pos(0);                //设置显示位置为第一行的第1个字符
     i = 0;
    while(dis4[i] != '\0')
     {                         //显示字符"DIGITALVOLTMETER"
       lcd_wdat(dis4[i]);
       i++;
     }

    lcd_pos(0x40);             //设置显示位置为第二行第1个字符
     i = 0;
    while(dis5[i] != '\0')
     {
       lcd_wdat(dis5[i]);      //显示字符" VOLTAGE:  .  V "
       i++;
     }
    
     while(1)
     { 
      n=ADC_read(channel_0);   //采集值送入n
      show_value(n);           //n中数据处理与显示         
                
      delay(50);               //延时50ms
     }
} 

/********************************************************************/ 
/*                                                                  */
/*将n=ADC_read(channel_0)改为n=ADC_read(channel_1)即可使用JP6输入   */
/*                                                                  */
/********************************************************************/     

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -