{"id":4636,"date":"2012-04-19T21:47:46","date_gmt":"2012-04-20T01:47:46","guid":{"rendered":"http:\/\/embedded-lab.com\/blog\/?p=4636"},"modified":"2012-07-30T09:29:12","modified_gmt":"2012-07-30T13:29:12","slug":"digital-logic-probe-for-troubleshooting-ttl-and-cmos-circuits","status":"publish","type":"post","link":"https:\/\/embedded-lab.com\/blog\/digital-logic-probe-for-troubleshooting-ttl-and-cmos-circuits\/","title":{"rendered":"Digital logic probe for troubleshooting TTL and CMOS circuits"},"content":{"rendered":"<p>A logic probe is considered as a stethoscope for engineers and technicians for debugging digital logic circuits that consists of logic gates, memories, registers, etc. A digital multimeter (DVM) can also be used for such analytical purposes but it gives you the numeric value of the voltage at a point instead of the logic state. Depending on whether the circuit is based on TTL or CMOS components, the voltage levels for logic 0 and 1 could be different for each family.\u00a0DVM users, thus, have to calculate logic levels from the measured voltages, which consumes time and delays the troubleshooting procedure. A logic probe, on the other hand, does all these functions automatically and shows meaningful logic states at test points. In this project, we will discuss about making a digital logic probe that is applicable to both TTL and CMOS circuits and uses minimal components.<\/p>\n<div id=\"attachment_4637\" style=\"width: 570px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/03\/LogicProbeTitle.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4637\" class=\"size-full wp-image-4637\" title=\"LogicProbeTitle\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/03\/LogicProbeTitle.jpg\" alt=\"\" width=\"560\" height=\"301\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/03\/LogicProbeTitle.jpg 560w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/03\/LogicProbeTitle-550x295.jpg 550w\" sizes=\"auto, (max-width: 560px) 100vw, 560px\" \/><\/a><p id=\"caption-attachment-4637\" class=\"wp-caption-text\">Logic probe for CMOS and TTL circuits<\/p><\/div>\n<p><!--more--><\/p>\n<p><strong>Theory<\/strong><\/p>\n<p>There are mainly two logic families used in digital circuits: TTL and CMOS. While TTL operates at +5V, the power supply for CMOS circuits could range from +3V to 15V. According to the standard TTL convention, any voltage less than 0.8V is defined as logic low while any voltage above 2.2 is defined as logic high and anything in between these extremes is defined as intermediate state. In case of CMOS circuits, any voltage less than 1\/3 of VDD is defined as logic low while any voltage above 2\/3 of VDD is defined as logic high. Any voltage between these values is defined as intermediate or transitional state. This logic probe works for both TTL and CMOS circuits powered from +5V to 15V.<\/p>\n<p>This logic probe consists of a 78L05 voltage regulator, a Microchip PIC12F683 microcontroller, a CD4094BE CMOS shift register and a tiny seven segment display. Since the operating voltage range of this logic probe is between 5 to 15V, the role of the 78L05 voltage regulator is to ensure that the microcontroller and the rest of the circuit are always powered with a stable 5V source. There are two voltage divider networks, each made from a 9.1K\u00a0 and a 1K Ohms (1% tolerance) resistors. The outputs of the two networks go to the ADC channels AN0 and AN1. The AN0 channel reads the logic level voltage of the test pin whereas the AN1 channel is used to measure the supply voltage of the test circuit. The information of the supply voltage is necessary to identify a CMOS circuit powered with &gt; 5V. The GP2, GP4, and GP5 pins of PIC12F683 drives the CD4094 shift register. The shift register acts as an I\/O expander in this application and its outputs are connected to a seven segment display.<\/p>\n<div id=\"attachment_4750\" style=\"width: 560px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/circuit.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4750\" class=\"size-medium wp-image-4750\" title=\"circuit\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/circuit-550x387.png\" alt=\"\" width=\"550\" height=\"387\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/circuit-550x387.png 550w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/circuit-1024x721.png 1024w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/circuit.png 1082w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><p id=\"caption-attachment-4750\" class=\"wp-caption-text\">Circuit diagram of the logic probe (click on image to enlarge)<\/p><\/div>\n<p><em>Note: In the above circuit, pins 8 and 16 of CD4094 should be connected to ground and Vcc, respectively.<\/em><\/p>\n<div id=\"attachment_4742\" style=\"width: 570px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/SetUpLogicProbe.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4742\" class=\"size-full wp-image-4742\" title=\"SetUpLogicProbe\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/SetUpLogicProbe.png\" alt=\"\" width=\"560\" height=\"345\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/SetUpLogicProbe.png 560w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/SetUpLogicProbe-550x338.png 550w\" sizes=\"auto, (max-width: 560px) 100vw, 560px\" \/><\/a><p id=\"caption-attachment-4742\" class=\"wp-caption-text\">Logic probe circuit setup on a breadboard<\/p><\/div>\n<p><strong>Software<\/strong><\/p>\n<p>The software for this project is written in MikroC PRO for PIC version 5.30. Only the ADC built-in library is used. The rest of the code is written without any library aid. The code starts with the definitions of pin names and common variable declarations. Apart from the main function which does all the tasks, there are six functions in the code. The <em>setup() <\/em>function sets directions of I\/O pins and initiates the built-in ADC for data acquisition. The <em>test_display()<\/em> function tests the LEDs of the seven segment display connected to the shift register. The way this is done with the shift register will be discussed later in this text. The feature that makes this logic probe universal and unique is its ability to determine the supply voltage level. In the function <em>test_supply()<\/em>, the power source is tested. During this test if it is found that the ADC average of supply voltage is within the span of 4.75V to 5.25V then the standard TTL minimum high and maximum low logic level voltages are set, otherwise conventional CMOS logic level voltage values are set. These values are kept in the variables called <em>high_level<\/em> and <em>low_level <\/em>and are retained till power down<em>.<\/em> The <em>display(unsigned char val)<\/em> function is a software-hardware link between the shift register and the micro. It converts any 8 bit value given to the variable <em>val<\/em> in a way that it can be sent as an output just like a regular I\/O port. The strobe pin is at first kept low to allow the access of the internal latches of the CD4094. Eight clock pulses are needed to shift data into the latches. During each clock pulse to the shift register, the variable <em>val\u2019s <\/em>most significant bit (MSB) is read first and is sent as a data to the data input of the shift register. After sending data to the data pin, <em>val <\/em>is left shifted once and the clock pin is also toggled once. At the end of eight cycles the strobe pin is pulled high and the display is updated. The <em>adc_avg(unsigned char ch)<\/em> function read the designated ADC channel by taking 16 samples of ADC data and converting these samples into an average voltage value. Lastly the <em>check_logic()<\/em> function checks the logic input and sends logic symbol data to the seven segment display.<\/p>\n<pre>\/\/Definition of shift register pin names\/\/\r\n#define     data_pin        GP5_bit\r\n#define     clock_pin       GP4_bit\r\n#define     strobe_pin      GP2_bit\r\n\r\n\/\/Definition of global variables\/\/\r\nfloat high_level = 0.0;           \/\/minimum logic high voltage value storage\r\nfloat low_level = 0.0;            \/\/maximum logic low voltage value storage\r\nconst unsigned short disp [4] =\r\n{0x38, 0x3E, 0x76, 0x00};         \/\/Symbols for display - L, U, H and blank\r\n\r\n\/\/Function prototypes\/\/\r\nstatic void setup(void);\r\nstatic void test_display(void);\r\nstatic void test_supply(void);\r\nvoid display(unsigned char val);\r\nfloat adc_avg(unsigned char ch);\r\nvoid check_logic(void);\r\n\r\nvoid main(void)\r\n{\r\n    setup();           \/\/Setup the micro for operation\r\n    test_supply();     \/\/Check supply voltage and choose convention\r\n    test_display();    \/\/Check display\r\n    for(;;)             \/\/Infinite loop\r\n    {\r\n            check_logic();   \/\/Test logic level at logic input terminal\r\n    }\r\n}\r\n\r\nstatic void setup(void)\r\n{\r\n     \/\/Set directions and initial states of I\/O pins\/\/\r\n     TRISIO5_bit = 0;\r\n     TRISIO4_bit = 0;\r\n     TRISIO3_bit = 1;\r\n     TRISIO2_bit = 0;\r\n     TRISIO1_bit= 1;\r\n     TRISIO0_bit = 1;\r\n     data_pin = 0;\r\n     strobe_pin = 0;\r\n     clock_pin = 0;\r\n     adc_init();          \/\/Initiate internal ADC module\r\n     delay_ms(100);       \/\/Wait of some time\r\n}\r\n\r\nstatic void test_display(void)\r\n{\r\n     unsigned short test = 0;\r\n     while(test&lt;3)                       \/\/Test seven segment display\r\n     {\r\n                  display(disp[test]);   \/\/Put called symbol on display\r\n                  delay_ms(400);         \/\/Wait for some time\r\n                  test++;                \/\/Continue test\r\n     }\r\n     display(disp[3]);                   \/\/Turn off display\r\n     delay_ms(300);                      \/\/ Wait for some time\r\n}\r\n\r\nstatic void test_supply(void)\r\n{\r\n     register float supply = 0;\r\n     supply = adc_avg(1);                \/\/Take the average of supply voltage\r\n     delay_ms(150);                      \/\/Wait for some time\r\n     if(((supply &gt;= 4.75) &amp;&amp; (supply &lt;= 5.25)))   \/\/TTL convention test\r\n     {\r\n                     high_level = 2.2;\r\n                     low_level = 0.8;\r\n     }                                            \/\/CMOS convention test\r\n     else\r\n     {\r\n                     high_level = (supply*0.67);\r\n                     low_level = (supply*0.33);\r\n     }                                            \/\/Wait for a while\r\n     delay_ms(50);\r\n}\r\n\r\nvoid display(unsigned char val)\r\n{\r\n    unsigned short clk = 0;\r\n    unsigned short d = 0;\r\n    strobe_pin = 0;                               \/\/Hold strobe pin low\r\n    for(clk = 0; clk &lt; 8; clk++)                  \/\/Do following job eight times\r\n    {\r\n        d = (0x80 &amp; val);                         \/\/Read the MSB of val\r\n        if(d == 0)                                \/\/If the MSB is zero\r\n        {\r\n             data_pin = 0;                        \/\/then send 0\r\n        }\r\n        else                                      \/\/otherwise send 1\r\n        {\r\n             data_pin = 1;\r\n        }\r\n        clock_pin = 1;                            \/\/Pull clock pin high\r\n        delay_ms(1);                              \/\/Wait for a while\r\n        val = val &lt;&lt; 1;                           \/\/Left shift val\r\n        clock_pin = 0;                            \/\/Hold clock pin low\r\n        delay_ms(1);                              \/\/Wait for a while\r\n    }\r\n    strobe_pin = 1;                               \/\/Pull strobe pin high\r\n    delay_ms(1);                                  \/\/Wait for a while\r\n}\r\n\r\nfloat adc_avg(unsigned char ch)\r\n{\r\n         register unsigned int temp = 0;\r\n         unsigned short samples = 0;\r\n         register float avg = 0;\r\n         delay_ms(1);\r\n         for(samples = 1; samples &lt;= 16; samples += 1)   \/\/Take 16 ADC samples\r\n         {\r\n                         temp = adc_read(ch);            \/\/Read assigned ADC\r\n                         temp += temp;                   \/\/channel data and\r\n                         delay_us(25);                   \/\/store temporarily\r\n         }\r\n         avg = (temp * 5.0);                            \/\/Convert to readable\r\n         avg \/= 1023.0;                                 \/\/value other than count\r\n         avg *= 10.0;                                   \/\/Take voltage divider\r\n         avg \/= 16.0;                                   \/\/and number of samples\r\n         return avg;                                    \/\/into account\r\n}\r\n\r\nvoid check_logic(void)\r\n{\r\n        register float vin = 0;\r\n        vin = adc_avg(0);                   \/\/Read logic input channel\r\n        delay_ms(20);                       \/\/Wait for some time\r\n        if(vin &gt;= high_level)               \/\/Check if it is high\r\n        {\r\n            display(disp[2]);               \/\/Send 'H' to display\r\n        }\r\n        else if(vin &lt;= low_level)           \/\/Check if it is low\r\n        {\r\n            display(disp[0]);               \/\/Send 'L' to display\r\n        }\r\n        else                                \/\/Otherwise it is undefined\r\n        {\r\n            display(disp[1]);               \/\/Toggle and send 'U' to display\r\n            delay_ms(400);\r\n            display(disp[3]);\r\n            delay_ms(400);\r\n        }\r\n}<\/pre>\n<p><a href=\"http:\/\/embedded-lab.com\/uploads\/HexFiles\/ShawonS\/ULP.zip\"><strong>Download source and HEX files<\/strong><\/a><\/p>\n<p><strong>Operation<\/strong><\/p>\n<p>The logic probe discussed here is very simple to operate. It should be powered by the power supply of any circuit which it will test. After power up and initial tests, it is ready for normal use. To check logic level at any point, the logic input terminal is just held at a point and the device reads the logic level at that point. It will show H, U or L which mean logic High, Undefined or intermediate or logic Low.<\/p>\n<div id=\"attachment_4743\" style=\"width: 570px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/LogicProbeOP.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4743\" class=\"size-full wp-image-4743\" title=\"LogicProbeOP\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/LogicProbeOP.png\" alt=\"\" width=\"560\" height=\"326\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/LogicProbeOP.png 560w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2012\/04\/LogicProbeOP-550x320.png 550w\" sizes=\"auto, (max-width: 560px) 100vw, 560px\" \/><\/a><p id=\"caption-attachment-4743\" class=\"wp-caption-text\">Logic probe displays H, L and U for logic states High, Low and Undefined, respectively<\/p><\/div>\n<p><strong>Conclusion<\/strong><\/p>\n<p>In this project not only a logic probe is designed but it was also discussed how to expand outputs of a small micro with an inexpensive shift register. Thus the maximum utility of a small micro is achieved. I\/O ports can also be expanded with multiplexer, parallel-input-serial-output (PISO) registers, decoders, encoders and universal shift registers as well as dedicated port expanders like MCP23008, 8255, etc. The seven segment display could also have been driven using several diodes but this technique required a large number of diodes.<\/p>\n<p><strong>Note:<\/strong> The datasheet of 78L05 regulator recommends that the input voltage should be greater than 7V to achieve a regulated +5V output. In our application, when the test circuit is a standard TTL, the supply voltage is only 5V, and as such the output of 78L05 is slightly less than 5V. This introduces some error in ADC calculations which is significantly less compared to the band difference between logic HIGH and LOW, and therefore doesn&#8217;t affect the operation of the logic probe. The logic probe circuit discussed here was tested in real life under various conditions and results were satisfactory for both TTL and CMOS circuits. I designed this project in a bread board as it was my prototype. A PCB or strip board version of it would have been much smaller than what is shown here.<\/p>\n<table style=\"width: 560px;\" border=\"0\" cellspacing=\"5\" cellpadding=\"2\" align=\"center\">\n<tbody>\n<tr>\n<td style=\"border-color: #cccccc; background-color: #fdfdfd;\">This project was written by Shawon Shahryiar from Bangladesh. He works as an Engineer in the Research and Development Cell at ELECTRO Group in Dhaka. If you have any questions or concerns regarding this project, you can contact him at:<br \/>\n<img decoding=\"async\" src=\"http:\/\/embedded-lab.com\/uploads\/images\/ShawonEmail.png\" alt=\"\" \/><\/td>\n<td style=\"border-color: #cccccc; background-color: #fdfdfd;\"><img decoding=\"async\" src=\"http:\/\/embedded-lab.com\/uploads\/images\/Shawon.jpg\" alt=\"\" \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n","protected":false},"excerpt":{"rendered":"<p>A logic probe is considered as a stethoscope for engineers and technicians for debugging digital logic circuits that consists of logic gates, memories, registers, etc. A digital multimeter (DVM) can also be used for such analytical purposes but it gives you the numeric value of the voltage at a point instead of the logic state. Depending on whether the circuit is based on TTL or CMOS components, the voltage levels for logic 0 and 1 could be different for each family.\u00a0DVM users, thus, have to calculate logic levels from the measured voltages, which consumes time and delays the troubleshooting procedure.<\/p>\n","protected":false},"author":1,"featured_media":4637,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[413,412,6],"class_list":["post-4636","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-pic-projects","tag-digital-probe","tag-logic-probe","tag-pic12f683"],"_links":{"self":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/4636","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/comments?post=4636"}],"version-history":[{"count":12,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/4636\/revisions"}],"predecessor-version":[{"id":4755,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/4636\/revisions\/4755"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/media\/4637"}],"wp:attachment":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/media?parent=4636"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/categories?post=4636"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/tags?post=4636"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}