找回密码
 立即注册

QQ登录

只需一步,快速开始

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

电解电容放电时间怎么计算

[复制链接]
跳转到指定楼层
楼主
ID:960619 发表于 2022-9-14 16:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
5V2200UF的电容,后面带0.025A的负载,这样在断开电源的情况下还能维持电路多久时间,够不够芯片做掉电存储动作
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:624769 发表于 2022-9-14 16:28 | 只看该作者
进入掉电中断后, 先关负载,再做存储动作。
回复

使用道具 举报

板凳
ID:123289 发表于 2022-9-14 16:45 | 只看该作者
电容上的电荷:Qc=U*C=5V*2200uF
负载使用电量:Q = I*t = 0.025A * t
假设:电压降到3.6V停止工作,则电容可提供的电荷 =Qc * (1-3.6/5)。
以下,楼主自己算吧。

够不够做掉电存储,还取决于存数的多少及技巧。通常够了。
回复

使用道具 举报

地板
ID:1044751 发表于 2022-9-14 16:55 | 只看该作者
Q=CU=0.011C
t=Q/I=0.44s
一般的芯片够了,芯片一般都是微秒级的
回复

使用道具 举报

5#
ID:712493 发表于 2022-9-14 19:47 来自手机 | 只看该作者
你这0.011电荷怎么算的
回复

使用道具 举报

6#
ID:960619 发表于 2022-9-14 20:09 | 只看该作者
羚羊树懒书架 发表于 2022-9-14 16:55
Q=CU=0.011C
t=Q/I=0.44s
一般的芯片够了,芯片一般都是微秒级的

0.44S是放电放完的时间,芯片电压过低不可能工作啊
回复

使用道具 举报

7#
ID:624769 发表于 2022-9-14 20:22 | 只看该作者
baobao125 发表于 2022-9-14 20:09
0.44S是放电放完的时间,芯片电压过低不可能工作啊

所以,算这些没有意义。 关键是要先关闭 负载,再开始保存数据,
从低压中断触发(3.8V)开始,只要关了 负载,哪怕你只有 47uf 的电容,也足够写 50个字节以上 到片内Eeprom 了。
回复

使用道具 举报

8#
ID:213173 发表于 2022-9-14 20:53 | 只看该作者
根据坛友的示例经修改实测成功,利用编程技巧不需要多大电容。TX-1C实验板上外围元件不少,电源滤波电容仅10uf,能够掉电后可靠保存2个字节(没有做保存更多字节试验)。测试掉电后能维持2.5ms。如需要保存更多字节应该要适当增大电容。
  1. //测试条件:TX-1C实验板,MCU型号IAP15W4K58S4,系统时钟11.0592MHz
  2. //注意:测试本示例时,需在ISP下载时将低压复位功能和低压时禁止EEPROM操作关闭

  3. #include "STC15Fxxxx.H"
  4. #include <intrins.h>                                //库头文件
  5. #define uint unsigned int                         //宏定义数据类型uint
  6. #define uchar unsigned char                 //宏定义数据类型uchar
  7. //宏定义ISP的操作命令
  8. #define CMD_IDLE    0               //空闲模式
  9. #define CMD_READ    1               //IAP字节读命令
  10. #define CMD_PROGRAM 2               //IAP字节编程命令
  11. #define CMD_ERASE   3               //IAP扇区擦除命令
  12. #define ENABLE_IAP  0x82            //CPU的等待时间
  13. #define IAP_ADDRESS 0x0800                        //测试地址
  14. sbit duan=P2^6;
  15. sbit wein=P2^7;

  16. //顺序共阴极数码管段码表,段码a-h顺序接PX0-PX7
  17. uchar code table[]={//共阴数码管段码"0~f-."
  18.                 0x3f,0x06,0x5b,0x4f,
  19.                 0x66,0x6d,0x7d,0x07,
  20.                 0x7f,0x6f,0x77,0x7c,
  21.                 0x39,0x5e,0x79,0x71,0x40,0x80};
  22. uchar data dis_buf[8];                //缓存数组
  23. uint num,sec;
  24. uchar i;

  25. void Timer0Init();                                        //定时器初始化声明
  26. void IapIdle();                                                //关闭IAP/EEPROM
  27. uchar IapReadByte(uint addr);                //读取EEPROM数据
  28. void IapProgramByte(uint addr, uchar dat);//写入EEPROM数据
  29. void IapEraseSector(uint addr);                //擦除EEPROM数据

  30. void main()                                                       
  31. {
  32.         P0M0 = 0x00;
  33.         P0M1 = 0x00;
  34.         P1M0 = 0x00;
  35.         P1M1 = 0x00;
  36.         P2M0 = 0x00;
  37.         P2M1 = 0x00;
  38.         P3M0 = 0x00;
  39.         P3M1 = 0x00;
  40.         P4M0 = 0x00;
  41.         P4M1 = 0x00;
  42.         P5M0 = 0x00;
  43.         P5M1 = 0x00;
  44.         P6M0 = 0x00;
  45.         P6M1 = 0x00;
  46.         P7M0 = 0x00;
  47.         P7M1 = 0x00;
  48.         sec=IapReadByte(IAP_ADDRESS)<<8|IapReadByte(IAP_ADDRESS+1);//读取保存的数据 用时11.75us
  49.         if(sec==0xffff)//如果没有保存数据
  50.                 sec=0;//变量为0
  51.         else IapEraseSector(IAP_ADDRESS);//擦除数据,为下次掉电保存数据做准备

  52.         PCON &= 0xDF;//清0掉电标志
  53.         ELVD = 1;//开低压中断
  54.         EA   = 1;//开总中断

  55.         Timer0Init();//初始化定时器

  56.         while(1)
  57.         {
  58.                 if(TF0)//查询T0中断请求标志
  59.                 {               
  60.                         TF0=0;//T0中断请求标志清0
  61.                         if(++num>=1000)//1秒
  62.                         {
  63.                                 num=0;                               
  64.                                 sec++;
  65.                         }
  66.                         dis_buf[0]=table[sec/10000%10];
  67.                         dis_buf[1]=table[sec/1000%10];
  68.                         dis_buf[2]=table[sec/100%10];
  69.                         dis_buf[3]=table[sec/10%10];
  70.                         dis_buf[4]=table[sec%10];
  71.                         //5位数码管动态显示
  72.                         P0=0x00;duan=1;duan=0;
  73.                         P0=~(0x01<<i);wein=1;wein=0;
  74.                         P0=dis_buf[i];duan=1;duan=0;
  75.                         i=++i%5;
  76.                 }
  77.         }
  78. }

  79. void Timer0Init(void)        //1毫秒@11.0592MHz
  80. {
  81.         AUXR |= 0x80;                //定时器时钟1T模式
  82.         TMOD &= 0xF0;                //设置定时器模式
  83.         TL0 = 0xCD;                        //设置定时初始值
  84.         TH0 = 0xD4;                        //设置定时初始值
  85.         TF0 = 0;                        //清除TF0标志
  86.         TR0 = 1;                        //定时器0开始计时
  87. }
  88. /*----------------------------
  89.         关闭IAP功能
  90. ----------------------------*/
  91. void IapIdle()
  92. {
  93.     IAP_CONTR = 0;                  //关闭IAP功能
  94.     IAP_CMD = 0;                    //清除命令寄存器
  95.     IAP_TRIG = 0;                   //清除触发寄存器
  96.     IAP_ADDRH = 0x80;               //将地址设置到非IAP区域
  97.     IAP_ADDRL = 0;
  98. }
  99. /*----------------------------
  100. 从ISP/IAP/EEPROM区域读取一字节
  101. ----------------------------*/
  102. uchar IapReadByte(uint addr)
  103. {
  104.     uchar dat;                       //数据缓冲区

  105.     IAP_CONTR = ENABLE_IAP;         //使能IAP
  106.     IAP_CMD = CMD_READ;             //设置IAP命令
  107.     IAP_ADDRL = addr;               //设置IAP低地址
  108.     IAP_ADDRH = addr >> 8;          //设置IAP高地址
  109.     IAP_TRIG = 0x5a;                //写触发命令(0x5a)
  110.     IAP_TRIG = 0xa5;                //写触发命令(0xa5)
  111.     _nop_();                        //等待ISP/IAP/EEPROM操作完成
  112.     dat = IAP_DATA;                 //读ISP/IAP/EEPROM数据
  113.     IapIdle();                      //关闭IAP功能
  114.     return dat;                     //返回
  115. }
  116. /*-------------------------------
  117. 写一字节数据到ISP/IAP/EEPROM区域
  118. --------------------------------*/
  119. void IapProgramByte(uint addr, uchar dat)
  120. {
  121.     IAP_CONTR = ENABLE_IAP;         //使能IAP
  122.     IAP_CMD = CMD_PROGRAM;          //设置IAP命令
  123.     IAP_ADDRL = addr;               //设置IAP低地址
  124.     IAP_ADDRH = addr >> 8;          //设置IAP高地址
  125.     IAP_DATA = dat;                 //写ISP/IAP/EEPROM数据
  126.     IAP_TRIG = 0x5a;                //写触发命令(0x5a)
  127.     IAP_TRIG = 0xa5;                //写触发命令(0xa5)
  128.     _nop_();                        //等待ISP/IAP/EEPROM操作完成
  129.     IapIdle();                      //关闭IAP功能
  130. }
  131. /*----------------------------
  132. ISP/IAP/EEPROM扇区擦除
  133. ----------------------------*/
  134. void IapEraseSector(uint addr)
  135. {
  136.     IAP_CONTR = ENABLE_IAP;         //使能IAP
  137.     IAP_CMD = CMD_ERASE;            //设置IAP命令
  138.     IAP_ADDRL = addr;               //设置IAP低地址
  139.     IAP_ADDRH = addr >> 8;          //设置IAP高地址
  140.     IAP_TRIG = 0x5a;                //写触发命令(0x5a)
  141.     IAP_TRIG = 0xa5;                //写触发命令(0xa5)
  142.     _nop_();                        //等待ISP/IAP/EEPROM操作完成
  143.     IapIdle();                      //关闭IAP功能
  144. }
  145. void PowerLost() interrupt 6                //剩余电量从中断开始到完全断电2.5ms
  146. {
  147.         EA = 0;                                                //关闭总中断
  148.         P0M1 = 0xff;                                //所有端口高阻用时2.75us
  149.         P1M1 = 0xff;
  150.         P2M1 = 0xff;
  151.         P3M1 = 0xff;
  152.         P4M1 = 0xff;
  153.         P5M1 = 0xff;
  154.         P6M1 = 0xff;
  155.         P7M1 = 0xff;
  156.         IapProgramByte(IAP_ADDRESS,sec>>8);//写数据高8位到EEPROM
  157.         IapProgramByte(IAP_ADDRESS+1,sec);//写数据低8位到EEPROM  写两个字节用时215.25us

  158.         while((PCON & 0x20) != 0)         //复查低压标志
  159.         {
  160.                 PCON &= 0xDF;                  //清除低压标志
  161.                 _nop_();               
  162.                 _nop_();                            //坐等掉电
  163.         }
  164.         IAP_CONTR = 0x20;                 //发现是误报,重启单片机,恢复正常工作
  165. }
复制代码

回复

使用道具 举报

9#
ID:960619 发表于 2022-9-14 21:10 | 只看该作者
188610329 发表于 2022-9-14 20:22
所以,算这些没有意义。 关键是要先关闭 负载,再开始保存数据,
从低压中断触发(3.8V)开始,只要关了 ...

我是先关负载,再存储的。用1MS中断扫描IO口电平,因为电容前面有个二极管,后面稳压,想着断电后应该是IO口先读取到低电平,比低压中断有更多的时间用于存储,稳妥些。但stc单片机有时候就是到擦除完后就不工作了。有时候还是可以完成存储的。 只用12M的频率
回复

使用道具 举报

10#
ID:879809 发表于 2022-9-14 23:39 | 只看该作者
跟工作频率无关,flash写一个字节或者写一个页面需要不到10ms时间,单片机执行时间可以忽略不计,完全够用了。
回复

使用道具 举报

11#
ID:624769 发表于 2022-9-15 08:14 来自手机 | 只看该作者
baobao125 发表于 2022-9-14 21:10
我是先关负载,再存储的。用1MS中断扫描IO口电平,因为电容前面有个二极管,后面稳压,想着断电后应该是I ...

你发现断电了,再去擦除eeprom的做法是不可取的,虽然不知道你是什么型号的单片机,但是,往eeprom写数据的话,一个字节2us,50个字节也只要0.1ms,而擦除一个扇区,基本要20ms以上,发现断电,再浪费这宝贵的20ms是极端不合理的。最后,检测前端断电,并不见得比掉电中断更及时,先不说,你的1ms间隔扫描低电平,是否比发现低于3.8v来的更及时,前段也有容性的吧?在单片机功耗大的情况下,单片机停振了,前端还没达到低电平的标准,不是不可能。个人的一些经验,仅供参考。
回复

使用道具 举报

12#
ID:1044792 发表于 2022-9-15 08:42 | 只看该作者
假如降至3V仍可维持工作,可以用如下式子估算:(5-3)* 0.0022(电容量) /0.025, 约0.17s,
回复

使用道具 举报

13#
ID:1044792 发表于 2022-9-15 08:43 | 只看该作者
假如至3V仍可工作,持续时间 则可用下式估算:(5-3)*0.0022 /0.025,约0.17S,
回复

使用道具 举报

14#
ID:807591 发表于 2022-9-15 09:16 | 只看该作者
有计算电容放电的在线工具网站,,另外找个示波器测一下就解决问题了,为什么要去算? 实际测量才是关键,测完可以考虑电容加大一点,以防时间久了电容容量降低
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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