找回密码
 立即注册

QQ登录

只需一步,快速开始

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

求 双IO独立控阻+RC放电测温方案

[复制链接]
跳转到指定楼层
楼主
ID:59341 发表于 2026-6-4 13:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
双 IO 独立控阻 + RC 放电测温 方案(无 ADC 测 NTC 成熟拓扑),这电路谁玩过,发个原理图示例代码出来学习学习
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:401564 发表于 2026-6-4 15:11 | 只看该作者
上古时期的东西,类似于钻木取火
一个带12位ADC的九齐单片机3毛2
回复

使用道具 举报

板凳
ID:1133081 发表于 2026-6-4 15:55 | 只看该作者
模拟串口+RC测电压程序,可以电压换算温度。测试芯片STC15F104W。
  1. /*------------------------------------------------------------------*/
  2. /* --- STC MCU International Limited -------------------------------*/
  3. /* --- STC 1T Series MCU RC Demo -----------------------------------*/
  4. /* If you want to use the program or the program referenced in the  */
  5. /* article, please specify in which data and procedures from STC    */
  6. /*------------------------------------------------------------------*/

  7. /*

  8. 功能描述: 使用STC15F系列C版本做的RC测量电压的例子.

  9. */
  10. #include "reg51.h"
  11. /********宏定义*******/
  12. #define MAIN_Fosc                22118400L        //定义主时钟
  13. #define        uchar        unsigned char
  14. #define uint        unsigned int
  15. /********特殊功能寄存器*******/
  16. sfr AUXR = 0x8e;    //Auxiliary register
  17. sfr P3M1  = 0xB1;        //P3M1.N,P3M0.N         =00--->Standard,        01--->push-pull
  18. sfr P3M0  = 0xB2;        //                                        =10--->pure input,        11--->open drain
  19. /********端口定义*******/
  20. sbit P_TXD1  = P3^1;        //定义模拟串口发送脚,打印信息用
  21. sbit P_RC = P3^2;                //RC 检测端口
  22. /********变量与子程序声明*******/
  23. uchar        SampleCnt;                //发送结果的采样间隔计数
  24. uchar        LineCnt;                //每行显示结果计数
  25. bit                B_Over;                        //超量程标志
  26. bit                B_ADC_OK;                //检测完成标志
  27. uint        adc;                        //RC做的ADC值

  28. void        RC_start(void);                //RC检测开始
  29. void        Tx1Send(uchar dat);        //发送数据
  30. void         InitTimer(void);        //初始化定时器
  31. void        delay_ms(uchar ms);        //延时

  32. ///////////////////////////////////////////////////////////

  33. void main(void)
  34. {        
  35.         InitTimer();                //初始化定时器
  36.         P3M1 |=  1 << 2;         //P3.2 开漏模式
  37.         P3M0 |=  1 << 2;
  38.         P_RC = 0;               //RC 检测端口

  39.         while (1)
  40.         {
  41.                 delay_ms(5);                //放电时间        
  42.                 B_ADC_OK = 0;                //清除ADC结束标志        
  43.                 B_Over = 0;                        //清除超量程标志
  44.                 RC_start();         //RC 检测开始
  45.                 while(!B_ADC_OK && !B_Over);        //等待ADC结束或超量程
  46.                 if(B_ADC_OK)                                        //检测完成标志为1
  47.                 {
  48.                         if(++SampleCnt >= 100)        //1秒钟发一个结果给串口
  49.                         {
  50.                                 SampleCnt = 0;
  51.                                 Tx1Send(adc / 10000 + '0');           //send to PC from the UART
  52.                                 Tx1Send(adc % 10000 / 1000 + '0');
  53.                                 Tx1Send(adc % 1000 / 100 + '0');
  54.                                 Tx1Send(adc % 100 / 10 + '0');
  55.                                 Tx1Send(adc % 10 + '0');
  56.                                 Tx1Send(' ');
  57.                                 Tx1Send(' ');
  58.                                 if(++LineCnt >= 10)                //10个结果后换行
  59.                                 {
  60.                                         LineCnt = 0;
  61.                                         Tx1Send(0x0d);   //send CR
  62.                                         Tx1Send(0x0a);
  63.                                 }
  64.                         }
  65.                 }
  66.         }
  67. }

  68. /***************延时函数*****************/
  69. void  delay_ms(uchar ms)
  70. {
  71.         uint i;
  72.         do
  73.         {
  74.                 i = MAIN_Fosc / 14000L;        //1T
  75.                 while(--i)        ;   //13T per loop
  76.         }while(--ms);
  77. }
  78. /**************** Timer初始化函数 ************/
  79. void InitTimer(void)
  80. {
  81.         TMOD = 0;                //16位自动重装
  82.         TH0  = 0;                //
  83.         TL0  = 0;                //
  84.         TR0  = 0;                //关定时器0
  85.         ET0  = 1;                //开定时器0中断
  86.         EA   = 1;                //开总中断
  87. }
  88. /********************* INT0外部中断函数 *************************/
  89. void INT0_int () interrupt 0                //
  90. {
  91.         if(INT0 && !B_Over)                //上升沿中断,无超时
  92.         {
  93.                 TR0 = 0;            //关定时器0
  94.                 P_RC = 0;           //RC 检测端口置0
  95.                 adc = TH0;          //读定时寄存器高8位数据
  96.                 adc =(adc<<8)+TL0;        //高8位数据+低8位数据
  97.                 B_ADC_OK = 1;                //标志ADC结束
  98.         }
  99. }
  100. /********************** Timer0中断函数************************/
  101. void timer0 (void) interrupt 1
  102. {
  103.         TR0 = 0;        //超量程关闭
  104.         B_Over = 1;        //标志超量程
  105. }
  106. /**************** RC启动函数 ******************************/
  107. void RC_start()
  108. {                                       //使用定时器0计时
  109.         TH0 = 0;            //计数寄存器清0
  110.         TL0 = 0;
  111.         B_Over = 0;                        //超时标志清0
  112.         P_RC = 1;           //RC 检测端口置1
  113.         TR0 = 1;            //开启定时器
  114.         IE0 = 0;                        //外部中断0请求标志清0
  115.         EX0 = 1;                        //INT0 开外中断
  116.         IT0 = 0;                        //INT0 上升/下降沿均可触发中断        
  117. }
  118. /********************** 模拟串口相关函数************************/

  119. void BitTime(void)        //位时间函数
  120. {
  121.         uint i;
  122.         i = ((MAIN_Fosc / 100) * 104) / 130000L - 1;                //根据主时钟来计算位时间
  123.         while(--i);
  124. }

  125. //模拟串口发送
  126. void Tx1Send(uchar dat)                //9600,N,8,1                发送一个字节
  127. {
  128.         uchar        i;
  129.         EA = 0;
  130.         P_TXD1 = 0;
  131.         BitTime();
  132.         for(i=0; i<8; i++)
  133.         {
  134.                 if(dat & 1)
  135.                         P_TXD1 = 1;
  136.                 else
  137.                         P_TXD1 = 0;
  138.                 dat >>= 1;
  139.                 BitTime();
  140.         }
  141.         P_TXD1 = 1;
  142.         EA = 1;
  143.         BitTime();
  144.         BitTime();
  145. }
复制代码



回复

使用道具 举报

地板
ID:1109793 发表于 2026-6-4 17:16 | 只看该作者
对啊,现在带AD的芯片都很便宜了呢
回复

使用道具 举报

5#
ID:41656 发表于 2026-6-4 19:29 | 只看该作者
这个估计要自己测试了,IO的输入阻抗可能影响电路的,而且高低电平阈值每个芯片还有偏差而且电容的容量误差一边也比较大只能粗略测量一致性不好。使用RC充放电时间常数C知道、高低电平阈值知道、充放电时间也知道就能计算出R
回复

使用道具 举报

6#
ID:1034262 发表于 2026-6-4 21:06 | 只看该作者
90年代末到2002年这几年用过,电子表、电子钟等等测温,要求IO读到高电平有高度一致性。
IO1 ---Ro----|
IO2 ---Rt----|
                 |
                C
                 |
              GND
步骤:
1、IO1、IO2均输出0,给C放电。
2、IO2高阻,IO1输出高,给C充电,直到IO2读到高电平,充电时间为t1。
3、IO1、IO2均输出0,给C放电。
4、IO1高阻,IO2输出高,给C充电,直到IO1读到高电平,充电时间为t2。
则 Rt = Ro*t2/t1

更准确的是用3个IO,不用考虑IO读到高电平的差异:
IO1 ---Ro----|
IO2 ---Rt----|
IO3----------|
                 |
                C
                 |
              GND
步骤:
IO3保持高阻。
1、IO1、IO2均输出0,给C放电。
2、IO2高阻,IO1输出高,给C充电,直到IO3读到高电平,充电时间为t1。
3、IO1、IO2均输出0,给C放电。
4、IO1高阻,IO2输出高,给C充电,直到IO3读到高电平,充电时间为t2。
则 Rt = Ro*t2/t1


回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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