单片机教程网

电脑版
提示:原网页已由神马搜索转码, 内容由www.51hei.com提供.
查看:206|回复:0
打印上一主题下一主题

基于51单片机的电参数终端采集控制设计 程序Proteus仿真图

[复制链接]
跳转到指定楼层
楼主
ID:316613发表于 2024-7-10 09:03|只看该作者|只看大图回帖奖励
仿真  程序  .需要 原理图设计,自己设计,免费开源  回馈51黑论坛坛友
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)



设计基于MCS-51的单相工频交流电参数检测仪。交流有效值0-220V,电流有效值0-40A。电压、电流值经电压、电流传感器输出有效值为0-5V的交流信号,传感器输出的电压、电流信号与被测电压、电流同相位。 基本要求如下 (1) 电流、电压测量精度0.1% (2) 检测电压、电流的相位角,求出功率因素 (3) 电流、电压有效值由LED轮流显示,也可由按键切换显示量


单片机源程序如下:
  1. #include<regx51.h>
  2. #include<intrins.h>
  3. #include<absacc.h>
  4. #include<math.h>
  5. #define uchar unsigned char
  6. #define uint unsigned int
  7. #define addo (5.0/65535.0)
  8. uchar vol[]="Voltage:";//定义串口通信的电压提示语
  9. uchar cur[]="Current:";//定义串口通信的电流提示语  
  10. uchar pf[]="Power Factor:";//定义串口通信的功率因数提示语
  11. uchar num[10]={'0','1','2','3','4','5','6','7','8','9'};//定义串口通信的数字字符查表传送  
  12. sbit DIN = P2^0;
  13. sbit CS = P2^1;
  14. sbit CLK = P2^2;
  15. sbit SDO = P2^3;
  16. sbit SCK = P2^4;
  17. sbit CONV = P2^5;
  18. sbit SDI=P2^6;
  19. uint High,Low;  
  20. sbit K=P3^2;
  21. bit choose=1;//定义A/D转换器通道选择变量
  22. double t=0;    
  23. static unsigned char disbuf[8] = {1,2,3,4,5,6,7,8};//数码管显示缓冲数据
  24. /*延时函数*/
  25. void delay_ms(uint n)
  26. {
  27.        uchar i;
  28.        while(n--)
  29.        {
  30.            for(i=0;i<100;i++);
  31.        }
  32. }
  33. /*定时器T0初始化 */
  34. void Init_T0()  
  35. {  
  36.        TMOD=0x09;  
  37.        TH0=0;  
  38.        TL0=0;  
  39. }  
  40. /*数码管进行显示*/
  41. void WriteByte(uchar dat)
  42. {
  43.        uchar i;
  44.        for(i=0;i<8;i++)
  45.        {
  46.            DIN = ((dat<<i)&0x80)?1:0;
  47.            CLK = 0;
  48.            _nop_();
  49.            CLK = 1;
  50.            _nop_();
  51.        }
  52. }
  53. void MAX7221_WRITE(uchar addr,uchar dat)
  54. {
  55.        CS = 0;
  56.        WriteByte(addr);
  57.        WriteByte(dat);
  58.        CS = 1;
  59. }
  60. void MAX7221_Initial(void)
  61. {
  62.        MAX7221_WRITE(0x0A,0x07);
  63.        MAX7221_WRITE(0x0B,0x07);
  64.        MAX7221_WRITE(0x0C,0x01);
  65.        MAX7221_WRITE(0x0F,0x00);
  66.        MAX7221_WRITE(0x09,0xff);
  67. }
  68. void display(uchar *str)
  69. {
  70.        uchar i;
  71.        for(i=0;i<8;i++)
  72.        {
  73.            MAX7221_WRITE(i+1,str[i]);
  74.        }
  75. }
  76. /*A/D转换读取转换值*/
  77. uint LTC1864_READ(void)
  78. {
  79.        uchar i;
  80.        uint temp = 0;
  81.        CONV = 0;
  82.        CONV = 1;
  83.        _nop_();_nop_();_nop_();
  84.        CONV = 0;
  85.        SDO = 1;
  86.        for(i=0;i<16;i++)
  87.        {
  88.            SCK = 1;
  89.            _nop_();
  90.            SCK = 0;
  91.            _nop_();
  92.            if(i==0)
  93.            {
  94.                  SDI=1;
  95.            }
  96.            if(i==1)
  97.            {
  98.                  choose=       !choose;
  99.                  SDI=choose;
  100.            }
  101.            temp<< = 1;
  102.            if(SDO==1)
  103.            {

  104.                  temp |= 0x0001;
  105.            }
  106.        }
  107.        CONV = 1;
  108.        return temp;
  109. }
  110. /*电流值进行数码管转换显示*/
  111. void HEXTOBCD_I(uint temp)
  112. {
  113.        disbuf[0] = temp/10000;
  114.        disbuf[1] = (temp%10000/1000)|0x80;
  115.        disbuf[2] = temp%1000/100;
  116.        disbuf[3] = temp%100/10;
  117.        disbuf[4] = temp%10;
  118.        disbuf[5] = 15;
  119.        disbuf[6] = 15;
  120.        disbuf[7] = 1;
  121. }
  122. /*电压值进行数码管转换显示*/
  123. void HEXTOBCD_V(uint temp)
  124. {
  125.        disbuf[0] = temp/10000;
  126.        disbuf[1] = temp%10000/1000;
  127.        disbuf[2] = (temp%1000/100)|0x80;
  128.        disbuf[3] = temp%100/10;
  129.        disbuf[4] = temp%10;
  130.        disbuf[5] = 15;
  131.        disbuf[6] = 15;
  132.        disbuf[7] = 2;
  133. }
  134. /*定时器T1初始化*/
  135. void Time_T1(void)
  136. {
  137.        TMOD=0x10;
  138.        TL1=0xb0;
  139.        TH1=0x3c;
  140.        IE=0x88;
  141.        TR1=1;
  142. }
  143. void delay_choose(int t)
  144. {
  145.        Time_T1();
  146.        while(t--)
  147.        {
  148.            while(!TF1);
  149.            TF1=0;
  150.            TL1=0x3c;
  151.            TH1=0X88;

  152.        }
  153. }
  154. /*读取相位差方波正脉冲宽度*/
  155. void Message_Width()  
  156. {  
  157.        while(K);  
  158.        TR0=1;  
  159.        while(!K);  
  160.        while(K);  
  161.        TR0=0;  
  162.        High=TH0;  
  163.        Low=TL0;  
  164. }  
  165. /*串口初始化波特率为9600*/  
  166. void UART_init(void)  
  167. {  
  168.    SCON = 0x50;//串口方式1  
  169.    TMOD = 0x20;// 定时器使用方式2自动重载  
  170.    TH1 = 0xFD;//9600波特率对应的预设数,定时器方式2下,TH1=TL1  
  171.    TL1 = 0xFD;  
  172.    TR1 = 1;//开启定时器,开始产生波特率  
  173. }  
  174. /*发送一个字符*/  
  175. void UART_send_byte(uchar dat)  
  176. {  
  177.        SBUF = dat;      
  178.        while (TI == 0);  
  179.        TI = 0;  
  180. }  
  181. /*发送一个字符串*/  
  182. void UART_send_string(uchar *buf)  
  183. {  
  184.        while (*buf != '\0')  
  185.        {  
  186.            UART_send_byte(*buf++);  
  187.        }  
  188. }  
  189. /*电流显示及发送*/
  190. void dianliu()
  191. {
  192.        uchar vol_value[7];//定义串口通信数据缓冲数组
  193.        uint I;
  194.        I=(int)(t*30500);
  195.        HEXTOBCD_I(I);
  196.        display(disbuf);
  197.        delay_ms(10);
  198.        /*串口通信逐一发送电流值*/
  199.        UART_init();
  200.        UART_send_string(cur);
  201.        vol_value[0]=num[disbuf[0]%16];
  202.        UART_send_byte(vol_value[0]);
  203.        vol_value[1]=num[disbuf[1]%16];
  204.        UART_send_byte(vol_value[1]);
  205.        UART_send_byte(0x2E);
  206.        vol_value[2]=num[disbuf[2]%16];
  207.        UART_send_byte(vol_value[2]);
  208.        vol_value[3]=num[disbuf[3]%16];
  209.        UART_send_byte(vol_value[3]);
  210.        vol_value[4]=num[disbuf[4]%16];
  211.        UART_send_byte(vol_value[4]);
  212.        UART_send_byte(0x41);
  213.        UART_send_byte(0x0d);
  214.        UART_send_byte(0x0a);
  215. }
  216. /*电压显示及发送*/
  217. void dianya()
  218. {
  219.        int I;
  220.        uchar vol_value[7];//定义串口通信数据缓冲数组
  221.       
  222.        I=(int)(t*5866);
  223.        HEXTOBCD_V(I);
  224.        display(disbuf);
  225.        delay_ms(10);
  226.        /*串口通信逐一发送电压值*/
  227.        UART_init();
  228.        UART_send_string(vol);
  229.        vol_value[0]=num[disbuf[0]%16];
  230.        UART_send_byte(vol_value[0]);
  231.        vol_value[1]=num[disbuf[1]%16];
  232.        UART_send_byte(vol_value[1]);
  233.        vol_value[2]=num[disbuf[2]%16];
  234.        UART_send_byte(vol_value[2]);
  235.        UART_send_byte(0x2E);
  236.        vol_value[3]=num[disbuf[3]%16];
  237.        UART_send_byte(vol_value[3]);
  238.        vol_value[4]=num[disbuf[4]%16];
  239.        UART_send_byte(vol_value[4]);
  240.        UART_send_byte(0x56);
  241.        UART_send_byte(0x0d);
  242.        UART_send_byte(0x0a);
  243. }
  244. /*串口通信发送功率因数*/
  245. void send_P()
  246. {
  247.        uchar vol_value[7];//定义串口通信数据缓冲数组
  248.        uint X1,I;
  249.        double t=0;
  250.        Init_T0();
  251.        Message_Width();  
  252.        X1=(High*256+TL0)/0.92;
  253.        t=(X1+t)/2;
  254.    /*串口通信逐一发送功率因数*/
  255.        t=t*0.000314;
  256.        I=abs(cos(t-0.147)*1000);
  257.        UART_init();
  258.        UART_send_string(pf);
  259.        vol_value[0]=num[I/1000];
  260.        UART_send_byte(vol_value[0]);
  261.        UART_send_byte(0x2E);
  262.        vol_value[0]=num[I%1000/100];
  263.        UART_send_byte(vol_value[0]);
  264.        vol_value[0]=num[I%100/10];
  265.        UART_send_byte(vol_value[0]);
  266.        vol_value[0]=num[I%10];
  267.        UART_send_byte(vol_value[0]);
  268.        UART_send_byte(0x0d);
  269.        UART_send_byte(0x0a);
  270.        UART_send_byte(0x0d);
  271.        UART_send_byte(0x0a);
  272. }
  273. void main()
  274. {
  275.        Time_T1();
  276.        MAX7221_Initial();
  277.        delay_ms(10);
  278.        LTC1864_READ();
  279.        while(1)
  280.        {
  281.            delay_ms(1000);
  282.            t= LTC1864_READ()*addo;//读取电流模拟量
  283.            dianliu();
  284.            delay_ms(1000);//延时2s
  285.            t= LTC1864_READ()*addo;//读取电压模拟量
  286.            delay_choose(40);
  287.            dianya();
  288.            send_P();
  289.            delay_choose(40);//延时2s
  290.        }
  291. }
复制代码

仿真程序和原理图下载: 基于51单片机的电参数终端采集控制设计.7z(1.49 MB, 下载次数: 17)

评分

黑币 +50
收起理由
+ 50
共享资料的黑币奖励!

查看全部评分

手机版|小黑屋|51黑电子论坛|51黑电子论坛6群QQ管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网