找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2590|回复: 0
打印 上一主题 下一主题
收起左侧

消防应急系统,DC--DC, 恒流模拟

[复制链接]
跳转到指定楼层
楼主
刚做完一款消防应急灯的程序,采用15W自带CCAP 可调方便实现恒流输出。恒流模块遇到瓶颈希望大家给点建议,同时按键进入月检,年检还没实现!欢迎大家评论!

  1. #include "reg51.h"
  2. #include "intrins.h"

  3. //#define FOSC    11059200L
  4. #define FOSC    24000000L

  5. typedef unsigned char BYTE;
  6. typedef unsigned int WORD;

  7. WORD code Vbg_ROM _at_ 0x03f7;            //1K程序空间的MCU
  8. WORD second,minute,hour,moutch;
  9. BYTE ADCbg;
  10. BYTE ADCx;
  11. WORD Vx;  //恒流电压mV
  12. BYTE ADCy;
  13. WORD Vy;  //电池电压mV

  14. sfr P0M1 = 0x93;
  15. sfr P0M0 = 0x94;
  16. sfr P1M1 = 0x91;
  17. sfr P1M0 = 0x92;
  18. sfr P2M1 = 0x95;
  19. sfr P2M0 = 0x96;
  20. sfr P3M1 = 0xb1;
  21. sfr P3M0 = 0xb2;
  22. sfr P4M1 = 0xb3;
  23. sfr P4M0 = 0xb4;
  24. sfr P5M1 = 0xC9;
  25. sfr P5M0 = 0xCA;
  26. sfr P6M1 = 0xCB;
  27. sfr P6M0 = 0xCC;
  28. sfr P7M1 = 0xE1;
  29. sfr P7M0 = 0xE2;
  30. sfr P_SW1       = 0xA2;             //外设功能切换寄存器1

  31. #define CCP_S0 0x10                 //P_SW1.4
  32. #define CCP_S1 0x20                 //P_SW1.5

  33. sfr CCON        =   0xD8;           //PCA控制寄存器
  34. sbit CCF0       =   CCON^0;         //PCA模块0中断标志
  35. sbit CCF1       =   CCON^1;         //PCA模块1中断标志
  36. sbit CR         =   CCON^6;         //PCA定时器运行控制位
  37. sbit CF         =   CCON^7;         //PCA定时器溢出标志
  38. sfr CMOD        =   0xD9;           //PCA模式寄存器
  39. sfr CL          =   0xE9;           //PCA定时器低字节
  40. sfr CH          =   0xF9;           //PCA定时器高字节
  41. sfr CCAPM0      =   0xDA;           //PCA模块0模式寄存器
  42. sfr CCAP0L      =   0xEA;           //PCA模块0捕获寄存器 LOW
  43. sfr CCAP0H      =   0xFA;           //PCA模块0捕获寄存器 HIGH
  44. sfr CCAPM1      =   0xDB;           //PCA模块1模式寄存器
  45. sfr CCAP1L      =   0xEB;           //PCA模块1捕获寄存器 LOW
  46. sfr CCAP1H      =   0xFB;           //PCA模块1捕获寄存器 HIGH
  47. sfr CCAPM2      =   0xDC;           //PCA模块2模式寄存器
  48. sfr CCAP2L      =   0xEC;           //PCA模块2捕获寄存器 LOW
  49. sfr CCAP2H      =   0xFC;           //PCA模块2捕获寄存器 HIGH
  50. sfr PCA_PWM0    =   0xf2;           //PCA模块0的PWM寄存器
  51. sfr PCA_PWM1    =   0xf3;           //PCA模块1的PWM寄存器
  52. sfr PCA_PWM2    =   0xf4;           //PCA模块2的PWM寄存器

  53. sfr ADC_CONTR   =   0xBC;                   //ADC控制寄存器
  54. sfr ADC_RES     =   0xBD;                   //ADC高8位结果
  55. sfr ADC_LOW2    =   0xBE;                   //ADC低2位结果
  56. sfr P1ASF       =   0x9D;                   //P1口第2功能控制寄存器
  57.                                             
  58. #define ADC_POWER   0x80                    //ADC电源控制位
  59. #define ADC_FLAG    0x10                    //ADC完成标志
  60. #define ADC_START   0x08                    //ADC起始控制位
  61. #define ADC_SPEEDLL 0x00                    //540个时钟
  62. #define ADC_SPEEDL  0x20                    //360个时钟
  63. #define ADC_SPEEDH  0x40                    //180个时钟
  64. #define ADC_SPEEDHH 0x60                    //90个时钟

  65. sbit SDJC = P1^0;
  66. sbit SDZDC = P1^1;
  67. sbit CD = P1^2;
  68. sbit DC = P1^5;
  69. sbit K = P3^0;
  70. sbit BELL = P3^1;
  71. sbit BL = P3^2;
  72. sbit GL = P3^3;
  73. sbit RL = P3^6;

  74. void InIt();
  75. void Delay(WORD n);
  76. //void GetADC(BYTE ch);
  77. void GetMv();
  78. void GetPWMInIt();
  79. void BEL();
  80. void YorM();
  81. void GetPWM();
  82. /*----------------------------
  83.   初始化
  84. ----------------------------*/
  85. void InIt(){
  86.     CD = 1;
  87.         DC = 1;
  88.         BL = 1;
  89.         GL = 1;
  90.         RL = 1;
  91. }
  92. /*----------------------------
  93. 软件延时
  94. ----------------------------*/
  95. void Delay(WORD n)
  96. {
  97.     WORD x;

  98.     while (n--)
  99.     {
  100.         x = 5000;
  101.         while (x--);
  102.     }
  103. }
  104. /*----------------------------
  105. ADC检测
  106. ----------------------------*/
  107. BYTE GetADC(BYTE ch){
  108.     ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
  109.     Delay(2);                               //ADC上电并延时
  110.     ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
  111.     _nop_();                                //等待4个NOP
  112.     _nop_();
  113.     _nop_();
  114.     _nop_();
  115.     while (!(ADC_CONTR & ADC_FLAG));        //等待ADC转换完成
  116.     ADC_CONTR &= ~ADC_FLAG;                 //清除ADC标志
  117.    
  118.     return ADC_RES;
  119. }
  120. /*----------------------------
  121. 电压检测
  122. ----------------------------*/
  123. void GetMv(){
  124.            //第一步:通过ADC的第2通道测试外部输入电压的ADC测量值
  125.     ADC_RES = 0;                            //清除结果寄存器
  126.     P1ASF = 0x08;                           //设置P1.3口为模拟通道
  127.     GetADC(3);
  128.     GetADC(3);
  129.     ADCx = GetADC(3);                                                //恒流AD

  130.         ADC_RES = 0;                            //清除结果寄存器
  131.     P1ASF = 0x10;                           //设置P1.4口为模拟通道
  132.     GetADC(4);
  133.     GetADC(4);
  134.     ADCy = GetADC(4);                                                //电池检测AD
  135.    
  136.         //第二步:通过ADC的第9通道测试Bandgap电压的ADC测量值
  137.     ADC_RES = 0;                            //清除结果寄存器
  138.     P1ASF = 0x00;                           //不设置P1ASF,即可从ADC的第9通道读取内部Bandgap电压的ADC测量值
  139.     GetADC(3);
  140.     GetADC(3);
  141.     ADCbg = GetADC(3);

  142.         //第三步:通过公式计算外部输入的实际电压值
  143.     //Vx = Vbg_RAM * ADCx / ADCbg;            //使用RAM中的Bandgap电压参数进行计算
  144.     Vx = Vbg_ROM * ADCx / ADCbg;          //使用ROM中的Bandgap电压参数进行计算
  145.     //Vy = Vbg_RAM * ADCy / ADCbg;
  146.         Vy = Vbg_ROM * ADCy / ADCbg;

  147. }
  148. /*----------------------------
  149. PWM输出初始化
  150. ----------------------------*/
  151. void GetPWMInIt(){
  152.         ACC = P_SW1;
  153.     ACC &= ~(CCP_S0 | CCP_S1);      //CCP_S0=0 CCP_S1=0
  154.     P_SW1 = ACC;                    //(P1.2/ECI, P1.1/CCP0, P1.0/CCP1, P3.7/CCP2)
  155.     CCON = 0;                       //初始化PCA控制寄存器
  156.                                     //PCA定时器停止
  157.                                     //清除CF标志
  158.                                     //清除模块中断标志
  159.     CL = 0;                         //复位PCA寄存器
  160.     CH = 0;
  161.     CMOD = 0x02;                    //设置PCA时钟源
  162.                                     //禁止PCA定时器溢出中断
  163.     PCA_PWM2 = 0x80;                //PCA模块2工作于6位PWM
  164.     CCAP2H = CCAP2L = 0x10;         //PWM2的占空比为60% ((40H-10H)/40H)
  165.     CCAPM2 = 0x42;                                                      //CCP2/P3.7输出
  166.           CR = 0;
  167.        
  168. }
  169. /*----------------------------
  170. PWM输出
  171. ----------------------------*/
  172. void GetPWM(){
  173.              CR = 1;
  174.                  if((Vx!=100)&&(20<Vx<=300)){  //Vx不等于100则减1
  175.                           CCAP0L = CCAP0L-1;
  176.                          if(CCAP0L==0x04){
  177.                                   CCAP0L = 0x04;                   //最大占空比输出
  178.                          }
  179.                  }
  180.                  CCAP0H = CCAP0L;
  181.                      if((Vx<=20)||(Vx>300)){  //LED故障
  182.                                    CR = 0;
  183.                                    BEL();
  184.                                    GL = 0;
  185.                                    Delay(100);
  186.                                    GL = 1;
  187.                          }else if((Vy<=2000)||(Vy>=4300)){        //电池故障
  188.                                     CR = 0;
  189.                                    BEL();
  190.                                    CD = 0;
  191.                                    RL = 0;
  192.                                    Delay(100);
  193.                                    RL = 1;
  194.                          }else{
  195.                                    CR = 1;
  196.                          }
  197. }
  198. /*----------------------------
  199. BELL警报
  200. ----------------------------*/
  201. void BEL(){
  202.      BELL = 1;
  203.          Delay(100);
  204.          BELL = 0;
  205. }
  206. /*----------------------------
  207. 自动年检,月检
  208. ----------------------------*/
  209. void YorM(){
  210.          switch(moutch){
  211.                   case 0: SDZDC = 0;                                 
  212.                                  GetPWM();
  213.                                  Delay(200);
  214.                                     break;
  215.                  case 1: SDZDC = 0;
  216.                                  GetPWM();
  217.                                  Delay(200);
  218.                                  break;
  219.                  case 2: SDZDC = 0;
  220.                                  GetPWM();
  221.                                  Delay(200);
  222.                                  break;
  223.                  case 3: SDZDC = 0;
  224.                                  GetPWM();
  225.                                  Delay(200);
  226.                                     break;
  227.                  case 4: SDZDC = 0;
  228.                                  GetPWM();
  229.                                  Delay(200);
  230.                                  break;
  231.                  case 5: SDZDC = 0;
  232.                                  GetPWM();
  233.                                  Delay(200);
  234.                                  break;
  235.                  case 6: SDZDC = 0;
  236.                                  GetPWM();
  237.                                  Delay(200);
  238.                                     break;
  239.                  case 7: SDZDC = 0;
  240.                                  GetPWM();
  241.                                  Delay(200);
  242.                                  break;
  243.                  case 8: SDZDC = 0;
  244.                                  GetPWM();
  245.                                  Delay(200);
  246.                                  break;
  247.                  case 9: SDZDC = 0;
  248.                                  GetPWM();
  249.                                  Delay(200);
  250.                                     break;
  251.                  case 10: SDZDC = 0;
  252.                                  GetPWM();
  253.                                  Delay(200);
  254.                                  break;
  255.                  case 11: SDZDC = 0;
  256.                                  GetPWM();
  257.                                  Delay(2000);
  258.                                  break;
  259.          }
  260. }
  261. /*----------------------------
  262. 主函数
  263. ----------------------------*/
  264. void main()
  265. {
  266.     P0M0 = 0x00;
  267.     P0M1 = 0x00;
  268.     P1M0 = 0x00;
  269.     P1M1 = 0x00;
  270.     P2M0 = 0x00;
  271.     P2M1 = 0x00;
  272.     P3M0 = 0x00;
  273.     P3M1 = 0x00;
  274.     P4M0 = 0x00;
  275.     P4M1 = 0x00;
  276.     P5M0 = 0x00;
  277.     P5M1 = 0x00;
  278.     P6M0 = 0x00;
  279.     P6M1 = 0x00;
  280.     P7M0 = 0x00;
  281.     P7M1 = 0x00;

  282.           InIt();
  283.           GetPWMInIt();
  284.         while(1){
  285.                      GetMv();                          //AD检测
  286.                   if(SDJC == 1){          //市电照明
  287.                          Delay(20);
  288.            if(SDJC == 1){
  289.                          YorM();                  //年检 月检
  290.                          SDZDC = 1;
  291.                          DC = 1;
  292.                          GetPWM();                 //PWM输出                         
  293.                          if(2000<=Vy<3900){
  294.               CD = 1;
  295.               RL = 0;                                                         
  296.              }
  297.                          if(3900<=Vy<4200){
  298.                            Delay(200);
  299.                            if(3900<=Vy<4200){
  300.                                CD = 1;
  301.                    RL = 1;
  302.                            }                          
  303.                          }
  304.                          if(4200<=Vy<4300){
  305.                                  Delay(200);
  306.                                  if(4200<=Vy<4300){
  307.                                          CD = 0;
  308.                     RL = 1;
  309.                                  }                             
  310.                            }
  311.                  }
  312.       }else{
  313.               SDZDC = 0;
  314.                           DC = 0;
  315.                           CD = 0;
  316.                           GetPWM();
  317.                         if(K == 0){
  318.                           CR = 0;
  319.                          }
  320.            }
  321.         }           
  322. }

  323. void timer0() interrupt 1        //定时器0(中断1)
  324. {
  325.    BYTE tim1;           //定义临时变量
  326. TL0=TL0+0XB0;TH0=0X3C;        //重装定时器初值
  327. tim1++;                //每中断一次tim1加1
  328. if(tim1==20){                           //中断20(1秒)
  329.    tim1=0;
  330.    second++;
  331.    if(second>=60){                  //如果秒到60
  332.              second=0;
  333.           minute++;                         //秒变0,分加1
  334.           if(minute>=60){         //如果分到60
  335.                    

  336. …………余下代码请下载附件…………
复制代码


下载:
消防应急系统.zip (44.42 KB, 下载次数: 147)

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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