基于51单片机的可控硅调压调光程序-带过零检测
全部代码下载:http://www.51hei.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); // 延时毫秒@12M,ms最大值255unsigned char scankey();sbit PWM_PIN= P1^0;sbit PWM_TESTLED= P1^2;/*在 /INT0为过零检测,36v,注意安全!! 外接了两个按键,用来调整占空比;注意由于P1.1口也控制继电器,因此杜绝字节赋值,不要出现如P1=1; 如果把 PWM 波形的频率提高,也可以用 LED 观察到渐亮渐暗的效果,目前看,只是闪烁的时间发生变化。220v调光设定为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 //单位次,调光多少级?推荐10级,比较合理(实际只能显示7级,请加MAP映射处理!);20级的话到13级就会出现误判读!//GRADE固定为10,以便完成9级调光!!!sw除开灭是8级调光,号称10级!#define CELL (9216/GRADE) //10为半个市电周期,一个波//#define CELL 10000 //10000us,实际是9216#define KEYPRESSTIME 7 //10ms,key bound delay timeint iShiftPoint;int b; //b一定要有符号整型!uint timemultiplex;uint timemultiplex_maxvalue;//------------------------------------------void main(){PWM_PIN = 0; //先关了PWM,免得一开始就给5V导通220V了!!安全考虑!!timemultiplex_maxvalue=3;timemultiplex=1; //外部过零中断IT0 = 1; //1为边沿触发EX0 = 1;//开启定时中断TMOD = 0x01; //T0定时方式1b =8;//初亮度调整iShiftPoint=b;TH0 = (65536-CELL*iShiftPoint) / 256; //历史:50ms@12MHz,这里定时没意义,通过外中断过零定时TL0 = (65536-CELL*iShiftPoint) % 256;ET0 = 1;TR0 = 1;//TR0 = 1;定时只是为了计算延时时长!10ms即10000us,分成10种时长,由t1产生这10种时长//定时器1初始化:TMOD |= 0x10; //T1定时方式1TH1 = (65536-_50us) / 256; TL1 = (65536-_50us) % 256;ET1 = 1;TR1 = 1;//TR0 = 1;定时只是为了计算延时时长!10ms即10000us,分成10种时长,由t1产生这10种时长EA = 1;//调光级别从0到4共5级别 能调光级别811~910#define MAXAA 998#define MINAA 11while(1){unsigned char buf;//以下为自动化按键测试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 (bMINAA)b=MINAA;b+=30;delaySTD_ms(500);continue;//以上为自动化按键测试 // while(1)// {// unsigned char buf;buf=scankey();if(buf==1) //调灭{b++;}if(buf==2){//二键调亮。b--是亮,765,从灭到月牙到亮b--;}if(buf==3){//3键盘关闭继电器,同时也得关PWM灯才得灭;再按一次3键,则全亮PWM_PIN=!PWM_PIN;}if (b>(GRADE-1)) b=LEVEL4;//仍然最亮 //历史:在这里调整周期.不能无限增加if (b0) b=LEVEL0;//必须设置为>20,1,不能设置为>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 {//过零检测,来个中断就表过零了,过零时才能重新基准一次10ms。// EA = 0;TR0=0;// PWM_PIN = 0; TH0 = (65536-CELL*iShiftPoint) / 256; //1000ms@12MHz,这里定时没意义,只是个时间流逝。通过外中断过零定时TL0 = (65536-CELL*iShiftPoint) % 256; TR0=1;// EA = 1;}void time0(void) interrupt 1 {/*TR0 = 0;TH0 = (65536-CELL*iShiftPoint) / 256; //历史:50ms@12MHz,这里定时没意义,通过外中断过零定时TL0 = (65536-CELL*iShiftPoint) % 256;TR0 = 1;*/int i;// 1次外部中断产生,其灭会等待CELL*iShiftPoint us之后就开pwm,直至下次过零点关掉 ;CELL*iShiftPoint us由定时器来计算PWM_PIN = 1; /*//随便两语句延时for (i=0;i100;i++){_nop_();_nop_();_nop_();}*/TR1 = 0;TH1 = (65536-_50us) / 256; //历史:50ms@12MHz,这里定时没意义,通过外中断过零定时TL1 = (65536-_50us) % 256;TR1 = 1;//关要!// PWM_PIN = 0;//亮个4us关,效果比一直亮好}//------------------------------------------ void time1(void) interrupt 3 {timemultiplex++;if (timemultiplex==timemultiplex_maxvalue){timemultiplex=0;//关要!PWM_PIN = 0;}}/*********************************************************/ // 延时子程序 /*********************************************************/ void delaySTD_ms(uchar ms) // 标准延时毫秒@12M,ms最大值255 { uchar i; while(ms--) for(i = 0; i 124; i++); } //那个键按下返回几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表示没按键按下,更表示误按了快速弹起了。}
光耦相关文章:光耦原理
可控硅相关文章:可控硅工作原理
pwm相关文章:pwm是什么
51单片机相关文章:51单片机教程
调光开关相关文章:调光开关原理
评论