找回密码
 立即注册
查看: 17|回复: 2

特种方式实现简易电感电容表的可能性?

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-09-16 15:04:28
已绑定手机

3

主题

3

回帖

23

积分

新手上路

积分
23
发表于 3 小时前 | 显示全部楼层 |阅读模式
我曾经用cd4069实验出一个特别容易起振的谐振电路,如下。 Screenshot_20250916_182248.jpg

源代码如下


#include <STC15F104E.H> // 包含STC15F104E的特殊功能寄存器定义头文件
#include <intrins.h>    // 如果需要使用_nop_()等内置函数


sbit INPUT_PIN  = P3^2; // 定义输入引脚为 P3.2
sbit OUTPUT_PIN = P3^3; // 定义输出引脚为 P3.3


void main()
{
    // 初始化 GPIO 模式
    // STC15F104E 的 P3M0 和 P3M1 寄存器用于配置P3口模式
    // 配置 P3.2 为高阻输入(或准双向口,根据外部驱动能力决定)
    P3M0 &= ~(1 << 2); // P3.2 M0 bit = 0
    P3M1 |=  (1 << 2); // P3.2 M1 bit = 1 (10: 高阻输入)


    // 配置 P3.3 为推挽输出,以获得较强的驱动能力
    P3M0 |=  (1 << 3); // P3.3 M0 bit = 1
    P3M1 &= ~(1 << 3); // P3.3 M1 bit = 0 (01: 推挽输出)


    // 另一种简单配置:如果输入信号由较强驱动能力的外部电路提供,输出负载较轻,
    // 可将所有端口设置为准双向模式(默认模式,兼容传统8051)
    // P3M0 = 0x00;
    // P3M1 = 0x00;


    while(1) // 主循环
    {
        // 核心逻辑:读取输入状态 -> 取反 -> 输出
        // 使用方法1: if-else 语句
        if(INPUT_PIN == 1)        // 如果检测到输入为高电平
        {
            OUTPUT_PIN = 0;       // 则输出低电平
        }
        else                      // 否则(输入为低电平)
        {
            OUTPUT_PIN = 1;       // 则输出高电平
        }


        // 使用方法2: 三元运算符 (? :) 一行语句完成
        // OUTPUT_PIN = (INPUT_PIN) ? 0 : 1;


        // 使用方法3: 直接使用逻辑非操作符 (!),最简洁
        // OUTPUT_PIN = !INPUT_PIN;


        // 注意:由于单片机执行速度极快(指令周期为时钟的1/6或1/12,STC15系列多数为1T单片机),
        // 这个循环会以很高的频率运行,因此输出的变化几乎是瞬时的,对于低频信号足以模拟硬件非门。
    }
}


突发奇想,有没有可能用单片机模拟cd4069实现lc谐振,并做出简易电感电容表,从而省掉外部lm311谐振电路.先写出代码,等抽空再做测试。






回复

使用道具 举报 送花

3

主题

1975

回帖

798

积分

等待验证会员

积分
798
发表于 3 小时前 | 显示全部楼层
特种方式实现简易电感电容表的可能性分析

在电子测量领域,利用单片机和基础逻辑门电路构建简易的电感电容(LC)表是一种经济且实用的方案。您提到的使用CD4069六反相器芯片和STC15F104E单片机构建LC测量系统,是一种典型的“特种方式”实现。本文将从原理、实现方式、精度分析和优化方向几个方面进行专业分析。

一、基本原理分析

您所使用的CD4069芯片本质上是由六个CMOS反相器构成的逻辑门集成电路。在无反馈的情况下,CMOS反相器具有极高的输入阻抗和极低的输出阻抗,适合用作振荡器的基本单元。

当在反相器两端引入LC谐振回路时,可以构成一个LC自由振荡电路。该电路的基本工作原理如下:
反相器构成一个放大器;
LC谐振回路作为选频网络;
振荡频率由LC值决定,公式为:

  $$
  f = \frac{1}{2\pi\sqrt{LC}}
  $$

当电路起振后,输出信号的频率即为LC谐振频率。通过单片机捕获该频率,再根据公式反推L或C的值,即可实现测量功能。

二、系统实现结构

您给出的系统结构如下:

1. CD4069振荡电路:构成LC自由振荡器;
2. STC15F104E单片机:捕获振荡频率并进行计算;
3. 输入/输出引脚配置:P3.2用于输入检测,P3.3用于驱动振荡电路。

该结构具备以下特点:
无需外部晶振:利用LC振荡频率作为基准,适合资源受限系统;
硬件开销小:仅需少量元件即可搭建;
测量范围受限:取决于单片机定时器的计数精度和振荡电路的稳定性。

三、软件实现分析

您提供的代码片段显示了引脚配置和主函数入口。从结构上看,应包含以下关键步骤:

1. 引脚配置:将P3.3设置为输出,P3.2为输入;
2. 定时器初始化:用于测量振荡周期;
3. 频率捕获:使用定时器或外部中断捕获信号周期;
4. 计算LC值:根据频率公式反推L或C;
5. 结果显示:通过串口或LCD显示测量结果。

代码示例补充如下(基于STC15系列):
  1. c
  2. include
  3. include
  4. sbit INPUTPIN  = P3^2;
  5. sbit OUTPUTPIN = P3^3;
  6. unsigned long frequency = 0;
  7. unsigned int period = 0;
  8. void Timer0Init() {
  9.     TMOD &= 0xF0;        // 清除T0模式位
  10.     TMOD |= 0x02;        // 定时器0,模式2(8位自动重装)
  11.     TH0 = 0x00;
  12.     TL0 = 0x00;
  13.     TR0 = 1;             // 启动定时器
  14. }
  15. void main() {
  16.     P3M0 = 0x00;
  17.     P3M1 = 0x00;         // 设置为准双向口
  18.     Timer0Init();
  19.     OUTPUTPIN = 1;      // 驱动LC振荡电路
  20.     while(1) {
  21.         // 使用外部中断或边沿检测捕获周期
  22.         // 例如使用下降沿触发中断
  23.         IT0 = 1;
  24.         EX0 = 1;
  25.         EA = 1;
  26.         // 计算频率和LC值
  27.         if(period != 0) {
  28.             frequency = 1000000UL / period; // 假设定时器精度为1us
  29.             // 进行LC计算,假设C已知求L
  30.             // L = 1/( (2πf)^2  C )
  31.         }
  32.     }
  33. }
  34. void INT0ISR(void) interrupt 0 {
  35.     static unsigned long lasttime = 0;
  36.     unsigned long now = TL0;
  37.     period = now - lasttime;
  38.     lasttime = now;
  39. }
复制代码

四、精度与误差分析

此类简易LC表的测量精度主要受以下因素影响:

1. 振荡器稳定性:
CD4069的阈值电压随温度和电源波动变化,影响振荡频率稳定性;
建议使用稳压电源,或在程序中加入校准机制。

2. 定时器分辨率:
STC15F104E的定时器精度为微秒级,对高频信号误差较大;
可采用倍频或分频技术提升测量精度。

3. 寄生参数影响:
PCB布局中寄生电容和电感会影响实际LC值;
建议采用屏蔽线或PCB走线优化。

4. 反相器非线性:
CD4069作为数字器件,其工作点偏离线性区,可能引入谐波;
可在反相器之间加入反馈电阻(如10MΩ)改善线性度。

五、优化建议与扩展方向

1. 增加校准功能:
在启动时自动测量已知电容/电感,作为参考基准;
提高测量一致性。

2. 使用专用比较器/运算放大器:
如LM393、LMV358等,可提高振荡稳定性;
成本略有增加,但性能显著提升。

3. 增加自动量程切换功能:
通过继电器或模拟开关切换不同范围的参考电容;
实现宽范围测量。

4. 引入软件滤波算法:
对频率采样值进行滑动平均处理;
提高测量稳定性。

5. 升级为LCR表:
引入交流激励与阻抗测量技术;
可测量电感的Q值、电容的ESR等参数。

六、结论

利用CD4069与STC15F104E构建简易LC表,是一种可行且成本低廉的特种测量方式。其核心在于通过LC振荡频率反推元件值。虽然受限于精度与稳定性,但通过合理的软硬件设计,仍可实现较为可靠的测量结果。

该方案适用于教育、实验、维修等非高精度测量场景,具有较强的实用价值。若进一步优化设计,甚至可扩展为多功能LCR测量仪,具备更高的工程应用潜力。

如需进一步交流电路细节或代码实现,欢迎继续探讨。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-09-16 15:04:28
已绑定手机

3

主题

3

回帖

23

积分

新手上路

积分
23
发表于 2 小时前 来自手机 | 显示全部楼层
不使用cd4069,而是由stc15f104e软件模拟激励出自由谐振,模拟i2c口驱动屏幕,显示电感或电容值,达到极度精简。

#include <STC15F104E.h> // STC15F104E寄存器定义

// 全局变量定义
unsigned long int cycle_cnt = 0;  // 周期计数(记录2次跳变的机器周期数)
bit freq_flag = 0;                // 频率计算完成标志

// 定时器0初始化(16位自动重装,用于产生激励脉冲宽度)
void Timer0_Init(void) {
    TMOD = 0x01;  // T0工作模式1(16位定时器)
    TH0 = 0xFF;   // 初值:定时1μs(晶振11.0592MHz,机器周期1.085μs,近似1μs)
    TL0 = 0xF6;
    ET0 = 0;      // 关闭T0中断(仅用于软件延时,无需中断)
    TR0 = 0;      // 初始关闭定时器
}

// 外部中断0初始化(下降沿触发,捕捉谐振信号跳变)
void INT0_Init(void) {
    IT0 = 1;      // INT0下降沿触发
    EX0 = 1;      // 使能INT0中断
    EA = 1;       // 使能总中断
    P32 = 1;      // 检测引脚初始置高(高阻输入)
}

// 输出LC谐振启动脉冲(P3.0输出2个窄脉冲)
void LC_Start_Pulse(void) {
    P3M0 = 0x01;  // P3.0推挽输出(仅P3.0配置为推挽,其他为准双向)
    P3M1 = 0x00;
   
    // 输出第一个脉冲(低电平10μs)
    P30 = 0;
    TR0 = 1; while(!TF0); TR0 = 0; TF0 = 0; // 定时1μs,循环10次
    P30 = 1;
    TR0 = 1; while(!TF0); TR0 = 0; TF0 = 0;
   
    // 输出第二个脉冲(低电平10μs)
    P30 = 0;
    TR0 = 1; while(!TF0); TR0 = 0; TF0 = 0;
    P30 = 1;
    TR0 = 1; while(!TF0); TR0 = 0; TF0 = 0;
   
    P3M0 = 0x00;  // 激励完成,P3.0恢复准双向(降低功耗)
}

// 外部中断0服务函数(捕捉谐振信号跳变,计算周期)
void INT0_ISR(void) interrupt 0 {
    static bit edge_flag = 0;  // 跳变沿标志(0:第一次下降沿,1:第二次下降沿)
   
    if(edge_flag == 0) {
        TCON &= 0xCF;  // 清定时器1启停位
        TH1 = 0x00;    // 定时器1清零(用于计数机器周期)
        TL1 = 0x00;
        TR1 = 1;       // 启动定时器1计数
        edge_flag = 1;
    } else {
        TR1 = 0;       // 停止计数
        cycle_cnt = (TH1 << 8) | TL1;  // 读取计数结果(2次跳变的周期)
        edge_flag = 0;
        freq_flag = 1; // 置位频率计算标志
    }
}

// 主函数
void main(void) {
    unsigned long int freq = 0;  // 谐振频率值(单位:Hz)
   
    Timer0_Init();  // 初始化定时器0(用于激励脉冲)
    INT0_Init();    // 初始化外部中断0(用于检测跳变)
   
    LC_Start_Pulse();  // 输出激励脉冲,启动LC自由谐振
   
    while(1) {
        if(freq_flag == 1) {  // 若检测到完整周期
            // 计算频率:晶振11.0592MHz,机器周期=12/11059200 ≈1.085μs
            // 周期=cycle_cnt * 1.085μs,频率=1/(周期*2)(下降沿间隔为半个周期)
            freq = 11059200 / (cycle_cnt * 24);  // 简化计算:11059200/(cycle_cnt*2*12)
            freq_flag = 0;  // 清除标志
            
            // -------------------
            // 此处可添加频率使用逻辑(如串口发送、LED指示等)
            // -------------------
            
            // 若需持续检测,可每隔一段时间重新发送激励脉冲
            // LC_Start_Pulse();
        }
    }
}
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-9-16 22:18 , Processed in 0.111111 second(s), 62 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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