标题:
基于单片机的0-22V电压表电路图+源程序
[打印本页]
作者:
yunduobala
时间:
2019-4-14 15:50
标题:
基于单片机的0-22V电压表电路图+源程序
基于单片机的0-24V电压表 电路原理图如下:
图片1.png
(3.34 MB, 下载次数: 12)
下载附件
2019-4-14 15:34 上传
单片机源程序如下:
#include"reg52.h"
#include"intrins.h"
typedef unsigned char uchar;
typedef unsigned int uint;
#define _Nop() _nop_()
unsigned char data_char_table[]= {"0123456789ABCDEF"}; //LCD数据
unsigned char Lcd_Dis1_table[] = {"Position:No. "}; //第一行显示框架
unsigned char pos_char_table[] = {" D "}; // 显示位置
unsigned char Lcd_Dis2_table[] = {"Voltage : V"}; //第二行显示框架
unsigned char num_char_table[] = {" 9A.CD V"}; // 显示位置
sbit lcd_rs_port=P2^5; //定义 LCD控制端口,根据硬件调整
sbit lcd_rw_port=P2^6;
sbit lcd_en_port=P2^7;
sbit X=P3^4;
sbit Y=P3^3;
sbit Z=P3^2;
#define lcd_data_port P0
void lcd_delay(uchar ms); //LCD1602延时
void lcd_busy_wait(); //LCD1602忙等待
void lcd_command_write(uint command); //LCD1602命令字写入
void lcd_system_reset(); //LCD1602初始化
void lcd_char_write(uint x_pos,y_pos,lcd_dat); //LCD1602字符写入
void lcd_bad_check(); //LCD1602坏点检查
void Num_to_Disp(uchar i,uint Num); //显示数据处理
void LcdDisp(uchar j,uint num); //液晶显示函数
float adadverage();
/*****定义与 ADC相关的特殊功能寄存器 *****/
sfr ADC_CONTR= 0xBC; //ADC控制寄存器
sfr ADC_RES = 0xBD; //ADChight8-bitresultregister
sfr ADC_RESL = 0xBE; //ADClow2-bitresultregister
sfr P1ASF = 0x9D; //P1口功能控制寄存器 P1ASF
/************定义相应操作位***************/
#define ADC_POWER 0x80 //ADC电源控制位,0:关闭,1:打开
#define ADC_FLAG 0x10 //ADC结束标志位
#define ADC_START 0x08 //ADC启动控制位
#define ADC_SPEEDLL 0x00 //540clocks__________选择转换速度
void InitADC(); //ADC初始化
uint GetADCResult(uchar ch);
void Delay(uint n); //延时程序
void delay_1ms(uchar x);
void decide();
/*--------------------------------主函数 --------------------------------*/
void main()
{
lcd_system_reset(); //LCD1602初始化
lcd_bad_check(); //LCD1602坏点检查
InitADC(); //初始化 ADC特殊功能寄存器
while(1)
{
decide();
Delay(1000);
}
}
/*--------------------------------域值判断 ------------------------------*/
void decide()
{
unsigned int res;
float NUM;
NUM=0.0;
X=1;
Y=1;
Z=1;
res=GetADCResult(0);
NUM=(res*5.00/1024.0);
NUM=NUM*5;
if(NUM<4.99)
{
X=1;
Y=1;
Z=0;
Delay(10);
LcdDisp(4,adadverage());
}
else if(NUM>=4.99&&NUM<6.24)
{
X=0;
Y=0;
Z=1;
Delay(10);
LcdDisp(3,adadverage());
}
else if(NUM>=6.24&&NUM<8.2)
{
X=1;
Y=0;
Z=1;
Delay(10);
LcdDisp(2,adadverage());
}
else if(NUM>=8.2&&NUM<12.4)
{
X=0;
Y=1;
Z=1;
Delay(10);
LcdDisp(1,GetADCResult(0));
}
else if(NUM>=12.4&&NUM<25.0)
{
X=1;
Y=1;
Z=1;
Delay(10);
LcdDisp(0,adadverage());
}
else
{
LcdDisp(8,0);
}
}
/*--------------------------------ADC取值 ------------------------------*/
uint GetADCResult(uchar ch)
{
ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ch|ADC_START;
_nop_(); //Mustwaitbeforeinquiry
_nop_();
_nop_();
_nop_();
while(!(ADC_CONTR & ADC_FLAG)); //Waitcompleteflag
ADC_CONTR &=ADC_FLAG; //Close ADC
return(ADC_RES*4+ADC_RESL); //ReturnADCresult
}
/*AD初始化*/
void InitADC()
{
P1ASF=P1|0x3f; //Set P1.0-P1.5 as an alogin putport
ADC_RES =0; //Clearpreviousresult
ADC_RESL=0;
ADC_CONTR=ADC_POWER|ADC_SPEEDLL;
Delay(20);
} //ADCpower-ondelayandStartA/Dconversion}
///////////////以下为 LCD显示数据处理/////////////////
void Num_to_Disp(uchar i,uint Num)
{
float NUM;
int xx,yy,zz,vv;
NUM=(Num*5.00/1024.0);//计算公式:10-bitA/DConversionResult=1024x(Vin/Vcc)
switch(i)
{
case 0:NUM=NUM*5.10;break;
case 1:NUM=NUM*2.52;break;
case 2:NUM=NUM*1.69;break;
case 3:NUM=NUM*1.27;break;
case 4:NUM=NUM*1.00;break;
}
xx=(int)NUM;
yy=(int)((NUM-(float)(xx))*10);
zz=(int)((NUM-(float)(xx))*100)%10;
vv=(int)((NUM-(float)(xx))*1000)%10;
num_char_table[9]=data_char_table[xx / 10]; //电压值十位
num_char_table[10]=data_char_table[xx % 10]; //电压值个位
num_char_table[12]=data_char_table[yy]; //电压值小数点后一位
num_char_table[13]=data_char_table[zz]; //电压值小数点后两位
num_char_table[14]=data_char_table[vv]; //电压值小数点后三位
pos_char_table[13]=data_char_table[i]; //当前 ADC接口
}
//////////////////以下为 LCD显示////////////////////
void LcdDisp(uchar j,uint num)
{
uint i=0;
for(i=0;i<16;i++)
{
lcd_char_write(i,0,Lcd_Dis1_table[i]);
lcd_char_write(i,1,Lcd_Dis2_table[i]); //显示框架
}
Num_to_Disp(j,num);
lcd_char_write(13,0,pos_char_table[13]);
for(i=9;i<15;i++)
{
lcd_char_write(i,1,num_char_table[i]); //显示电压
}
delay_1ms(100);
}
//////////////以下是 LCD1602驱动程序////////////////
/*LCD1602延时*/
void lcd_delay(uchar ms)
{
uchar j;
while(ms--)
{
for(j=0;j<250;j++)
{;}
}
}
/*LCD1602忙等待*/
void lcd_busy_wait()
{
lcd_rs_port=0;
lcd_rw_port=1;
lcd_en_port=1;
lcd_data_port=0xff;
while(lcd_data_port&0x80);
lcd_en_port=0;
}
/*LCD1602命令字写入*/
void lcd_command_write(uint command)
{
lcd_busy_wait();
lcd_rs_port=0;
lcd_rw_port=0;
lcd_en_port=0;
lcd_data_port=command;
lcd_en_port=1;
lcd_en_port=0;
}
/*LCD1602初始化*/
void lcd_system_reset( )
{
lcd_delay(20);
lcd_command_write(0x38);
lcd_delay(100);
lcd_command_write(0x38);
lcd_delay(50);
lcd_command_write(0x38);
lcd_delay(10);
lcd_command_write(0x08);
lcd_command_write(0x01);
lcd_command_write(0x06);
lcd_command_write(0x0c);
}
/*LCD1602字符写入*/
void lcd_char_write(uint x_pos,y_pos,lcd_dat)
{
x_pos &=0x0f;/*X位置范围 0~15*/
y_pos &=0x01;/*Y位置范围 0~1*/
if(y_pos==1)
x_pos +=0x40;
x_pos +=0x80;
lcd_command_write(x_pos);
lcd_busy_wait();
lcd_rs_port=1;
lcd_rw_port=0;
lcd_en_port=0;
lcd_data_port=lcd_dat;
lcd_en_port=1;
lcd_en_port=0;}
/*LCD1602坏点检查*/
void lcd_bad_check()
{
char i,j;
for(i=0;i<2;i++)
{
for(j=0;j<16;j++)
{
lcd_char_write(j,i,0xff);
}
}
lcd_delay(200);
lcd_delay(200);
lcd_delay(200);
lcd_delay(100);
lcd_delay(200);
lcd_command_write(0x01);/*clearlcddisp*/
}
//////////////////以上是 LCD1602驱动程序////////////////
void Delay(uint n)
{
uint x;
while(n--)
{
x=500;
while(x--);
}
}
/*1MS为单位的延时程序*/
void delay_1ms(uchar x)
{
uchar j;
while(x--)
{
for(j=0;j<125;j++)
{;}
}
}
float adadverage()
{
float adverageval;
unsigned char i;
for(i=0;i<200;i++)
{
adverageval += GetADCResult(0);
}
adverageval=adverageval/200;
return(adverageval);
}
复制代码
所有资料51hei提供下载:
程序.rar
(33.74 KB, 下载次数: 20)
2019-4-14 15:30 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1