是本人初學51時制作的自動調壓電路,設計上比較笨拙,僅供參考,參考莫笑!有單片機程序原理圖!
制作出來的實物圖如下:
800911408800874695.jpg (2.49 MB, 下載次數: 60)
下載附件
實物圖
2018-12-21 09:56 上傳
電路原理圖如下:
0.png (109.51 KB, 下載次數: 68)
下載附件
2018-12-21 15:31 上傳
變壓轉換詳表
220V變24V電壓比:9.166
0.png (25.39 KB, 下載次數: 69)
下載附件
2018-12-21 15:32 上傳
輸入電壓低于160VLED亮,控口P1.1
輸入電壓高于260VLED亮,無輸出
單片機源程序如下:
- #include <stc12c2052ad.h>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define AD_SPEED 0x60 //0000,0000 1080個時鐘周期轉換一次,
- #define nop _nop_()
- //
- sbit v16=P1^1;
- sbit v17=P1^2 ;
- sbit v18=P1^3;
- sbit v19=P1^4 ;
- sbit v20=P1^5 ;
- sbit v21=P1^6 ;
- sbit v22=P1^7 ;
- sbit v23=P3^7 ;
- sbit v24=P3^5;
- sbit v25=P3^4;
- sbit led16=P3^3;
- sbit led25=P3^2;
- /****************************************************************/
- void delayms(uint);
- int ADC();
- void InitADC();
- float voltage=0.0;
- uint vac,V=0.0,V1=0.0,V2;
- float vdc=0.00 ;
- void kaig();
- /***8**************************************************************/
- void main()
- {
- InitADC();
- delayms(1500);
- while (1)
- {
- WDT_CONTR=0x34;
-
- delayms(100);
- V2=ADC();
- delayms(10);
- vdc= V2/256.00*5.00 ;//單片機最高是5伏模擬電壓
- if ((vdc>3.78)||(vdc<1.85)) //acv=269.35 acv=131.8
- {
- P1=0XFF;
- P3=0XFF;
- led25=0;
- led16=0;
- break;
- }
- else
- {
- if (V2<107) //vdc=2.0865 acv=148.68
- led16=~led16;
- if (V2>187) //vdc=3.6465 acv=259.8
- led25=~led25;
- delayms(100);
- kaig();
- }
-
-
- }
- }
- /////////////////////////////
- void kaig()
- {
- if (vdc<=2.31)
-
- {
-
- vac=16;
- led16=0;
- }
-
- if (2.31<vdc&&vdc<=2.45)
-
- vac=17;
-
- if (2.45<vdc&&vdc<=2.59)
-
- vac=18;
- if (2.59<vdc&&vdc<=2.73)
-
- vac=19;
-
- if (2.73<vdc&&vdc<=2.87)
-
- vac=20;
-
- if (2.87<vdc&&vdc<=3.01)
-
- vac=21;
-
- if (3.01<vdc&&vdc<=3.15)
-
- vac=22;
- if (3.15<vdc&&vdc<=3.29)
-
- vac=23;
-
- if (3.29<vdc&&vdc<=3.43)
-
- vac=24;
-
- if (3.43<vdc&&vdc<=3.57)
- vac=25;
-
- if (vdc>3.57)
- {
- vac=25;
- led25=0;
- }
- switch(vac)
- {
-
- case 16:
- if (v16==0)
- break;
- else
- {
-
- P1=0XFF;
- P3=0XFF;
- v16=0;
- }
- break;
- case 17:
- if (v17==0)
- break;
- else
- {
- P1=0XFF;
- P3=0XFF;
- v17=0;
- }
- break;
- case 18:
- if(v18==0)
- break;
- else
- {
- P1=0XFF;
- P3=0XFF;
- v18=0;
- }
- break;
- case 19:
- if(v19==0)
- break;
- else
- {
- P1=0XFF;
- P3=0XFF;
- v19=0;
- }
- break;
- case 20:
- if(v20==0)
- break;
- else
- {
- P1=0XFF;
- P3=0XFF;
- v20=0;
- }
- break;
- case 21:
- if(v21==0)
- break ;
- else
- {P1=0XFF;
- P3=0XFF;
- v21=0;
-
- }
- break;
- case 22:
- if(v22==0)
- nop;
- else
- {
- P1=0XFF;
- P3=0XFF;
- v22=0;
- }
- break;
- case 23:
- if(v23==0)
- break;
- else
- {
- P1=0XFF;
- P3=0XFF;
- v23=0;
- }
- break;
- case 24:
- if(v24==0)
- break;
- else
- {
- P1=0XFF;
- P3=0XFF;
- v24=0;
- }
- break;
- case 25:
- if(v25==0)
- break;
- else
- {
- P1=0XFF;
- P3=0XFF;
- v25=0;
- }
- break;
-
- }
-
-
-
- }
- /*void UartInit() //9600bps@11.0592MHz
- {
- PCON &= 0x7f; //波特率不倍速
- SCON = 0x50; //8位數據,可變波特率
- AUXR |= 0x40; //定時器1時鐘為Fosc,即1T
- AUXR &= 0xfe; //串口1選擇定時器1為波特率發生器
- TMOD &= 0x0f; //清除定時器1模式位
- TMOD |= 0x20; //設定定時器1為8位自動重裝方式
- TL1 = 0xDC; //設定定時初值
- TH1 = 0xDC; //設定定時器重裝值
- ET1 = 0; //禁止定時器1中斷
- TR1 = 1; //啟動定時器1
- }
-
-
- //
- //
- */
- //AD轉換初始化 ----打開ADC電源
- void InitADC()
- {
- P1=0xff;
- ADC_CONTR|=0x80;
- delayms(80);
- //這兩個寄存器用來設置 P1口四種狀態,每一位對應一個P1引腳 ,按狀態組合操作
- /*****************
- P1M0 和P1M1 寄存器位 7 6 5 4 3 2 1 0
- P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0
- 同理P3M0 P3M0 也是。因為STC12C2052AD只有兩個P口,所以只有這倆組 STC12C5410AD還多P2M0 P1M0 有三組
- P1M0 P1M1 高
- 0 0 普通I0口 (準雙向) P1寄存器位 7 6 5 4 3 2 1 0
- 0 1 強推挽輸出 (20MA電流 )盡量少用 P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0
- 1 0 僅做輸入 A/D轉換時可用此模式
- 1 1 開漏 ,A/D轉換時可用此模式
-
- 例如:
- 要設置P1.1為 AD 輸入口
- 則 P1M0=0X02 ;
- P1M1=0X02; 開漏即可
- 當不用AD時,最好 關閉ADC電源 ,恢復為IO口狀態
- ********************************/
- P1M0=0x01;//這兩個寄存器用來設置 P1口四種狀態,每一位對應一個P1引腳 ,按狀態組合操作
- P1M1=0x01;//設置P1.0為開漏狀態
- }
-
- // AD轉換程序
- /******************************************************
- 注意:這個函數里注釋的命令是通用命令,可以針對所有AD通道使用,我這就認準了P1.1一個通道,所以直接
- //賦值,省點"流量"!折磨我的問題就出在這個函數里的while等待語句
- while (1) //等待A/D轉換結束
- {
- if (ADC_CONTR & 0x10) //0001,0000 測試A/D轉換結束否
- { break; }
- }
- 這是能用的,我原來寫的是:
- while (ADC_CONTR & 0x10==0);
- 這樣寫不能用,再說一遍:這樣就不能用了!
- 至于為嘛,因為 優先級,“==”比&優先級高,
- 所以加個括號就可以了
- while ( (ADC_CONTR & 0x10) == 0 );
- 不經常用C語言,就會記不住啦!!
- 由此得到一個教訓;小問題影響效率
- 經驗:經常加一加括號會死啊,似乎也不耗“流量”吧!
- *********************************************/
- int ADC()
- {
- ADC_DATA = 0; //清除結果
- ADC_CONTR = 0x60; //轉換速度設置 0x60 最快速度
- ADC_CONTR = 0xE0; //1110,0000 清 ADC_FLAG, ADC_START 位和低 3 位 開啟AD電源保持速度設置
- // ADC_CONTR =0xe1; // 選擇 A/D 當前通道 P1.1 保持上句設置
- // ADC_CONTR |= 0x01; //選擇 A/D 當前通道 P1.1
- delayms(2); //使輸入電壓達到穩定
- ADC_CONTR = 0xE8; //開啟轉換 1110 1001 保持上句設置
- // ADC_CONTR |= 0x08; //0000,1000 令 ADCS = 1, 啟動A/D轉換,
- while (1) //等待A/D轉換結束
- {
- if (ADC_CONTR & 0x10) //0001,0000 測試A/D轉換結束否
- { break; }
- }
- ADC_CONTR =0xE0;
- //ADC_CONTR &= 0xE7; //1111,0111 清 ADC_FLAG 位, 關閉A/D轉換,
- return ADC_DATA; //返回 A/D 10 位轉換結果
-
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
0.png (41.49 KB, 下載次數: 65)
下載附件
2018-12-21 15:31 上傳
所有資料51hei提供下載:
調壓.rar
(162.1 KB, 下載次數: 26)
2018-12-21 09:57 上傳
點擊文件名下載附件
僅供參考 下載積分: 黑幣 -5
|