找回密码
 立即注册
楼主: wuzhengmin

比较器实验求救 | 已解决

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:42
  • 最近打卡:2025-10-15 15:37:36
已绑定手机

2

主题

271

回帖

782

积分

高级会员

积分
782
发表于 2025-10-2 09:27:29 | 显示全部楼层
Debu*** 发表于 2025-9-10 12:13
调电位器设置比较点略低于电源电压,让电源电压刚开始下降时就触发比较器,才能实现掉电保存 ...

尊敬的版主,您真的厉害,经验丰富,回答细致,可惜我天生愚钝,今天才真正看懂您宝贵的提示!我慢慢研究一下,也买了一个更大的电容,有机会来顺德我这儿,一定请您吃饭喝茶!!!

点评

得闲饮茶!  详情 回复 发表于 2025-10-2 16:25
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:200
  • 最近打卡:2025-10-15 13:18:53

77

主题

6775

回帖

1万

积分

超级版主

积分
14384
发表于 2025-10-2 16:25:18 | 显示全部楼层
wuzhe*** 发表于 2025-10-2 09:27
尊敬的版主,您真的厉害,经验丰富,回答细致,可惜我天生愚钝,今天才真正看懂您宝贵的提示!我慢慢研究 ...

得闲饮茶!
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:42
  • 最近打卡:2025-10-15 15:37:36
已绑定手机

2

主题

271

回帖

782

积分

高级会员

积分
782
发表于 2025-10-7 19:40:40 | 显示全部楼层
经过梁工的提醒,我慢慢反应过来:


实际上,比较的时候,电位器的位置(实际是+极电压)也很关键:

仔细研究梁工的留言:

“调电位器设置比较点略低于电源电压,让电源电压刚开始下降时就触发比较器,才能实现掉电保存”  其实我一开始没有真的看懂





回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:42
  • 最近打卡:2025-10-15 15:37:36
已绑定手机

2

主题

271

回帖

782

积分

高级会员

积分
782
发表于 2025-10-7 19:44:41 | 显示全部楼层
今天我觉得是真理解了梁工的话

就把自己的程序和stc的样板结合起来,实验成功

顺利的保存了计时时间数据:

计时数据掉电保存.zip

341.42 KB, 下载次数: 5

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:42
  • 最近打卡:2025-10-15 15:37:36
已绑定手机

2

主题

271

回帖

782

积分

高级会员

积分
782
发表于 2025-10-7 19:51:28 | 显示全部楼层
当然,也遇到让我不理解的地方:


看下面的程序:

  1. /*用比较器的方式做个低电压掉电保存数据,P37引脚电压小于1.19V(内部REFV1.19V)点中断,
  2. 保存计时数据
  3. */
  4. #include "COMM/stc.h"                //调用头文件
  5. #include "COMM/stc32_stc8_usb.h"
  6. #include "seg_led.h"
  7. #include "key.h"
  8. #include "beep.h"
  9. #include "tim0.h"
  10. #include "exit.h"
  11. #include "adc.h"
  12. #include "ntc.h"
  13. #include "usart2.h"
  14. #include "stdio.h"
  15. #include "intrins.h"
  16. #include " wdt.h"
  17. #include "cmp.h"                //调用头文件
  18. #include "eeprom.h"
  19. char *USER_DEVICEDESC = NULL;
  20. char *USER_PRODUCTDESC = NULL;
  21. char *USER_STCISPCMD = "@STCISP#";
  22. bit  TIM_10MS_Flag;                        //10ms的标志位
  23. u32 TimCount = 0;                //计数几个10ms
  24. bit LowVolFlag;     //低电压标志
  25. bit B_1ms;          //1ms标志
  26. u16 Test_cnt;   //测试用的秒计数变量
  27. u16 Temp_cnt;   //保存用的秒计数变量
  28. u8  tmp[2];     //通用数组
  29. void sys_init();        //函数声明
  30. void delay_ms(u16 ms);        //unsigned int
  31. void Test_cntfz(void)
  32. {
  33.                         SEG0  = Test_cnt/100000%10;
  34.                         SEG1  = Test_cnt/10000%10;        
  35.                         SEG2  = Test_cnt/1000%10;               
  36.                         SEG3  = Test_cnt/100%10;                //取10位
  37.                         SEG4  = Test_cnt/10%10;                //取1位,这句错了,多除了10 导致我好几天想不明白!
复制代码
这里主程序中,应该是中断1000次才是1秒啊?
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:42
  • 最近打卡:2025-10-15 15:37:36
已绑定手机

2

主题

271

回帖

782

积分

高级会员

积分
782
发表于 2025-10-7 19:55:10 | 显示全部楼层
但是如果真写1000:



while(1)
                        {
                                        if((B_1ms) && (LowVolFlag == 0))   //1ms到,低电压时不工作
                                        {
                                                B_1ms = 0;
                                                                if(++TimCount >= 100)   //1秒到这里不是应该1000么?
                                                               
                                                                        TimCount = 0;        //清1000ms计数
                                                                        Test_cnt++;         //秒计数+1
                                                                        if(Test_cnt > 10000)    Test_cnt = 0;   //秒计数范围为0~10000
                                                                       
                                                                        Test_cntfz();
                                                               
                                                                       
                                        }
                        }


程序烧录后时间明显慢了很多,差了大约10倍!

怎么回事?


#include "tim0.h"
#include "eeprom.h"


//========================================================================
// 函数名称: Timer0_Init
// 函数功能: 定时器0初始化
// 入口参数: 无
// 函数返回: 无
// 当前版本: VER1.0
// 修改日期: 2023
// 当前作者:
// 其他备注:
//========================================================================
void Timer0_Init(void)                //1毫秒@24.000MHz
{
        AUXR = 0x80;    //Timer0 set as 1T, 16 bits timer auto-reload,
    TH0 = (u8)(Timer0_Reload / 256);
    TL0 = (u8)(Timer0_Reload % 256);
    ET0 = 1;    //Timer0 interrupt enable
    TR0 = 1;    //Tiner0 run
        ET0 = 1;                                //使能定时器0中断
       
//        AUXR &= 0x7F;                        //定时器时钟12T模式
//        TMOD &= 0xF0;                        //设置定时器模式
//        TL0 = 0x30;                                //设置定时初始值
//        TH0 = 0xF8;                                //设置定时初始值
//        TF0 = 0;                                //清除TF0标志
//        TR0 = 1;                                //定时器0开始计时
//        ET0 = 1;                                //使能定时器0中断
       
        IP = 0X02;                                //设置为最高优先级
        IPH = 0X02;
}


定时器0确实是1ms

当然,我们运行其他语句,也是要耗时间的........................

但是也不至于差别太大啊?
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:42
  • 最近打卡:2025-10-15 15:37:36
已绑定手机

2

主题

271

回帖

782

积分

高级会员

积分
782
发表于 2025-10-7 20:24:00 | 显示全部楼层
很没有理由的这样写:
  1. while(1)
  2.                         {
  3.                                         if((B_1ms) && (LowVolFlag == 0))   //1ms到,低电压时不工作
  4.                                         {
  5.                                                 B_1ms = 0;
  6.                                                                 if(++TimCount >= 100)   //1秒到这里不是应该1000么?
  7.                                                                 {
  8.                                                                         TimCount = 0;        //清1000ms计数
  9.                                                                         Test_cnt++;         //秒计数+1
  10.                                                                         if(Test_cnt > 10000)    Test_cnt = 0;   //秒计数范围为0~10000
  11.                                                                        
  12.                                                                         Test_cntfz();
  13.                                                                 }
  14.                                                                        
  15.                                         }
  16.                         }
复制代码
好像时间还准一点点.......

计时数据掉电保存.zip

341.43 KB, 下载次数: 3

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:42
  • 最近打卡:2025-10-15 15:37:36
已绑定手机

2

主题

271

回帖

782

积分

高级会员

积分
782
发表于 2025-10-7 20:27:51 | 显示全部楼层
不管怎么说,掉电存储,还行,基本都成功存储。证明程序没有太大问题,单片机只要有点问题,会相互影响,不可能顺利的
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:42
  • 最近打卡:2025-10-15 15:37:36
已绑定手机

2

主题

271

回帖

782

积分

高级会员

积分
782
发表于 2025-10-8 08:12:07 | 显示全部楼层
昨晚在一台华南金牌PC机上,程序运行了30多分钟后发现3个问题:


1是时间数据不能超过1000,过了1000就清0

但是我在程序中的设置是10000或者56500 ,数据类型是u16

2 是显示有时候出差,不知道什么原因,最后一位就不能正常显示了

3 LED9 LED10 好像由数据通信,无规则闪烁
今天我们先换台主机:


处理器  英特尔 Xeon(至强)E5-2637 v2@3.50GHz 四核
主板  华硕 Z9PA-U8 Series
内存  16 GB(镁光 DDR3 1333MHz 16GB)


然后看看试验箱线路图,LED9 LED10 是串口通信指示灯,P46-RXD2-2
P47-TXD2-2 线连接,我们先把P46-RXD2  和 P47-TXD2 设置为高阻状态:

在void CMP_Init(void)的最后加一句

P4M0 &= ~0xc0; P4M1 |= 0xc0;     //P46P47配置为高阻,因为运行时发现LED9
                                                                        //LED10 闪亮

先把问题3解决了


回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:42
  • 最近打卡:2025-10-15 15:37:36
已绑定手机

2

主题

271

回帖

782

积分

高级会员

积分
782
发表于 2025-10-8 08:58:31 | 显示全部楼层
好像第3个问题就解决了,目前在华硕主机上运行了30分钟


掉电保持试了10次,只有1次没成功

但是第一个问题依然存在,只能计时到1000,我程序中是10000的,现在到了1000就清零

第二个问题还没有复现:

计时数据掉电保存.zip

341.61 KB, 下载次数: 3

回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-10-16 07:56 , Processed in 0.124344 second(s), 98 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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