手工打造的逻辑分析探头

原创 电子森林 2021-08-15 22:47

这是发布在Hackster.io上的一个项目,作者为John Bradnam,一个很小的分析仪能分析CMOS和TTL电路,能够测量5种状态,检测脉冲并针对不同的状态播放不同的声音。


国外的玩家没有我们方便,做个PCB是件很折腾的事情,因此简单的电路都要想办法手工打造。


下面就是这个项目的简单介绍:


在此之前,作者尝试做过多种不同的逻辑分析探针,看下图是作者多年来设计的一些作品:

作者认为应该设计一款终极的逻辑探针,具有如下的一些特点:

  • 它必须足够小以方便拿在手中

  • 能够显示低、高和不关心的状态

  • 一个显示系统,在使用时易于阅读

  • 对“低”和“高”状态有声音反馈

  • 处理不同逻辑系列的器件,例如:TTL 和 CMOS

  • 能够检测探头是否正在测量快速变化的信号

  • 具有针对意外过电压的输入保护

硬件的设计

采用了ATtiny1614位微处理器,通过一个7段数码管进行显示测量的电压,并驱动一个扬声器发出声音,轻触开关切换不同的逻辑系列,一个3.3V的稳压器给微处理器提供电源,原理图见下(使用Eagle绘制)


这个设计中用到的器件主要有:

微芯科技 ATtiny1614 x1
TSS-307EWA 7-Seg 0.36in CC 显示器x1
LM1117-33 3.3V 稳压器(SOT-223封装)x1
C&K 开关 PTS 645 系列开关(6mm轴)x1
SMT-916喇叭x1
3.6V 400mW 齐纳二极管(SOD80C 封装)x2
1N4007 – 高电压、高额定电流二极管(SOD-123 包装)x2 
无源元件:5 个 180R 0805、1 个 91R 0805、2 个 1K 0805、2 个 3K 0805、1 个 15K 0805 电阻器;2 x 0.1uF 0805, 1 x 10uF 0805, 1 x 100uF/10V 7343 电容器


作者制作了一个PCB,单面板,主要器件都是表面贴装的。7段数码管和电路板成直角安装。

该探针是高度可以配置的,允许添加其它的逻辑系列器件,见下面程序中的截图部分:

下面是制作的PCB,在国外制作PCB还是很不方便的。


将缝衣针绑上做探针:

焊上7段数码管:

装上开关和电源连线:

作者用一个Arduino Nano来对其进行编程:

使用Arduino的IDE:


下面是这个逻辑分析探针的代码:

/************************************************************************** ATtiny1614 Logic Probe
Schematic & PCB at https://www.hackster.io/john-bradnam/contact-digital-thermometer-ed18d2 2021-08-10 John Bradnam (jbrad2089@gmail.com) Create program for ATtiny1614
-------------------------------------------------------------------------- Arduino IDE: -------------------------------------------------------------------------- BOARD: ATtiny1614/1604/814/804/414/404/214/204 Chip: ATtiny1614 Clock Speed: 20MHz millis()/micros(): "Enabled (default timer)" Programmer: jtag2updi (megaTinyCore)
ATTiny1614 Pins mapped to Ardunio Pins +--------+ VCC + 1 14 + GND (SS) 0 PA4 + 2 13 + PA3 10 (SCK) 1 PA5 + 3 12 + PA2 9 (MISO) (DAC) 2 PA6 + 4 11 + PA1 8 (MOSI) 3 PA7 + 5 10 + PA0 11 (UPDI) (RXD) 4 PB3 + 6 9 + PB0 7 (SCL) (TXD) 5 PB2 + 7 8 + PB1 6 (SDA) +--------+ **************************************************************************/
//Debug mode will use the TX pin to send serial messages. As this is also used//for Segment A, the display is disabled when DEBUG mode is enabled//#define DEBUG
//Display Pins#define A_PIN 5 //PB2#define B_PIN 4 //PB3#define C_PIN 3 //PA7#define D_PIN 0 //PA4#define EF_PIN 1 //PA5#define G_PIN 2 //PA6
//Inputs#define VIN_PIN 9 //PA2#define PROBE_PIN 8 //PA1#define MODE_PIN 10 //PA3
#define ADC_PROBE ADC_MUXPOS_AIN1_gc#define ADC_VIN ADC_MUXPOS_AIN2_gc

//Outputs#define SPKR_PIN 6 //PB1
//Frequency for different states#define VDD_TONE 1760#define HIGH_TONE 880#define LOW_TONE 220#define GND_TONE 110#define BTN_TONE 440
//Pin and mask mapping tabletypedef struct { int8_t pin; int8_t mask;} SEG;
#define SEG_COUNT 6SEG segments[] = { {A_PIN, B00000001}, {B_PIN, B00000010}, {C_PIN, B00000100}, {D_PIN, B00001000}, {EF_PIN, B00010000}, {G_PIN, B00100000}};
//Character set#define CHAR_COUNT 10#define CHAR_SPACE 0#define CHAR_VDD 1#define CHAR_HIGH 2#define CHAR_FLOAT 3#define CHAR_LOW 4#define CHAR_GND 5#define CHAR_PULSE 6#define CHAR_CMOS 7#define CHAR_TTL 8#define CHAR_LS 9
uint8_t charset[] = { B00000000, //CHAR_SPACE B00000001, //CHAR_VDD B00000110, //CHAR_HIGH B00100000, //CHAR_FLOAT B00011111, //CHAR_LOW B00001000, //CHAR_GND B00110011, //CHAR_PULSE B00011001, //CHAR_CMOS B00111000, //CHAR_TTL B00011000 //CHAR_LS};
char debugset[] = { ' ', //CHAR_SPACE '+', //CHAR_VDD '1', //CHAR_HIGH '?', //CHAR_FLOAT '0', //CHAR_LOW '-', //CHAR_GND 'P', //CHAR_PULSE 'C', //CHAR_CMOS 'T', //CHAR_TTL 'L' //CHAR_LS};
typedef struct { float low; //Maximum voltage a LOW state can be (fixed voltage) float high; //Minumum voltage a HIGH state can be as a percentage of VDD uint8_t chr; //Character to display for this family} FAMILY;
//This table defines the voltage levels for each family that the probe can measure#define NUMBER_OF_FAMILIES 3FAMILY families[NUMBER_OF_FAMILIES] = { {0.8,80,CHAR_CMOS}, //CMOS family with tones {0.4,48,CHAR_TTL}, //0.4, 2.4 (1987 - National LS S TTL Logic Databook) {0.5,54,CHAR_LS} //0.5, 2.7 (1987 - National LS S TTL Logic Databook)};
enum STATES { STATE_UNKNOWN, STATE_VDD, STATE_HIGH, STATE_FLOAT, STATE_LOW, STATE_GND, STATE_PULSE };
#define PULSE_PERIOD 100 //Maximum time between state changes to be detected as a pulse (1/2 the period => 5Hz)
uint8_t activeFamily = 0; //Current chip family being testedSTATES lastState = STATE_UNKNOWN; //Last state measuredSTATES activeState = STATE_UNKNOWN; //Current state at probefloat supplyVoltage = 0; //VDD from 3V3 regulatorfloat probeVoltage = 0; //Last reading from probefloat vinVoltage = 0; //Last reading from VINlong pulseTimeout = 0; //Timer used to measure pulsesbool waitingOnChange = false; //Enabled when waiting on pulseTimeoutbool soundEnabled = false; //Whether tones are played for the states
//-------------------------------------------------------------------------// Initialise Hardwarevoid setup(void){ for (int i = 0; i < SEG_COUNT; i++) { pinMode(segments[i].pin, OUTPUT); digitalWrite(segments[i].pin, LOW); }
#ifdef DEBUG Serial.begin(115200); #endif
pinMode(VIN_PIN, INPUT); pinMode(PROBE_PIN, INPUT); pinMode(MODE_PIN, INPUT_PULLUP); pinMode(SPKR_PIN, OUTPUT);
//Setup ADC VREF.CTRLA = VREF_ADC0REFSEL_1V1_gc; ADC0.CTRLC = ADC_REFSEL_VDDREF_gc | ADC_PRESC_DIV256_gc; // 78kHz clock ADC0.CTRLA = ADC_ENABLE_bm; // Single, 10-bit
measureSupplyVoltage();}
//--------------------------------------------------------------------// Main program loopvoid loop(void){ if (buttonPressed()) { activeFamily++; if (activeFamily == NUMBER_OF_FAMILIES) { activeFamily = 0; soundEnabled = !soundEnabled; //Turn/off audio } showChar(families[activeFamily].chr); noTone(SPKR_PIN); if (soundEnabled) { tone(SPKR_PIN, BTN_TONE); } waitForButtonRelease(); noTone(SPKR_PIN);
//Force an update waitingOnChange = false; lastState = STATE_UNKNOWN; } testProbe();}
//--------------------------------------------------------------------// Test if button pressedbool buttonPressed(){ bool result = false; if (digitalRead(MODE_PIN) == LOW) { delay(10); //Debounce return (digitalRead(MODE_PIN) == LOW); } return result;}
//--------------------------------------------------------------------// Wait until the button is releasedvoid waitForButtonRelease(){ while (digitalRead(MODE_PIN) == LOW) ;}
//--------------------------------------------------------------------// Measure the voltages and dislay the results if changedvoid testProbe(){ //Voltages are feed through divide by 4 resistor voltage converter //so they need to multiplied by 4. probeVoltage = measureVoltage(ADC_PROBE) * 4; vinVoltage = measureVoltage(ADC_VIN) * 4;
//Calculate HIGH and VDD thresholds from VIN voltage float vdd = vinVoltage - 0.1; float high = families[activeFamily].high * vinVoltage / 100; bool pulse = false; //Workout state if (probeVoltage < 0.1) { activeState = STATE_GND; } else if (probeVoltage <= families[activeFamily].low) { activeState = STATE_LOW; } else if (probeVoltage < high) { activeState = STATE_FLOAT; } else if (probeVoltage <= vdd) { activeState = STATE_HIGH; } else { activeState = STATE_VDD; }
if (activeState != lastState) //Only do something if state changes { #ifdef DEBUG Serial.println("p=" + String(probeVoltage) + ", vin=" + String(vinVoltage) + ", vdd=" + String(supplyVoltage)); delay(200); #endif if ((activeState == STATE_HIGH) ^ (lastState == STATE_HIGH)) //Change in state from either LOW to HIGH or HIGH to LOW { pulse = (waitingOnChange && millis() < pulseTimeout); //If state change within PULSE_PERIOD signal it as a pulse pulseTimeout = millis() + PULSE_PERIOD; //Set next timeout waitingOnChange = true; //and signal we are waiting on a state change } else { //This isn't a pulse waitingOnChange = false; pulse = false; }
//Turn off any sound from the last state noTone(SPKR_PIN);
//Show the result int chr = (pulse) ? CHAR_PULSE : (uint8_t)activeState; showChar(chr);
if (soundEnabled) //Play sound if enabled { switch(chr) { case CHAR_VDD: tone(SPKR_PIN, VDD_TONE); break; case CHAR_HIGH: tone(SPKR_PIN, HIGH_TONE); break; case CHAR_LOW: tone(SPKR_PIN, LOW_TONE); break; case CHAR_GND: tone(SPKR_PIN, GND_TONE); break; } }
//Record last state lastState = activeState; }}
//--------------------------------------------------------------------// Display character on 7 segment display// chr - character to show (0 <= chr < CHAR_COUNT)void showChar(uint8_t chr){ if (chr < CHAR_COUNT) { #ifdef DEBUG Serial.println(debugset[chr]); #else uint8_t mask = charset[chr]; for (int i = 0; i < SEG_COUNT; i++) { digitalWrite(segments[i].pin, (mask & segments[i].mask) ? HIGH : LOW); } #endif } }
//--------------------------------------------------------------------------// Measure supply voltage// Source: David Johnson-Davies - www.technoblogy.com - 13th April 2021void measureSupplyVoltage() { ADC0.MUXPOS = ADC_MUXPOS_INTREF_gc; // Measure INTREF ADC0.COMMAND = ADC_STCONV_bm; // Start conversion while (ADC0.COMMAND & ADC_STCONV_bm); // Wait for completion uint16_t adc_reading = ADC0.RES; // ADC conversion result supplyVoltage = 1126.4 / adc_reading;}
//--------------------------------------------------------------------------// Measure voltage of a given pin// adcMux - ADC_Ax constant for the pin to measurefloat measureVoltage(uint8_t adcMux) { ADC0.MUXPOS = adcMux; // Measure Analog pin ADC0.COMMAND = ADC_STCONV_bm; // Start conversion while (ADC0.COMMAND & ADC_STCONV_bm); // Wait for completion uint16_t adc_reading = ADC0.RES; // ADC conversion result return supplyVoltage * adc_reading / 1024;}


点击左下角的“阅读原文”跳转到Hackster.io上的英文原文。


硬禾小帮手 - 硬件工程师的设计助手

硬禾学堂 - 硬件工程师的在线学习平台

电子森林 讲述电子工程师需要掌握的重要技能: PCB设计、FPGA应用、模拟信号链路、电源管理等等;不断刷新的行业新技术 - 树莓派、ESP32、Arduino等开源系统;随时代演进的热点应用 - 物联网、无人驾驶、人工智能....
评论
  • 国产光耦合器正以其创新性和多样性引领行业发展。凭借强大的研发能力,国内制造商推出了适应汽车、电信等领域独特需求的专业化光耦合器,为各行业的技术进步提供了重要支持。本文将重点探讨国产光耦合器的技术创新与产品多样性,以及它们在推动产业升级中的重要作用。国产光耦合器创新的作用满足现代需求的创新模式新设计正在满足不断变化的市场需求。例如,高速光耦合器满足了电信和数据处理系统中快速信号传输的需求。同时,栅极驱动光耦合器支持电动汽车(EV)和工业电机驱动器等大功率应用中的精确高效控制。先进材料和设计将碳化硅
    克里雅半导体科技 2024-11-29 16:18 163浏览
  • 在电子技术快速发展的今天,KLV15002光耦固态继电器以高性能和强可靠性完美解决行业需求。该光继电器旨在提供无与伦比的电气隔离和无缝切换,是现代系统的终极选择。无论是在电信、工业自动化还是测试环境中,KLV15002光耦合器固态继电器都完美融合了效率和耐用性,可满足当今苛刻的应用需求。为什么选择KLV15002光耦合器固态继电器?不妥协的电压隔离从本质上讲,KLV15002优先考虑安全性。输入到输出隔离达到3750Vrms(后缀为V的型号为5000Vrms),确保即使在高压情况下,敏感的低功耗
    克里雅半导体科技 2024-11-29 16:15 119浏览
  • RDDI-DAP错误通常与调试接口相关,特别是在使用CMSIS-DAP协议进行嵌入式系统开发时。以下是一些可能的原因和解决方法: 1. 硬件连接问题:     检查调试器(如ST-Link)与目标板之间的连接是否牢固。     确保所有必要的引脚都已正确连接,没有松动或短路。 2. 电源问题:     确保目标板和调试器都有足够的电源供应。     检查电源电压是否符合目标板的规格要求。 3. 固件问题: &n
    丙丁先生 2024-12-01 17:37 59浏览
  • 艾迈斯欧司朗全新“样片申请”小程序,逾160种LED、传感器、多芯片组合等产品样片一触即达。轻松3步完成申请,境内免费包邮到家!本期热荐性能显著提升的OSLON® Optimal,GF CSSRML.24ams OSRAM 基于最新芯片技术推出全新LED产品OSLON® Optimal系列,实现了显著的性能升级。该系列提供五种不同颜色的光源选项,包括Hyper Red(660 nm,PDN)、Red(640 nm)、Deep Blue(450 nm,PDN)、Far Red(730 nm)及Ho
    艾迈斯欧司朗 2024-11-29 16:55 163浏览
  • 戴上XR眼镜去“追龙”是种什么体验?2024年11月30日,由上海自然博物馆(上海科技馆分馆)与三湘印象联合出品、三湘印象旗下观印象艺术发展有限公司(下简称“观印象”)承制的《又见恐龙》XR嘉年华在上海自然博物馆重磅开幕。该体验项目将于12月1日正式对公众开放,持续至2025年3月30日。双向奔赴,恐龙IP撞上元宇宙不久前,上海市经济和信息化委员会等部门联合印发了《上海市超高清视听产业发展行动方案》,特别提到“支持博物馆、主题乐园等场所推动超高清视听技术应用,丰富线下文旅消费体验”。作为上海自然
    电子与消费 2024-11-30 22:03 76浏览
  • 最近几年,新能源汽车愈发受到消费者的青睐,其销量也是一路走高。据中汽协公布的数据显示,2024年10月,新能源汽车产销分别完成146.3万辆和143万辆,同比分别增长48%和49.6%。而结合各家新能源车企所公布的销量数据来看,比亚迪再度夺得了销冠宝座,其10月新能源汽车销量达到了502657辆,同比增长66.53%。众所周知,比亚迪是新能源汽车领域的重要参与者,其一举一动向来为外界所关注。日前,比亚迪汽车旗下品牌方程豹汽车推出了新车方程豹豹8,该款车型一上市就迅速吸引了消费者的目光,成为SUV
    刘旷 2024-12-02 09:32 69浏览
  • 《高速PCB设计经验规则应用实践》+PCB绘制学习与验证读书首先看目录,我感兴趣的是这一节;作者在书中列举了一条经典规则,然后进行详细分析,通过公式推导图表列举说明了传统的这一规则是受到电容加工特点影响的,在使用了MLCC陶瓷电容后这一条规则已经不再实用了。图书还列举了高速PCB设计需要的专业工具和仿真软件,当然由于篇幅所限,只是介绍了一点点设计步骤;我最感兴趣的部分还是元件布局的经验规则,在这里列举如下:在这里,演示一下,我根据书本知识进行电机驱动的布局:这也算知行合一吧。对于布局书中有一句:
    wuyu2009 2024-11-30 20:30 91浏览
  • 光耦合器作为关键技术组件,在确保安全性、可靠性和效率方面发挥着不可或缺的作用。无论是混合动力和电动汽车(HEV),还是军事和航空航天系统,它们都以卓越的性能支持高要求的应用环境,成为现代复杂系统中的隐形功臣。在迈向更环保技术和先进系统的过程中,光耦合器的重要性愈加凸显。1.混合动力和电动汽车中的光耦合器电池管理:保护动力源在电动汽车中,电池管理系统(BMS)是最佳充电、放电和性能监控背后的大脑。光耦合器在这里充当守门人,将高压电池组与敏感的低压电路隔离开来。这不仅可以防止潜在的损坏,还可以提高乘
    腾恩科技-彭工 2024-11-29 16:12 119浏览
  • 国产光耦合器因其在电子系统中的重要作用而受到认可,可提供可靠的电气隔离并保护敏感电路免受高压干扰。然而,随着行业向5G和高频数据传输等高速应用迈进,对其性能和寿命的担忧已成为焦点。本文深入探讨了国产光耦合器在高频环境中面临的挑战,并探索了克服这些限制的创新方法。高频性能:一个持续关注的问题信号传输中的挑战国产光耦合器传统上利用LED和光电晶体管进行信号隔离。虽然这些组件对于标准应用有效,但在高频下面临挑战。随着工作频率的增加,信号延迟和数据保真度降低很常见,限制了它们在电信和高速计算等领域的有效
    腾恩科技-彭工 2024-11-29 16:11 106浏览
  • 学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&
    youyeye 2024-11-30 14:30 65浏览
  • 光伏逆变器是一种高效的能量转换设备,它能够将光伏太阳能板(PV)产生的不稳定的直流电压转换成与市电频率同步的交流电。这种转换后的电能不仅可以回馈至商用输电网络,还能供独立电网系统使用。光伏逆变器在商业光伏储能电站和家庭独立储能系统等应用领域中得到了广泛的应用。光耦合器,以其高速信号传输、出色的共模抑制比以及单向信号传输和光电隔离的特性,在光伏逆变器中扮演着至关重要的角色。它确保了系统的安全隔离、干扰的有效隔离以及通信信号的精准传输。光耦合器的使用不仅提高了系统的稳定性和安全性,而且由于其低功耗的
    晶台光耦 2024-12-02 10:40 70浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦