使用STC12C5A60S2内部AD测量电压0-5V(单片机应使用5V电压供电)

使用STC12C5A60S2内部AD测量电压0-5V(单片机应使用5V电压供电)

main.c

/***********************************************************
程序功能:ADC采集电压信号(0-5V)+LCD1602液晶显示
***********************************************************/
#include "reg51.h"
#include "intrins.h"
//sfr P4        = 0XC0;
sfr ADC_CONTR = 0XBC;
sfr ADC_RES   = 0XBD;
sfr ADC_LOW2  = 0XBE;
sfr P1ASF     = 0X9D;

typedef unsigned char BYTE;
typedef unsigned int WORD;

#include "1602.h"

#define ADC_POWER   0X80
#define ADC_FLAG    0X10
#define ADC_START   0X08
#define ADC_SPEEDLL 0X00
#define ADC_SPEEDL  0X20
#define ADC_SPEEDH  0X40
#define ADC_SPEEDHH 0X60

void InitADC();
void Delay(WORD n);
WORD GetADCResult(BYTE ch);
void DisplayADCResult(BYTE Channel);

char bai=0,shi=0,ge=0;

void main()
{
	WORD i=0;
	InitADC();
	LCDInit();
	DisplayListChar(0, 0, "Volt:");
	while(1)
	{
		i++;
		if(i==500)
		{
			DisplayADCResult(0);
			i=0;
		}			
	}
}
/平均滤波//
#define N 100
float AD_average(BYTE Channel)
{
	float value=0;
	BYTE count;
	for(count=0;count<100;count++)
	{
	value+=GetADCResult(Channel);   //100次采样
	}
//value/=202.5;
// value/=205;
// value/=2048;
// value/=512;
 value/=100;		   //求平均
 value=value*5.0/1024;//val/1024*5
 return value;
}
void DisplayADCResult(BYTE Channel)
{
	float ADResult;
	WORD Result;
	ADResult=AD_average(Channel)*100;
	Result=(int)ADResult;

	bai=Result/100;
	shi=Result%100/10;
	ge=Result%10;

	DisplayOneChar(6,0,table[bai]);
	DisplayOneChar(7,0,'.');
	DisplayOneChar(8,0,table[shi]);
	DisplayOneChar(9,0,table[ge]);
	
	DisplayOneChar(10,0,'V');
		
}

WORD GetADCResult(BYTE ch)
{
	ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ch|ADC_START;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	while(!(ADC_CONTR&ADC_FLAG));
	ADC_CONTR&=~ADC_FLAG;

	return ADC_RES*4+ADC_LOW2;
}

void InitADC()
{
	P1ASF = 0XFF;
	ADC_RES = 0;
	ADC_CONTR = ADC_POWER|ADC_SPEEDLL;
	Delay(2);
}

void Delay(WORD t)
{
	WORD x;
	while(t--)
	{
		x = 5000;
		while(x--);
	}
}


1602.h

sbit LCD_RS=P0^7;//定义引脚
sbit LCD_RW=P0^6;
sbit LCD_E=P0^5;
#define LCD_Data P2

/********宏定义***********************************************************/
#define Busy    0x80 //用于检测LCD状态字中的Busy标识


/********数据定义*************************************************************/
code BYTE table[]={48,49,50,51,52,53,54,55,56,57};	 //0-9 ascii码的数字

/********函数声明*************************************************************/
void WriteDataLCD(BYTE WR_DATA);					//写数据
void WriteCommandLCD(BYTE WCLCD);		//写命令
void WriteCommandLCD1(BYTE WCLCD);		//写命令
void busy_check(void);						//读状态
void LCDInit(void);										//初始化
void DisplayOneChar(BYTE X, BYTE Y, BYTE DData);			//相应坐标显示字节内容
void DisplayListChar(BYTE X, BYTE Y, BYTE code *DData);	//相应坐标开始显示一串内容
//void delay1MS(uint t)
//{
//	uint i,j;
//	for(i=0;i<t;i++)
//	for(j=0;j<935;j++);
//}

/*初始化*/	
void LCDInit(void)
{
	WriteCommandLCD(0x38);//不检测忙信号
	WriteCommandLCD(0x08); 	//关闭显示
	WriteCommandLCD(0x01); 	//显示清屏
	WriteCommandLCD(0x06); 	//显示光标移动设置
	WriteCommandLCD(0x0C); 	//显示开及光标设置
}

/*按指定位置显示一串字符*/	
void DisplayListChar(BYTE X, BYTE Y, BYTE code *DData)
{
 	BYTE ListLength;
 	ListLength = 0;
 	X &= 0xF;
	Y &= 0x1; 				//限制X不能大于15,Y不能大于1
 	while (DData[ListLength]>=0x20){ //若到达字串尾则退出
   		if (X <= 0xF){ 		//X坐标应小于0xF
     		DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
     		ListLength++;
     		X++;
    	}
  	}
}

/*按指定位置显示一个字符*/	
void DisplayOneChar(BYTE X, BYTE Y, BYTE DData)
{
	X &= 0xF; 
 	Y &= 0x1;				//限制X不能大于15,Y不能大于1
 	if (Y)
	 X |= 0x40; 		//当要显示第二行时地址码+0x40;
	
	X |= 0x80; 			//算出指令码
 	WriteCommandLCD(X); //发送地址码
 	WriteDataLCD(DData);
}

/***********写指令********************************************************/	
void WriteCommandLCD(BYTE WCLCD)
{	
	busy_check();
	LCD_Data = WCLCD;
	LCD_RS = 0;
	LCD_RW = 0; 
	LCD_E = 1; 	
	LCD_E = 0;
}

 /***********写数据********************************************************/	
void WriteDataLCD(BYTE WR_DATA)
{
	busy_check(); //检测忙
 	LCD_Data = WR_DATA;
 	LCD_RS = 1;
 	LCD_RW = 0;
	LCD_E = 1; 
	LCD_E = 0; 
}

//检测忙信号
void busy_check(void)
{
 	LCD_Data = 0xFF; 
	LCD_E = 0;
 	LCD_RS = 0;
 	LCD_RW = 1;
 	LCD_E = 1;
 	while (LCD_Data & Busy);
	LCD_E = 0;
}


 

效果

0.00V、3.3V、5.0V测试

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值