2019-03-24 19:34发布
/*********************************************************************************** ToHo projetc Voltmeter 2011-11-13 电压表(精度约为0.02V) 参考电压取自3.3V IC*P1.1接3.3V 稳压电源,P1.0为输入端**********************************************************************************/#include<reg51.h>#include<intrins.h>
/************************************************************************************STC12C5A60S2内置AD转换器特殊功能寄存器功能说明*和地址定义,P1口用作输入端。************************************************************************************/
//ADC特殊功能寄存器sfr ADC_CONTR = 0xBC;sfr ADC_RES = 0xBD;sfr ADC_LOW2 = 0xBE;sfr P1ASF = 0x9D;
//定义ADC_CONTR的运行常数#define ADC_POWER 0x80 //AD电源控制位(电源开之后要加一个小的延时用以稳定电源)不用时可以关掉节能#define ADC_FLAG 0x10 //转换结束标志位,用以中断查询,一定要软件清0#define ADC_START 0x08 //开始转换控制位,置1开始转换,转换结束后为0#define ADC_SPEEDLL 0x00 //90时钟周期一次 21MHz时约为250KHz(该时钟是CPU内部RC震荡器产生的)#define ADC_SPEEDL 0x20 //180时钟周期#define ADC_SPEEDH 0x40 //360T#define ADC_SPEEDHH 0x60 //540T
sbit RS=P3^7;sbit RW=P3^6;sbit LCD_E=P2^7;#define uchar unsigned char#define uint unsigned intuchar code daima[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};//LCD1602 字符代码uchar code logo[]="TOHO_Voltmeter By SXL 2011-11 ";//LOGO 显示uchar code disp[]="The Voltage is :";unsigned long int m,i;uchar a=1;
/*************************************************************************************
*延时部分*需精确延时
*************************************************************************************/
/*延时子程序 小于大约 10 us 的延时*/void delay(uchar x){ uchar a,b; for(a=x;a>0;a--) for(b=17;b>0;b--);}
/*********延时大约1ms ***********/void delay1(uint x){ uint a,b; for(a=x;a>0;a--) for(b=1700;b>0;b--); }
/***********************************************************************************LCD 1602 显示部分 * 含读写驱动程序、初始化程序、时间日期星期温度显示程序、LOGO显示**********************************************************************************//*LCD1602读状态程序*/uchar ReadStatusLCD(void){ P0=0xff;//置高用于读取数据 RS=0; RW=1;//RW=1读取 delay(10); LCD_E=0; delay(10); LCD_E=1; while(P0&0x80);//检测忙信号 return(P0);}
/*LCD1602写数据程序*/void WriteDataLCD(uchar WDLCD){ ReadStatusLCD();//检测忙 P0=WDLCD; RS=1;//RS=1时写入数据 RW=0;//RW=0时写入 delay(10); LCD_E=1;//若晶振速度太高可以在这后加小的延时 delay(10); LCD_E=0;}
/*LCD1602液晶写指令程序*/void WriteCommandLCD(uchar WCLCD,BuysC){ if(BuysC) ReadStatusLCD();//根据需要检测忙 P0=WCLCD; RS=0; //写指令 RW=0; delay(10); LCD_E=1; delay(10); LCD_E=0;}
/*LCD 1602在指定位置显示一个字符程序*/void DisplayOneChar(uchar X,uchar Y,uchar DData){ if(Y<2) { Y&=0x01; X&=0xf;//限制X不能大于15,Y不能大于1 if(Y)X|=0x40;//当要显示第二行时地址码+0x40; X|=0x80;//算出指令码 WriteCommandLCD(X,1); WriteDataLCD(DData); }}
/*LOGO 显示*/void logo1(){ uchar a,b; for(b=0;b<2;b++) { for(a=0;a<16;a++) { DisplayOneChar(a,b,logo[a+16*b]); delay1(80); } } delay1(500);}/**************************LCD 1602 初始化程序******************/void LCD_init(void){ P0=0; WriteCommandLCD(0x38,0);//三次显示模式设置,不检测忙信号 delay(15); WriteCommandLCD(0x38,0); delay(15); WriteCommandLCD(0x38,0); delay(15); WriteCommandLCD(0x38,1);//显示模式设置,开始要求每次检测忙信号 WriteCommandLCD(0x08,1);//关闭显示 WriteCommandLCD(0x01,1);//显示清屏 WriteCommandLCD(0x06,1);//显示光标移动设置 WriteCommandLCD(0x0c,1);//显示开及光标设置 delay(200);}
/**************************ADC初始化程序***********************/void init_ADC(){ P1ASF=0x03; //P1.0作为模拟功能A/D使用 ADC_RES=0; //清ADC转换结果 ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ADC_START|0x01; delay1(5); IE=0xa0; //开AD中断和总中断}
void main(){ uchar a; LCD_init(); logo1(); LCD_init(); for(a=0;a<16;a++) { DisplayOneChar(a,0,disp[a]); } DisplayOneChar(10,1,'V'); DisplayOneChar(7,1,'.'); init_ADC(); while(1);}
/*********************AD中断服务程序**********************/void ADC_function() interrupt 5{ ADC_CONTR&=!ADC_FLAG; //软件清FLAG标志位 if(a==0) { i=ADC_RES; DisplayOneChar(6,1,daima[(m*i)/256/100]); DisplayOneChar(8,1,daima[((m*i)/256/10)%10]); DisplayOneChar(9,1,daima[((m*i)/256)%10]); ADC_CONTR&=!ADC_POWER; //关AD电源 delay1(100); } if(a==1) { m=84480/ADC_RES; } a++; if(a>1) a=0; ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ADC_START|a; delay1(5);}
最多设置5个标签!
/**********************************************************************************
* ToHo projetc Voltmeter 2011-11-13 电压表(精度约为0.02V) 参考电压取自3.3V IC
*P1.1接3.3V 稳压电源,P1.0为输入端
**********************************************************************************/
#include<reg51.h>
#include<intrins.h>
/**********************************************************************************
*
*STC12C5A60S2内置AD转换器特殊功能寄存器功能说明
*和地址定义,P1口用作输入端。
*
***********************************************************************************/
//ADC特殊功能寄存器
sfr ADC_CONTR = 0xBC;
sfr ADC_RES = 0xBD;
sfr ADC_LOW2 = 0xBE;
sfr P1ASF = 0x9D;
//定义ADC_CONTR的运行常数
#define ADC_POWER 0x80 //AD电源控制位(电源开之后要加一个小的延时用以稳定电源)不用时可以关掉节能
#define ADC_FLAG 0x10 //转换结束标志位,用以中断查询,一定要软件清0
#define ADC_START 0x08 //开始转换控制位,置1开始转换,转换结束后为0
#define ADC_SPEEDLL 0x00 //90时钟周期一次 21MHz时约为250KHz(该时钟是CPU内部RC震荡器产生的)
#define ADC_SPEEDL 0x20 //180时钟周期
#define ADC_SPEEDH 0x40 //360T
#define ADC_SPEEDHH 0x60 //540T
sbit RS=P3^7;
sbit RW=P3^6;
sbit LCD_E=P2^7;
#define uchar unsigned char
#define uint unsigned int
uchar code daima[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};//LCD1602 字符代码
uchar code logo[]="TOHO_Voltmeter By SXL 2011-11 ";//LOGO 显示
uchar code disp[]="The Voltage is :";
unsigned long int m,i;
uchar a=1;
/*************************************************************************************
*延时部分
*需精确延时
*************************************************************************************/
/*延时子程序 小于大约 10 us 的延时*/
void delay(uchar x)
{
uchar a,b;
for(a=x;a>0;a--)
for(b=17;b>0;b--);
}
/*********延时大约1ms ***********/
void delay1(uint x)
{
uint a,b;
for(a=x;a>0;a--)
for(b=1700;b>0;b--);
}
/*********************************************************************************
*
*LCD 1602 显示部分
* 含读写驱动程序、初始化程序、时间日期星期温度显示程序、LOGO显示
*
*********************************************************************************/
/*LCD1602读状态程序*/
uchar ReadStatusLCD(void)
{
P0=0xff;//置高用于读取数据
RS=0;
RW=1;//RW=1读取
delay(10);
LCD_E=0;
delay(10);
LCD_E=1;
while(P0&0x80);//检测忙信号
return(P0);
}
/*LCD1602写数据程序*/
void WriteDataLCD(uchar WDLCD)
{
ReadStatusLCD();//检测忙
P0=WDLCD;
RS=1;//RS=1时写入数据
RW=0;//RW=0时写入
delay(10);
LCD_E=1;//若晶振速度太高可以在这后加小的延时
delay(10);
LCD_E=0;
}
/*LCD1602液晶写指令程序*/
void WriteCommandLCD(uchar WCLCD,BuysC)
{
if(BuysC) ReadStatusLCD();//根据需要检测忙
P0=WCLCD;
RS=0; //写指令
RW=0;
delay(10);
LCD_E=1;
delay(10);
LCD_E=0;
}
/*LCD 1602在指定位置显示一个字符程序*/
void DisplayOneChar(uchar X,uchar Y,uchar DData)
{
if(Y<2)
{
Y&=0x01;
X&=0xf;//限制X不能大于15,Y不能大于1
if(Y)X|=0x40;//当要显示第二行时地址码+0x40;
X|=0x80;//算出指令码
WriteCommandLCD(X,1);
WriteDataLCD(DData);
}
}
/*LOGO 显示*/
void logo1()
{
uchar a,b;
for(b=0;b<2;b++)
{
for(a=0;a<16;a++)
{
DisplayOneChar(a,b,logo[a+16*b]);
delay1(80);
}
}
delay1(500);
}
/**************************LCD 1602 初始化程序******************/
void LCD_init(void)
{
P0=0;
WriteCommandLCD(0x38,0);//三次显示模式设置,不检测忙信号
delay(15);
WriteCommandLCD(0x38,0);
delay(15);
WriteCommandLCD(0x38,0);
delay(15);
WriteCommandLCD(0x38,1);//显示模式设置,开始要求每次检测忙信号
WriteCommandLCD(0x08,1);//关闭显示
WriteCommandLCD(0x01,1);//显示清屏
WriteCommandLCD(0x06,1);//显示光标移动设置
WriteCommandLCD(0x0c,1);//显示开及光标设置
delay(200);
}
/**************************ADC初始化程序***********************/
void init_ADC()
{
P1ASF=0x03; //P1.0作为模拟功能A/D使用
ADC_RES=0; //清ADC转换结果
ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ADC_START|0x01;
delay1(5);
IE=0xa0; //开AD中断和总中断
}
void main()
{
uchar a;
LCD_init();
logo1();
LCD_init();
for(a=0;a<16;a++)
{
DisplayOneChar(a,0,disp[a]);
}
DisplayOneChar(10,1,'V');
DisplayOneChar(7,1,'.');
init_ADC();
while(1);
}
/*********************AD中断服务程序**********************/
void ADC_function() interrupt 5
{
ADC_CONTR&=!ADC_FLAG; //软件清FLAG标志位
if(a==0)
{
i=ADC_RES;
DisplayOneChar(6,1,daima[(m*i)/256/100]);
DisplayOneChar(8,1,daima[((m*i)/256/10)%10]);
DisplayOneChar(9,1,daima[((m*i)/256)%10]);
ADC_CONTR&=!ADC_POWER; //关AD电源
delay1(100);
}
if(a==1)
{
m=84480/ADC_RES;
}
a++;
if(a>1) a=0;
ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ADC_START|a;
delay1(5);
}
一周热门 更多>