极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 19070|回复: 2

[求助]Arduino控制可控硅的程序(含过零检测)各位大神现身吧

[复制链接]
发表于 2012-10-25 12:21:45 | 显示全部楼层 |阅读模式
本帖最后由 wasdpkj 于 2012-11-1 20:46 编辑

我自己搞定了!

这次主要是来求助程序的,可控硅是通过高低电平来控制其导通角达到目的,可过零检测这里我就纠结了,涉及到中断,c语言太烂是在无从下手。

上网搜了很久,没有arduino控制可控硅的例子,各位能否帮我看看程序如何写好。

最终目的是arduino控制220v市电电器的功率,用可控硅可以实现电压的无极调整,光耦则是安全考虑。

电路图:

电路图经测试是有效的,P1是控制端,P2是过零检测端



这里有个例子:
http://wenku.baidu.com/view/dc37c4eb998fcc22bcd10d13.html


以下是搜得的51单片机代码(c语言太烂,实在看不太懂)

  1. #include <reg52.H>          
  2. #include "intrins.h"

  3. #define        _50msL_        50000*0.9216
  4. #define        _50msH_        50000*0.9216
  5. #define        _1ms_        922
  6. #define        _10ms_        9216
  7. #define        _50us        46    //50*0.9216

  8. #define uchar unsigned char  
  9. #define uint unsigned int
  10. void delaySTD_ms(uchar ms); // 延时毫秒@12M,ms最大值255
  11. unsigned char scankey();


  12. sbit PWM_PIN= P1^0;
  13. sbit PWM_TESTLED= P1^2;
  14. /*在
  15.  /INT0为过零检测,36v,注意安全!! 外接了两个按键,用来调整占空比;

  16.   注意由于P1.1口也控制继电器,因此杜绝字节赋值,不要出现如P1=1;
  17.  如果把 PWM 波形的频率提高,也可以用 LED 观察到渐亮渐暗的效果,目前看,只是闪烁的时间发生变化。
  18.   220v调光设定为1kHz@12M,每周期1000us,分为10次比较合理,每CELL为1000us!
  19. */
  20. sbit    key1pressed= P1^5;
  21. sbit    key2pressed= P1^6;
  22. sbit    key3pressed= P1^7;


  23. #define LEVEL0 0
  24. #define LEVEL1 1
  25. #define LEVEL2 2
  26. #define LEVEL3 3
  27. #define LEVEL4 4

  28. #define GRADE 10  //单位次,调光多少级?推荐10级,比较合理(实际只能显示7级,请加MAP映射处理!);20级的话到13级就会出现误判读!
  29. //GRADE固定为10,以便完成9级调光!!!sw除开灭是8级调光,号称10级!
  30. #define CELL  (9216/GRADE)     //10为半个市电周期,一个波
  31. //#define CELL  10000  //10000us,实际是9216
  32. #define KEYPRESSTIME  7  //10ms,key bound delay time

  33. int iShiftPoint;
  34. int b; //b一定要有符号整型!
  35. uint timemultiplex;
  36. uint timemultiplex_maxvalue;
  37. //------------------------------------------
  38. void main()
  39. {
  40.         PWM_PIN = 0; //先关了PWM,免得一开始就给5V导通220V了!!安全考虑!!
  41. timemultiplex_maxvalue=3;
  42. timemultiplex=1;       
  43.         //外部过零中断
  44.         IT0 = 1; //1为边沿触发
  45.         EX0 = 1;
  46.         //开启定时中断
  47.         TMOD = 0x01;                 //T0定时方式1
  48.     b =8;//初亮度调整
  49.         iShiftPoint=b;
  50.         TH0 = (65536-CELL*iShiftPoint) / 256;   //历史:50ms@12MHz,这里定时没意义,通过外中断过零定时
  51.         TL0 = (65536-CELL*iShiftPoint) % 256;
  52.         ET0 = 1;
  53.         TR0 = 1;//TR0 = 1;定时只是为了计算延时时长!10ms即10000us,分成10种时长,由t1产生这10种时长
  54. //定时器1初始化:
  55.         TMOD |= 0x10;                 //T1定时方式1
  56.         TH1 = (65536-_50us) / 256;   
  57.         TL1 = (65536-_50us) % 256;
  58.         ET1 = 1;
  59.         TR1 = 1;//TR0 = 1;定时只是为了计算延时时长!10ms即10000us,分成10种时长,由t1产生这10种时长

  60.         EA = 1;


  61. //调光级别从0到4共5级别 能调光级别811~910
  62. #define MAXAA 998
  63. #define MINAA 11
  64.          while(1)
  65.                 {
  66.                         unsigned char buf;

  67. //以下为自动化按键测试
  68.                         b =MINAA;
  69.                         if (b>MAXAA)
  70.                         {
  71.                 //        delaySTD_ms(500);
  72.                 //        delaySTD_ms(500);                       
  73.                 //        delaySTD_ms(500);
  74.                 //        delaySTD_ms(500);
  75.                 //                b=MINAA;
  76.                         PWM_PIN=0;
  77.                         EA=0;
  78.                         }
  79.                         if (b<MINAA)
  80.                                  b=MINAA;
  81.                         b+=30;
  82.                         delaySTD_ms(500);
  83.                         continue;
  84. //以上为自动化按键测试                       

  85.        //  while(1)
  86.         //        {
  87.         //                unsigned char buf;
  88.                         buf=scankey();
  89.                          if(buf==1)  //调灭
  90.                                 {
  91.                                         b++;
  92.                                 }
  93.                          if(buf==2)
  94.                                 {//二键调亮。b--是亮,765,从灭到月牙到亮
  95.                                         b--;
  96.                                 }
  97.                          if(buf==3)
  98.                                 {//3键盘关闭继电器,同时也得关PWM灯才得灭;再按一次3键,则全亮
  99.                                         PWM_PIN=!PWM_PIN;
  100.                                 }
  101.                         if (b>(GRADE-1)) b=LEVEL4;//仍然最亮   //历史:在这里调整周期.不能无限增加
  102.                         if (b<0)           b=LEVEL0;//必须设置为>20,<1,不能设置为>19,<0,否则最后亮了就熄灭一下
  103.                         iShiftPoint=b;
  104.                         //other while
  105. /*
  106.                         delaySTD_ms(500);
  107.                         delaySTD_ms(500);                       
  108.                         delaySTD_ms(500);
  109.                         delaySTD_ms(500);
  110.                         timemultiplex_maxvalue++;
  111.                         if (timemultiplex_maxvalue>40) timemultiplex_maxvalue=40;
  112. */
  113.                 }
  114. }

  115. //------------------------------------------

  116. void X0_INT(void) interrupt 0
  117. {
  118. //过零检测,来个中断就表过零了,过零时才能重新基准一次10ms。

  119.      //   EA = 0;
  120.         TR0=0;
  121.         //        PWM_PIN = 0;       
  122.                 TH0 = (65536-CELL*iShiftPoint) / 256;   //1000ms@12MHz,这里定时没意义,只是个时间流逝。通过外中断过零定时
  123.                 TL0 = (65536-CELL*iShiftPoint) % 256;   
  124.         TR0=1;
  125.           //        EA = 1;
  126. }

  127. void time0(void) interrupt 1
  128. {

  129. /*
  130.         TR0 = 0;
  131.         TH0 = (65536-CELL*iShiftPoint) / 256;   //历史:50ms@12MHz,这里定时没意义,通过外中断过零定时
  132.         TL0 = (65536-CELL*iShiftPoint) % 256;
  133.         TR0 = 1;
  134. */
  135.         int i;
  136.         // 1次外部中断产生,其灭会等待CELL*iShiftPoint us之后就开pwm,直至下次过零点关掉 ;CELL*iShiftPoint us由定时器来计算
  137.         PWM_PIN = 1;      

  138. /*
  139. //随便两语句延时
  140. for (i=0;i<100;i++)
  141. {
  142.                            _nop_();
  143.                         _nop_();
  144.                         _nop_();
  145. }
  146. */

  147.         TR1 = 0;
  148.         TH1 = (65536-_50us) / 256;   //历史:50ms@12MHz,这里定时没意义,通过外中断过零定时
  149.         TL1 = (65536-_50us) % 256;
  150.         TR1 = 1;
  151.                 //关要!
  152. //                PWM_PIN = 0;//亮个4us关,效果比一直亮好

  153. }
  154. //------------------------------------------

  155. void time1(void) interrupt 3
  156. {
  157.     timemultiplex++;
  158.         if (timemultiplex==timemultiplex_maxvalue)
  159.         {
  160.                 timemultiplex=0;
  161.                 //关要!
  162.                 PWM_PIN = 0;
  163.         }
  164. }


  165. /*********************************************************/
  166. // 延时子程序
  167. /*********************************************************/
  168. void delaySTD_ms(uchar ms)  // 标准延时毫秒@12M,ms最大值255   
  169. {   
  170.     uchar i;   
  171.     while(ms--)   
  172.         for(i = 0; i < 124; i++);   
  173. }

  174. //那个键按下返回几
  175. unsigned char scankey()
  176. {
  177.         if (key1pressed==0)
  178.         {
  179.                 delaySTD_ms(KEYPRESSTIME);
  180.                 if (key1pressed==0)
  181.                 {
  182.                         while(!key1pressed);
  183.                         delaySTD_ms(KEYPRESSTIME);
  184.                         return 1;
  185.                 }
  186.         }
  187.         if (key2pressed==0)
  188.         {
  189.                 delaySTD_ms(KEYPRESSTIME);
  190.                 if (key2pressed==0)
  191.                 {
  192.                         while(!key2pressed);
  193.                         delaySTD_ms(KEYPRESSTIME);
  194.                         return 2;
  195.                 }
  196.         }
  197.         if (key3pressed==0)
  198.         {
  199.                 delaySTD_ms(KEYPRESSTIME);
  200.                 if (key3pressed==0)
  201.                 {
  202.                         while(!key3pressed);
  203.                         delaySTD_ms(KEYPRESSTIME);
  204.                         return 3;
  205.                 }
  206.         }

  207.         return 0;  //0表示没按键按下,更表示误按了快速弹起了。
  208. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2012-10-25 23:22:18 | 显示全部楼层
好资料,你使用了吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-10-26 12:34:47 | 显示全部楼层
太行摄狼 发表于 2012-10-25 23:22
好资料,你使用了吗?

没使用,刚试了试,没加过零检测的话,风扇只能勉强转,无法很好地控制,我现在就是不会编程。。所以来求助,您能否帮忙看看程序怎么写
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-30 02:31 , Processed in 0.049815 second(s), 19 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表