51單片機(jī) 初學(xué)入門(mén) 24小時(shí)必答區(qū) STM32/8 ARM M3 AVR PIC MSP430 DSP Proteus仿真 Arduino 綜合區(qū)
單片機(jī)DIY制作 智能小車(chē)/機(jī)器人 智能家居 飛行器diy/多軸/航模 程序設(shè)計(jì) 資料共享
模擬數(shù)字 電子制作DIY 拆機(jī)樂(lè)園 PCB 電源 音響/功放 無(wú)線/紅外 儀器儀表 PLC Labview 業(yè)界動(dòng)態(tài)
Protel Altium Designer Allegro orcad Pads/PowerPCB FPGA/CPLD Multisim仿真
Windows/CE 安卓 uCOS uCLinux
這是一個(gè)用51單片機(jī)通過(guò)過(guò)零檢測(cè)來(lái)調(diào)整可控硅的導(dǎo)通角從而實(shí)現(xiàn)調(diào)光調(diào)壓,其中過(guò)零電路用一個(gè)p620光耦,220v這端的電阻是40k,這是一個(gè)已經(jīng)有成熟應(yīng)用的例子,現(xiàn)在公開(kāi)給51hei單片機(jī)論壇的網(wǎng)友.
視頻演示:
全部代碼下載:http://www.torrancerestoration.com/f/kkggl.rar
以下是c51源代碼部分: #include <reg52.H> #include "intrins.h" #define _50msL_ 50000*0.9216 #define _50msH_ 50000*0.9216 #define _1ms_ 922 #define _10ms_ 9216 #define _50us 46 //50*0.9216 #define uchar unsigned char #define uint unsigned int void delaySTD_ms(uchar ms); // 延時(shí)毫秒@12M,ms最大值255 unsigned char scankey(); sbit PWM_PIN= P1^0; sbit PWM_TESTLED= P1^2; /*在 /INT0為過(guò)零檢測(cè),36v,注意安全��! 外接了兩個(gè)按鍵,用來(lái)調(diào)整占空比; 注意由于P1.1口也控制繼電器,因此杜絕字節(jié)賦值,不要出現(xiàn)如P1=1; 如果把 PWM 波形的頻率提高,也可以用 LED 觀察到漸亮漸暗的效果,目前看,只是閃爍的時(shí)間發(fā)生變化。 220v調(diào)光設(shè)定為1kHz@12M,每周期1000us,分為10次比較合理,每CELL為1000us! */ sbit key1pressed= P1^5; sbit key2pressed= P1^6; sbit key3pressed= P1^7; #define LEVEL0 0 #define LEVEL1 1 #define LEVEL2 2 #define LEVEL3 3 #define LEVEL4 4 #define GRADE 10 //單位次,調(diào)光多少級(jí)?推薦10級(jí),比較合理(實(shí)際只能顯示7級(jí),請(qǐng)加MAP映射處理�。�;20級(jí)的話到13級(jí)就會(huì)出現(xiàn)誤判讀! //GRADE固定為10,以便完成9級(jí)調(diào)光�。。w除開(kāi)滅是8級(jí)調(diào)光,號(hào)稱(chēng)10級(jí)! #define CELL (9216/GRADE) //10為半個(gè)市電周期,一個(gè)波 //#define CELL 10000 //10000us,實(shí)際是9216 #define KEYPRESSTIME 7 //10ms,key bound delay time int iShiftPoint; int b; //b一定要有符號(hào)整型! uint timemultiplex; uint timemultiplex_maxvalue; //------------------------------------------ void main() { PWM_PIN = 0; //先關(guān)了PWM,免得一開(kāi)始就給5V導(dǎo)通220V了!!安全考慮!! timemultiplex_maxvalue=3; timemultiplex=1; //外部過(guò)零中斷 IT0 = 1; //1為邊沿觸發(fā) EX0 = 1; //開(kāi)啟定時(shí)中斷 TMOD = 0x01; //T0定時(shí)方式1 b =8;//初亮度調(diào)整 iShiftPoint=b; TH0 = (65536-CELL*iShiftPoint) / 256; //歷史:50ms@12MHz,這里定時(shí)沒(méi)意義,通過(guò)外中斷過(guò)零定時(shí) TL0 = (65536-CELL*iShiftPoint) % 256; ET0 = 1; TR0 = 1;//TR0 = 1;定時(shí)只是為了計(jì)算延時(shí)時(shí)長(zhǎng)!10ms即10000us,分成10種時(shí)長(zhǎng),由t1產(chǎn)生這10種時(shí)長(zhǎng) //定時(shí)器1初始化: TMOD |= 0x10; //T1定時(shí)方式1 TH1 = (65536-_50us) / 256; TL1 = (65536-_50us) % 256; ET1 = 1; TR1 = 1;//TR0 = 1;定時(shí)只是為了計(jì)算延時(shí)時(shí)長(zhǎng)!10ms即10000us,分成10種時(shí)長(zhǎng),由t1產(chǎn)生這10種時(shí)長(zhǎng) EA = 1; //調(diào)光級(jí)別從0到4共5級(jí)別 能調(diào)光級(jí)別811~910 #define MAXAA 998 #define MINAA 11 while(1) { unsigned char buf; //以下為自動(dòng)化按鍵測(cè)試 b =MINAA; if (b>MAXAA) { // delaySTD_ms(500); // delaySTD_ms(500); // delaySTD_ms(500); // delaySTD_ms(500); // b=MINAA; PWM_PIN=0; EA=0; } if (b<MINAA) b=MINAA; b+=30; delaySTD_ms(500); continue; //以上為自動(dòng)化按鍵測(cè)試 // while(1) // { // unsigned char buf; buf=scankey(); if(buf==1) //調(diào)滅 { b++; } if(buf==2) {//二鍵調(diào)亮。b--是亮,765,從滅到月牙到亮 b--; } if(buf==3) {//3鍵盤(pán)關(guān)閉繼電器,同時(shí)也得關(guān)PWM燈才得滅;再按一次3鍵,則全亮 PWM_PIN=!PWM_PIN; } if (b>(GRADE-1)) b=LEVEL4;//仍然最亮 //歷史:在這里調(diào)整周期.不能無(wú)限增加 if (b<0) b=LEVEL0;//必須設(shè)置為>20,<1,不能設(shè)置為>19,<0,否則最后亮了就熄滅一下 iShiftPoint=b; //other while /* delaySTD_ms(500); delaySTD_ms(500); delaySTD_ms(500); delaySTD_ms(500); timemultiplex_maxvalue++; if (timemultiplex_maxvalue>40) timemultiplex_maxvalue=40; */ } } //------------------------------------------ void X0_INT(void) interrupt 0 { //過(guò)零檢測(cè),來(lái)個(gè)中斷就表過(guò)零了,過(guò)零時(shí)才能重新基準(zhǔn)一次10ms。 // EA = 0; TR0=0; // PWM_PIN = 0; TH0 = (65536-CELL*iShiftPoint) / 256; //1000ms@12MHz,這里定時(shí)沒(méi)意義,只是個(gè)時(shí)間流逝。通過(guò)外中斷過(guò)零定時(shí) TL0 = (65536-CELL*iShiftPoint) % 256; TR0=1; // EA = 1; } void time0(void) interrupt 1 { /* TR0 = 0; TH0 = (65536-CELL*iShiftPoint) / 256; //歷史:50ms@12MHz,這里定時(shí)沒(méi)意義,通過(guò)外中斷過(guò)零定時(shí) TL0 = (65536-CELL*iShiftPoint) % 256; TR0 = 1; */ int i; // 1次外部中斷產(chǎn)生,其滅會(huì)等待CELL*iShiftPoint us之后就開(kāi)pwm,直至下次過(guò)零點(diǎn)關(guān)掉 ;CELL*iShiftPoint us由定時(shí)器來(lái)計(jì)算 PWM_PIN = 1; /* //隨便兩語(yǔ)句延時(shí) for (i=0;i<100;i++) { _nop_(); _nop_(); _nop_(); } */ TR1 = 0; TH1 = (65536-_50us) / 256; //歷史:50ms@12MHz,這里定時(shí)沒(méi)意義,通過(guò)外中斷過(guò)零定時(shí) TL1 = (65536-_50us) % 256; TR1 = 1; //關(guān)要! // PWM_PIN = 0;//亮個(gè)4us關(guān),效果比一直亮好 } //------------------------------------------ void time1(void) interrupt 3 { timemultiplex++; if (timemultiplex==timemultiplex_maxvalue) { timemultiplex=0; //關(guān)要! PWM_PIN = 0; } } /*********************************************************/ // 延時(shí)子程序 /*********************************************************/ void delaySTD_ms(uchar ms) // 標(biāo)準(zhǔn)延時(shí)毫秒@12M,ms最大值255 { uchar i; while(ms--) for(i = 0; i < 124; i++); } //那個(gè)鍵按下返回幾 unsigned char scankey() { if (key1pressed==0) { delaySTD_ms(KEYPRESSTIME); if (key1pressed==0) { while(!key1pressed); delaySTD_ms(KEYPRESSTIME); return 1; } } if (key2pressed==0) { delaySTD_ms(KEYPRESSTIME); if (key2pressed==0) { while(!key2pressed); delaySTD_ms(KEYPRESSTIME); return 2; } } if (key3pressed==0) { delaySTD_ms(KEYPRESSTIME); if (key3pressed==0) { while(!key3pressed); delaySTD_ms(KEYPRESSTIME); return 3; } } return 0; //0表示沒(méi)按鍵按下,更表示誤按了快速?gòu)椘鹆恕?}