本设计的程序可直接用于以下单片机(STC89C51、STC89C52、AT89S51、AT89S52、AT89C51、AT89C52),硬件构成:单片机+最小系统+1602液晶
显示屏+ADC0832模数转换芯片+电位器调节模块,采用ADC0832芯片模数转换,量程是0-5V、分辨率是0.08V。
本设计含:C语言单片机源程序(编程环境Keil4)、PR0TEUS7.8及以上仿真文件。
#include <REGX51.H>
#include <intrins.h>
#include<stdio.h>
#define THC0 0xf8
#define TLC0 0x50
#include "LCD.H"
#include "delay.h"
/*******************************定义全局变量********************************/
unsigned char count = 0x00; //定时器计数
unsigned char CH; //通道变量
unsigned char aa[16]={' ','C','u','r','r','e','n','t',' ','V','o','l','a','g','e',':'};
unsigned char cc[16]={' ',' ',' ',' ',' ',' ','.',' ',' ','V',' ',' ',' ',' ',' ',' '};
unsigned int v,dat;
/*********************************端口定义**********************************/
sbit CS = P3^6;
sbit Clk = P3^4;
sbit DATI = P3^5;
sbit DATO = P3^5;
/****************************************************************************
函数功能:AD转换子程序
入口参数:CH 出口参数:dat
****************************************************************************/
unsigned char adc0832(unsigned char CH)
{
unsigned char i,test,adval;
adval = 0x00;
test = 0x00;
Clk = 0; //初始化
DATI = 1;
_nop_();
CS = 0;
_nop_();
Clk = 1;
_nop_();
if ( CH == 0x00 ) //通道选择
{
Clk = 0;
DATI = 1; //通道0的第一位
_nop_();
Clk = 1;
_nop_();
Clk = 0;
DATI = 0; //通道0的第二位
_nop_();
Clk = 1;
_nop_();
}
else
{
Clk = 0;
DATI = 1; //通道1的第一位
_nop_();
Clk = 1;
_nop_();
Clk = 0;
DATI = 1; //通道1的第二位
_nop_();
Clk = 1;
_nop_();
}
Clk = 0;
DATI = 1;
for( i = 0;i < 8;i++ ) //读取前8位的值
{
_nop_();
adval <<= 1;
Clk = 1;
_nop_();
Clk = 0;
if (DATO)
adval |= 0x01;
else
adval |= 0x00;
}
for (i = 0; i < 8; i++) //读取后8位的值
{
test >>= 1;
if (DATO)
test |= 0x80;
else
test |= 0x00;
_nop_();
Clk = 1;
_nop_();
Clk = 0;
}
if (adval == test) //比较前8位与后8位的值,如果不相同舍去。若一直出现显示为零,请将该行去掉
dat = test;
_nop_();
CS = 1; //释放ADC0832
DATO = 1;
Clk = 1;
return dat;
}
/**************主函数************/
void main()
{
TMOD = 0x01; //设置中断
TH0=(65536-50000)/256; //定时器1初值定时50ms
TL0=(65536-50000)%256;
IE = 0x82;
TR0 = 1;
init();
LCD_Write_String(0,0,aa);
while(1)
{
v=dat*1.96;
cc[5]=v/100+'0';
cc[7]=v/10%10+'0';
cc[8]=v%10+'0';
LCD_Write_String(0,1,cc);
}
}
/****************************************************************************
函数功能:定时器中断延时程序 这一段的作用时隔一段时间抽样一次 否侧显示的最后一位会不稳定
****************************************************************************/
void timer0(void) interrupt 1
{
TMOD = 0x01;
TH0=(65536-50000)/256; //定时器1初值定时50ms
TL0=(65536-50000)%256;
IE = 0x82;
TR0 = 1;
count++;
if (count == 0x01)
{
count = 0x00;
dat = adc0832(CH);
}
}