仿真 程序 .需要 原理图设计,自己设计,免费开源 回馈51黑论坛坛友
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
设计基于MCS-51的单相工频交流电参数检测仪。交流有效值0-220V,电流有效值0-40A。电压、电流值经电压、电流传感器输出有效值为0-5V的交流信号,传感器输出的电压、电流信号与被测电压、电流同相位。 基本要求如下 (1) 电流、电压测量精度0.1% (2) 检测电压、电流的相位角,求出功率因素 (3) 电流、电压有效值由LED轮流显示,也可由按键切换显示量
单片机源程序如下:
- #include<regx51.h>
- #include<intrins.h>
- #include<absacc.h>
- #include<math.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define addo (5.0/65535.0)
- uchar vol[]="Voltage:";//定义串口通信的电压提示语
- uchar cur[]="Current:";//定义串口通信的电流提示语
- uchar pf[]="Power Factor:";//定义串口通信的功率因数提示语
- uchar num[10]={'0','1','2','3','4','5','6','7','8','9'};//定义串口通信的数字字符查表传送
- sbit DIN = P2^0;
- sbit CS = P2^1;
- sbit CLK = P2^2;
- sbit SDO = P2^3;
- sbit SCK = P2^4;
- sbit CONV = P2^5;
- sbit SDI=P2^6;
- uint High,Low;
- sbit K=P3^2;
- bit choose=1;//定义A/D转换器通道选择变量
- double t=0;
- static unsigned char disbuf[8] = {1,2,3,4,5,6,7,8};//数码管显示缓冲数据
- /*延时函数*/
- void delay_ms(uint n)
- {
- uchar i;
- while(n--)
- {
- for(i=0;i<100;i++);
- }
- }
- /*定时器T0初始化 */
- void Init_T0()
- {
- TMOD=0x09;
- TH0=0;
- TL0=0;
- }
- /*数码管进行显示*/
- void WriteByte(uchar dat)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- DIN = ((dat<<i)&0x80)?1:0;
- CLK = 0;
- _nop_();
- CLK = 1;
- _nop_();
- }
- }
- void MAX7221_WRITE(uchar addr,uchar dat)
- {
- CS = 0;
- WriteByte(addr);
- WriteByte(dat);
- CS = 1;
- }
- void MAX7221_Initial(void)
- {
- MAX7221_WRITE(0x0A,0x07);
- MAX7221_WRITE(0x0B,0x07);
- MAX7221_WRITE(0x0C,0x01);
- MAX7221_WRITE(0x0F,0x00);
- MAX7221_WRITE(0x09,0xff);
- }
- void display(uchar *str)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- MAX7221_WRITE(i+1,str[i]);
- }
- }
- /*A/D转换读取转换值*/
- uint LTC1864_READ(void)
- {
- uchar i;
- uint temp = 0;
- CONV = 0;
- CONV = 1;
- _nop_();_nop_();_nop_();
- CONV = 0;
- SDO = 1;
- for(i=0;i<16;i++)
- {
- SCK = 1;
- _nop_();
- SCK = 0;
- _nop_();
- if(i==0)
- {
- SDI=1;
- }
- if(i==1)
- {
- choose= !choose;
- SDI=choose;
- }
- temp <<= 1;
- if(SDO==1)
- {
- temp |= 0x0001;
- }
- }
- CONV = 1;
- return temp;
- }
- /*电流值进行数码管转换显示*/
- void HEXTOBCD_I(uint temp)
- {
- disbuf[0] = temp/10000;
- disbuf[1] = (temp%10000/1000)|0x80;
- disbuf[2] = temp%1000/100;
- disbuf[3] = temp%100/10;
- disbuf[4] = temp%10;
- disbuf[5] = 15;
- disbuf[6] = 15;
- disbuf[7] = 1;
- }
- /*电压值进行数码管转换显示*/
- void HEXTOBCD_V(uint temp)
- {
- disbuf[0] = temp/10000;
- disbuf[1] = temp%10000/1000;
- disbuf[2] = (temp%1000/100)|0x80;
- disbuf[3] = temp%100/10;
- disbuf[4] = temp%10;
- disbuf[5] = 15;
- disbuf[6] = 15;
- disbuf[7] = 2;
- }
- /*定时器T1初始化*/
- void Time_T1(void)
- {
- TMOD=0x10;
- TL1=0xb0;
- TH1=0x3c;
- IE=0x88;
- TR1=1;
- }
- void delay_choose(int t)
- {
- Time_T1();
- while(t--)
- {
- while(!TF1);
- TF1=0;
- TL1=0x3c;
- TH1=0X88;
- }
- }
- /*读取相位差方波正脉冲宽度*/
- void Message_Width()
- {
- while(K);
- TR0=1;
- while(!K);
- while(K);
- TR0=0;
- High=TH0;
- Low=TL0;
- }
- /*串口初始化波特率为9600*/
- void UART_init(void)
- {
- SCON = 0x50;//串口方式1
- TMOD = 0x20;// 定时器使用方式2自动重载
- TH1 = 0xFD;//9600波特率对应的预设数,定时器方式2下,TH1=TL1
- TL1 = 0xFD;
- TR1 = 1;//开启定时器,开始产生波特率
- }
- /*发送一个字符*/
- void UART_send_byte(uchar dat)
- {
- SBUF = dat;
- while (TI == 0);
- TI = 0;
- }
- /*发送一个字符串*/
- void UART_send_string(uchar *buf)
- {
- while (*buf != '\0')
- {
- UART_send_byte(*buf++);
- }
- }
- /*电流显示及发送*/
- void dianliu()
- {
- uchar vol_value[7];//定义串口通信数据缓冲数组
- uint I;
- I=(int)(t*30500);
- HEXTOBCD_I(I);
- display(disbuf);
- delay_ms(10);
- /*串口通信逐一发送电流值*/
- UART_init();
- UART_send_string(cur);
- vol_value[0]=num[disbuf[0]%16];
- UART_send_byte(vol_value[0]);
- vol_value[1]=num[disbuf[1]%16];
- UART_send_byte(vol_value[1]);
- UART_send_byte(0x2E);
- vol_value[2]=num[disbuf[2]%16];
- UART_send_byte(vol_value[2]);
- vol_value[3]=num[disbuf[3]%16];
- UART_send_byte(vol_value[3]);
- vol_value[4]=num[disbuf[4]%16];
- UART_send_byte(vol_value[4]);
- UART_send_byte(0x41);
- UART_send_byte(0x0d);
- UART_send_byte(0x0a);
- }
- /*电压显示及发送*/
- void dianya()
- {
- int I;
- uchar vol_value[7];//定义串口通信数据缓冲数组
-
- I=(int)(t*5866);
- HEXTOBCD_V(I);
- display(disbuf);
- delay_ms(10);
- /*串口通信逐一发送电压值*/
- UART_init();
- UART_send_string(vol);
- vol_value[0]=num[disbuf[0]%16];
- UART_send_byte(vol_value[0]);
- vol_value[1]=num[disbuf[1]%16];
- UART_send_byte(vol_value[1]);
- vol_value[2]=num[disbuf[2]%16];
- UART_send_byte(vol_value[2]);
- UART_send_byte(0x2E);
- vol_value[3]=num[disbuf[3]%16];
- UART_send_byte(vol_value[3]);
- vol_value[4]=num[disbuf[4]%16];
- UART_send_byte(vol_value[4]);
- UART_send_byte(0x56);
- UART_send_byte(0x0d);
- UART_send_byte(0x0a);
- }
- /*串口通信发送功率因数*/
- void send_P()
- {
- uchar vol_value[7];//定义串口通信数据缓冲数组
- uint X1,I;
- double t=0;
- Init_T0();
- Message_Width();
- X1=(High*256+TL0)/0.92;
- t=(X1+t)/2;
- /*串口通信逐一发送功率因数*/
- t=t*0.000314;
- I=abs(cos(t-0.147)*1000);
- UART_init();
- UART_send_string(pf);
- vol_value[0]=num[I/1000];
- UART_send_byte(vol_value[0]);
- UART_send_byte(0x2E);
- vol_value[0]=num[I%1000/100];
- UART_send_byte(vol_value[0]);
- vol_value[0]=num[I%100/10];
- UART_send_byte(vol_value[0]);
- vol_value[0]=num[I%10];
- UART_send_byte(vol_value[0]);
- UART_send_byte(0x0d);
- UART_send_byte(0x0a);
- UART_send_byte(0x0d);
- UART_send_byte(0x0a);
- }
- void main()
- {
- Time_T1();
- MAX7221_Initial();
- delay_ms(10);
- LTC1864_READ();
- while(1)
- {
- delay_ms(1000);
- t= LTC1864_READ()*addo;//读取电流模拟量
- dianliu();
- delay_ms(1000);//延时2s
- t= LTC1864_READ()*addo;//读取电压模拟量
- delay_choose(40);
- dianya();
- send_P();
- delay_choose(40);//延时2s
- }
- }
复制代码
仿真程序和原理图下载:
基于51单片机的电参数终端采集控制设计.7z
(1.49 MB, 下载次数: 20)
|