微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 基于51单片机的可控硅调压调光程序-带过零检测

基于51单片机的可控硅调压调光程序-带过零检测

时间:08-06 来源:互联网 点击:
这是一个用51单片机通过过零检测来调整可控硅的导通角从而实现调光调压,其中过零电路用一个p620光耦,220v这端的电阻是40k,这是一个已经有成熟应用的例子.

全部代码下载: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表示没按键按下,更表示误按了快速弹起了。}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top