仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include <reg52.h>
- #include <intrins.H>
- #include <math.H>
- #include <stdio.h>
- #define u8 unsigned char
- #define uchar unsigned char
- #define uint unsigned int
- #define u16 unsigned int
- #define uchar unsigned char
- #define uint unsigned int
- float dianliu1,dianliu2,dianya;
- uchar dianji=0;
- sbit LCD_RS = P2^4; //液晶1602 RS端口
- sbit LCD_RW = P2^5; //液晶1602 RS端口
- sbit LCD_EP = P2^6; //液晶1602 EN端口
- sbit key1 = P3^0;
- sbit key2 = P3^1;
- sbit key3 = P1^0;
- sbit key4 = P1^1;
- sbit led = P1^2;
- sbit fmq = P1^4; //
- int dianliumax = 90,dianyamax =30;
- uchar code table[] = {" A1=100A V=13 V"}; //设定速度初始化
- uchar code table1[] = {" A0=100A V=22 V"}; // 动态显示初始化
- uchar n , i,x,table2[5],table3[5],ge,shi,bai,flag1,key1n,temp;
- unsigned char x=1 ;
- void init();
- void display_val(unsigned int zhuan);
- unsigned int flag_aa;
- /***********延时1MS程序***/
- void delay(uint z)
- { uint x,y;
- for(x=z;x>0;x--)
- for(y=80;y>0;y--);
- }
- /******液晶写命令************/
- void write_com(uchar com)
- { LCD_RS=0;
-
- P0=com ;
- // delay(1);
- LCD_EP=1;
- delay(1);
- LCD_EP=0;
- }
- /*****************/
- /********液晶写数据***********/
- void write_data(uchar date)
- { LCD_RS=1;
-
- P0=date ;
- //delay(1);
- LCD_EP=1;
- delay(1);
- LCD_EP=0;
- }
- /*****************************/
- void dis1(int z,unsigned int zhua,int x,int y)
- {
-
- table2[0]=zhua/10000+0x30; //取万位
- table2[1]=(zhua%10000)/1000+0x30; //取千位
- table2[2]=(zhua%1000)/100+0x30; //取百位
- table2[3]=(zhua%100)/10+0x30; //取十位
- table2[4]=zhua%10+0x30; //取个位
- if(z==1)
- write_com(0x80+x);
- if(z==2)
- write_com(0x80+0x40+x);
- // write_data(table2[0]);
- // write_data(table2[1]);
- write_data(table2[3]);
- if(y==1)
- write_data('.');
- write_data(table2[4]);
- if(y==2)
- write_data('.');
- write_data(table2[5]);
- write_com(0x80+16);
-
-
- }
- void dis(int z,unsigned int zhua,int x,int y)
- {
-
- table2[0]=zhua/10000+0x30; //取万位
- table2[1]=(zhua%10000)/1000+0x30; //取千位
- table2[2]=(zhua%1000)/100+0x30; //取百位
- table2[3]=(zhua%100)/10+0x30; //取十位
- table2[4]=zhua%10+0x30; //取个位
- if(z==1)
- write_com(0x80+x);
- if(z==2)
- write_com(0x80+0x40+x);
- // write_data(table2[0]);
- // write_data(table2[1]);
- write_data(table2[2]);
- if(y==1)
- write_data('.');
- write_data(table2[3]);
- if(y==2)
- write_data('.');
- write_data(table2[4]);
- write_com(0x80+16);
-
-
- }
- /*--------------------------液晶初始化-----------------------------*/
- void init_lcd()
- {
- LCD_EP=0;
- write_com(0x38);
- write_com(0x08);
- write_com(0x06);
- write_com(0x0c);
- write_com(0x01);
- //初始化显示
- write_com(0x80);
- for(i=0;i<16;i++)
- {
- write_data(table[i]);
- delay(3);
- }
- write_com(0x80+0x40);
- for(i=0;i<16;i++)
- {
- write_data(table1[i]);
- delay(3);
- }
- }
- void uart(void) //串口通信初始化
- {
- SCON=0x50; //串口通信工作方式1
- REN=1; //允许接收
- TMOD=0x20; //定时器1的工作方式2
- TH1=0xfd,TL1=0xfd;
- TI=1; //这里一定要注意
- TR1=1; //打开定时器
- }
- void init()
- {
- TMOD=0X10; //定时器工作方式1
- TH1=0XFF; //100us定时,装入初值
- TL1=0XA4;
- TR1=1; //启动T1工作
- ET1=1; //允许T1中断
- EA =1; //开总中断
- }
- int max(int a,int b,int c)
- {
- return (a>b?a:b)>c?(a>b?a:b):c;
- }
-
-
- /***********************************************************************************************************
- ADC0832相关函数
- ***********************************************************************************************************/
- sbit ADCS =P1^5; //ADC0832 片选
- sbit ADCLK =P1^7; //ADC0832 时钟
- sbit ADDI =P1^6; //ADC0832 数据输入 /*因为单片机的管脚是双向的,且ADC0832的数据输入输出不同时进行,
- sbit ADDO =P1^6; //ADC0832 数据输出 /*为节省单片机引脚,简化电路所以输入输出连接在同一个引脚上
- //========================================================================
- unsigned int Adc0832(unsigned char channel)
- {
- uchar i=0;
- uchar j;
- uint dat=0;
- uchar ndat=0;
- uchar Vot=0;
- if(channel==0)channel=2;
- if(channel==1)channel=3;
- ADDI=1;
- _nop_();
- _nop_();
- ADCS=0;//拉低CS端
- _nop_();
- _nop_();
- ADCLK=1;//拉高CLK端
- _nop_();
- _nop_();
- ADCLK=0;//拉低CLK端,形成下降沿1
- _nop_();
- _nop_();
- ADCLK=1;//拉高CLK端
- ADDI=channel&0x1;
- _nop_();
- _nop_();
- ADCLK=0;//拉低CLK端,形成下降沿2
- _nop_();
- _nop_();
- ADCLK=1;//拉高CLK端
- ADDI=(channel>>1)&0x1;
- _nop_();
- _nop_();
- ADCLK=0;//拉低CLK端,形成下降沿3
- ADDI=1;//控制命令结束
- _nop_();
- _nop_();
- dat=0;
- for(i=0;i<8;i++)
- {
- dat|=ADDO;//收数据
- ADCLK=1;
- _nop_();
- _nop_();
- ADCLK=0;//形成一次时钟脉冲
- _nop_();
- _nop_();
- dat<<=1;
- if(i==7)dat|=ADDO;
- }
- for(i=0;i<8;i++)
- {
- j=0;
- j=j|ADDO;//收数据
- ADCLK=1;
- _nop_();
- _nop_();
- ADCLK=0;//形成一次时钟脉冲
- _nop_();
- _nop_();
- j=j<<7;
- ndat=ndat|j;
- if(i<7)ndat>>=1;
- }
- ADCS=1;//拉低CS端
- ADCLK=0;//拉低CLK端
- ADDO=1;//拉高数据端,回到初始状态
- dat<<=8;
- dat|=ndat;
- return(dat); //return ad data
- }
- /***********************************************************************************************************
- ADC0832相关函数
- ***********************************************************************************************************/
- sbit ADCS2 =P3^7; //ADC0832 片选
- sbit ADCLK2 =P3^6; //ADC0832 时钟
- sbit ADDI2 =P3^5; //ADC0832 数据输入 /*因为单片机的管脚是双向的,且ADC0832的数据输入输出不同时进行,
- sbit ADDO2 =P3^5; //ADC0832 数据输出 /*为节省单片机引脚,简化电路所以输入输出连接在同一个引脚上
- //========================================================================
- unsigned int Adc08322(unsigned char channel)
- {
- uchar i=0;
- uchar j;
- uint dat=0;
- uchar ndat=0;
- uchar Vot=0;
- if(channel==0)channel=2;
- if(channel==1)channel=3;
- ADDI2=1;
- _nop_();
- _nop_();
- ADCS2=0;//拉低CS端
- _nop_();
- _nop_();
- ADCLK2=1;//拉高CLK端
- _nop_();
- _nop_();
- ADCLK2=0;//拉低CLK端,形成下降沿1
- _nop_();
- _nop_();
- ADCLK2=1;//拉高CLK端
- ADDI2=channel&0x1;
- _nop_();
- _nop_();
- ADCLK2=0;//拉低CLK端,形成下降沿2
- _nop_();
- _nop_();
- ADCLK2=1;//拉高CLK端
- ADDI2=(channel>>1)&0x1;
- _nop_();
- _nop_();
- ADCLK2=0;//拉低CLK端,形成下降沿3
- ADDI2=1;//控制命令结束
- _nop_();
- _nop_();
- dat=0;
- for(i=0;i<8;i++)
- {
- dat|=ADDO2;//收数据
- ADCLK2=1;
- _nop_();
- _nop_();
- ADCLK2=0;//形成一次时钟脉冲
- _nop_();
- _nop_();
- dat<<=1;
- if(i==7)dat|=ADDO2;
- }
- for(i=0;i<8;i++)
- {
- j=0;
- j=j|ADDO2;//收数据
- ADCLK2=1;
- _nop_();
- _nop_();
- ADCLK2=0;//形成一次时钟脉冲
- _nop_();
- _nop_();
- j=j<<7;
- ndat=ndat|j;
- if(i<7)ndat>>=1;
- }
- ADCS2=1;//拉低CS端
- ADCLK2=0;//拉低CLK端
- ADDO2=1;//拉高数据端,回到初始状态
- dat<<=8;
- dat|=ndat;
- return(dat); //return ad data
- }
- void key()
- {
- if(key1 == 0)
- {
- delay(50);
- dianliumax ++;
- if( dianliumax >999)
- dianliumax = 999;
- }
- if(key2 == 0)
- {
- delay(50);
- dianliumax --;
- if( dianliumax < 1)
- dianliumax = 1;
- }
-
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
Keil代码与Proteus仿真下载:
电压电流检测仿真.7z
(71.91 KB, 下载次数: 283)
|