仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- /******引脚说明
- LCD液晶RS2.5 RW2.6 E2.7 DB0~DB7:P0.0~P0.7
- 电压测量P1.1;需要0~30v需要加分流电阻,,分辨率0.03v;
- 电流侧量P1.7;需要加放大电路如lm358;op07等,分辨率3ma
- **********/
- //stc12c5a60
- //时间20141107
- #include<STC12C5A60S2.h>
- #include<stdio.h>
- #include<intrins.h>//头文件
- #define uchar unsigned char//宏定义
- #define uint unsigned int//宏定义
- #define ulint unsigned long int//宏定义
- #define N 21//ADC中值滤波次数,必须为基数
- #define ISP_TRIG() ISP_TRIG=0x5A,ISP_TRIG=0xA5//ISP触发命令
- sbit rs=P3^5;//液晶RS
- sbit rw=P3^6;//液晶RW
- sbit e=P3^4;//液晶E
- void AD_init(void);//ADC初始化
- void delay(uint z);//延时函数
- uint AD_get(uchar haha );//读ADC的数值
- void LCD_data(uchar shuju);//写数据
- void zhiling(uchar zhilin);//写指令
- void LCD_init(void);//初始化LCD
- void tablex(uint tab);//数据分解
- uint filter(uchar dat);//中值滤波
- void timer_init(void);//定时器初始化
- uchar h1,h2,h3,h4;//LCD显示变量
- ulint mas,maz;//容量计算
- uchar table[]="0123456789";//显示数组
- uchar table1[]=".VAWa";
- void main()
- {
- ulint tempv,tempa;//存放电压电流值
- AD_init();//ADC初始化
- timer_init();//定时器初始化
- LCD_init();//LCD初始化
- while(1)
- {
- tempv=filter(0x88);//设置ADC通道0、开始转换
- tablex(tempv*3);//分解数据
- zhiling(0x80);//LCD地址
- LCD_data(table[h1]);//
- LCD_data(table[h2]);//
- LCD_data(table1[0]);//
- LCD_data(table[h3]);//
- LCD_data(table[h4]);//
- LCD_data(table1[1]);//显示
-
- tempa=filter(0x8f);//设置ADC通道7、开始转换
- if(tempa<=10)//防止数据成负数
- tempa=10;
- mas=tempa*3-30;//计算容量取样赋值
- tablex(tempa*3-30);//减去LM358失调的数值
- zhiling(0x88);//LCD地址
- LCD_data(table[h1]);
- LCD_data(table1[0]);
- LCD_data(table[h2]);
- LCD_data(table[h3]);
- LCD_data(table[h4]);
- LCD_data(table1[2]);
-
- tablex((tempv*3/10)*((tempa*3-30)/10)/10);//计算功率
- zhiling(0x80+0x40);
- LCD_data(table[h1]);
- LCD_data(table[h2]);
- LCD_data(table1[0]);
- LCD_data(table[h3]);
- LCD_data(table[h4]);
- LCD_data(table1[3]);
-
- tablex(maz/1000);//显示MAH
- zhiling(0x88+0x40);
- LCD_data(table[h1]);
- LCD_data(table1[0]);
- LCD_data(table[h2]);
- LCD_data(table[h3]);
- LCD_data(table[h4]);
- LCD_data(table1[4]);
-
- }
- }
- //-------------------------------------------------------------
- void delay(uint z)///////////////延时程序
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=19;y>0;y--);
- }
- void AD_init(void)/////////////////////初始化ADC
- {
- P1ASF=0xff;//P1口全部作为模拟功能AD使用
- ADC_RES=0;//清零转换结果寄存器高8位
- ADC_RESL=0;//清零转换结果寄存器低2位
- ADC_CONTR=0x80;//开启AD电源
- delay(5);//等待1ms,让AD电源稳定
- }
- uint AD_get(uchar haha )//ADC读数
- {
- uint rew;
- ADC_CONTR=haha;//开启AD转换
- _nop_(); _nop_(); _nop_(); _nop_();//要经过4个CPU时钟的延时
- while(!(ADC_CONTR&0x10));//等待转换完成
- ADC_CONTR&=0xe7;//关闭AD转换,ADC_FLAG位由软件清0
- rew=ADC_RES*4+ADC_RESL;//组合成10位
- delay(1);//等待
- return rew;//返回ADC值
- }
- void zhiling(uchar zhilin)//写指令
- {
- e=0;
- rs=0;
- rw=0;
- P0=zhilin;
- delay(20);
- e=1;
- delay(20);
- e=0;
- }
- void LCD_data(uchar shuju)//写数据
- {
- e=0;
- rs=1;
- rw=0;
- P0=shuju;
- delay(20);
- e=1;
- delay(20);
- e=0;
- }
- void LCD_init(void)//初始化LCD
- {
- delay(300);
- zhiling(0x38);
- delay(100);
- zhiling(0x38);
- delay(100);
- zhiling(0x38);
- delay(100);
- zhiling(0x38);
- zhiling(0x38);
- zhiling(0x08);
- zhiling(0x01);
- zhiling(0x06);
- zhiling(0x0c);
- }
- void tablex(uint tab1)//数据分解
- {
- h1=tab1/1000;//1023//1
- h2=tab1%1000/100;//023//0
- h3=tab1%100/10;//23//2
- h4=tab1%10;//3
- }
- uint filter(uchar dat)//中位值滤波
- {
- uint value_buf[N];
- uint count,i,j,temp;
- for(count=0;count<N;count++)
- {
- AD_init();//初始化ADC
- value_buf[count] = AD_get(dat);//读ADC数值
- delay(1);
- }
- for (j=0;j<N-1;j++)
- {
- for (i=0;i<N-j;i++)
- {
- if ( value_buf[i]>value_buf[i+1] )
- {
- temp = value_buf[i];
- value_buf[i] = value_buf[i+1];
- value_buf[i+1] = temp;
- }
- }
- }
- return value_buf[(N-1)/2];
- }
- void timer_init(void)//定时器初始化
- {
- TMOD=0x01;/////////设置工作方式1
- TH0=(65536-50000)/256;///////赋值
- TL0=(65536-50000)%256;
- EA=1;ET0=1;//开总中断;开定时器中断
- TR0=1;////////启动计数器
- }
- void timer0()interrupt 1 //定时中断
- {
- uchar t;
- TR0=0;
- TH0=(65536-50000)/256;///////赋初值
- TL0=(65536-50000)%256;
- t++;
- if(t==20)
- {
- t=0;
- maz+=(mas*1000)/3600;
- }
- TR0=1;
- }
复制代码
全部资料51hei下载地址:
单片机数字电压表.rar
(20.96 KB, 下载次数: 47)
|