Design of simple serializer for serial port  - Page 1
Forum section: electronics / beginners

author: juanfermed
author_rank: Regular Contributor
timestamp: May 21, 2013, 04:55:56 pm
content: Hi everyone! As the title says, I have to design a simple serializer (if that is the correct name) or serial transmitter for the serial port of a computer. The thing is I need to send 10 bits ( 1 start bit, 8 data bits, 1 stop bit) to a computer using its serial port, at a baud rate of 9600. I cannot use a microcontroller to make this, the implementation must be using simple discrete digital logic (gates, flip flops, mux).I have 8 bits of data in parallel that I must send when an external "send" pulse is given, and they have to be send serially.I have come with an idea using 10 D-type flip flop with asynchronous preset/clear, to which I load the 8 bits of data using an external pulse from an ADC, and the start and stop bits to the two other flip flops. The load is through the asynchronous preset/clear. After loading the data, I generate a pulse which enables the clock signal for the Flip Flops (a monostable oscillator), which is at 9600 Hz,and after the necesary time this clock enable signal turns off, thus stoping the serial data being sent.I will be uploading the schematic soon, but I would thank anyone that has any other idea or comments about this, or any other simpler way to doing this, or that has any previous experience design a similar circuit.Thanks!!!

author: free_electron
author_rank: Super Contributor
timestamp: May 21, 2013, 05:14:01 pm
content: 10 bit shift register clocked at 9600 hz...simple

author: FrankBuss
author_rank: Unknown
timestamp: May 21, 2013, 05:23:30 pm
content: Quote from: free_electron on May 21, 2013, 05:14:01 pmThere is a 10 bit shift register chip? Of course, you can cascade more than one shift register. But you still need to generate some control signals for latching the ADC at the right time. I guess I would use just a 4017 and a 74373 instead of a shift register and a bunch of ANDs, ORs etc.But why not using a microcontroller? With a PIC it is like 10 lines of C code, and it includes the ADC all in one chip. Needs just an external oscillator.

author: PA0PBZ
author_rank: Super Contributor
timestamp: May 21, 2013, 05:28:31 pm
content: 10 bit shift register... maybe difficult but as long as it is at least 10 bits - no problem.http://users.ece.utexas.edu/~valvano/Datasheets/74F676.pdfAnd 4017? How are you going to parallel load that?

author: mikes
author_rank: Regular Contributor
timestamp: May 21, 2013, 06:41:52 pm
content: A multi-bit shift register hardly fits the requirement "simple discrete digital logic (gates, flip flops, mux)." This sounds like a class assignment, otherwise you'd just use a micro or a UART.5x 74742x 74043x 7400Here's the basic circuit:You don't necessarily need a stop bit. If you don't send one immediately after another, the idle time ("marking time") will include the stop bit.

author: FrankBuss
author_rank: Unknown
timestamp: May 21, 2013, 07:01:23 pm
content: Quote from: PA0PBZ on May 21, 2013, 05:28:31 pmMy idea was to use the 4017 as a state machine. For example on output 1, the 74373 is loaded. Then ANDing the other outputs of the 4017 with the 74373 outputs in turn. But a combination of a 4017 and a 74676 might be the solution with the fewest chips. The output 1 of the 4017 just resets the shift register and loads a new byte, and while the other 9 states are clocked, the shift register transfers the byte (and the stop/start bit).But right, might be a class assignment. But if not specified in more details, for me all 40* and 74* chips are "simple discrete logic"

author: juanfermed
author_rank: Regular Contributor
timestamp: May 22, 2013, 08:41:59 am
content: Hi everyone! Thanks for your comments and really neat ideas!@free_electron, as FrankBuss correctly pointed, the 10 bit shit register clocked at 9600hz is not enough as the timing for loading the data to the shift register is a tricky part too.@FrankBuss I thought it was not possible to get rid of the shift registers, as the serial nature of the data to be sent implies that data somehow needed to be queued through only one pin, but your idea just makes it. If I am not wrong, the principle was clocking the 4017 at 9600 hz, which would enable the data load of the 74373 and each clock would enable consecutive pins and corresponding outputs of the 74373, through ANDs, in order to make them appear in one only output of a combinational logic circuit. The 74F676 PA0PBZ suggested just makes the work easy, and I think I might use it, with the only problem that I find it really hard to find that cheap here in my country, so your solution still stands for me. I will have to analyze how big the combinational logic would be in order to know wheter or not it is cheaper and smaller than mikes solution.@mikes, I though something like your solution, but using OR gates instead of NANDs, but the idea is just the same. I find this the more straight forward way to do it, but, please correct me if I im wrong, I think I need to load the stop bit because the idle state of the line is "low" and the start bit is indicated by a transition to high state, so the last bit I should send must be a zero in order to leave the line in low state and to still set it in low state when I load any data. For example, if when I load that first bit, the start bit that is a "1", and do not send the data inmediately, the receiver might think that I started a communication, but I didnt, I just loaded data to my shift registers. Am I right?Thanks for your help! I was thinking any other way to do it but I couldnt come with anything simpler, and you just pointed out other solutions! I think also the 74F676 is the simplest one, but no electronics store here sells that kind of magic.BTW, yes, this is a class asignment, we were said to implement serial transmit and receive of data from some sensors and some motors, but without using any kind of programmable logic or microcontroller, ehh requirement. That is why I cannot use it, on the other hand, its fun to think on non conventional solutions to this stuff.Thanks a lot! Sorry for my bad english

author: juanfermed
author_rank: Regular Contributor
timestamp: May 22, 2013, 08:47:22 am
content: Also, when I was looking for any kind of solution to this in google, I used the word "serializer" but the kind of stuff I got was "LVDS", "Gbps", "high bandwitdh data rates", "Clock recovery circuits through PLL" and a lot of stuff like that, which I dont really understood. What is the correct name for a circuit like this? Is there any?

author: hlavac
author_rank: Frequent Contributor
timestamp: May 22, 2013, 10:01:05 am
content: In what form is your input? 8 Parallel bits? Do you have suitable clock for the 9600 baud rate already?There are parallel load, serial out shift registers like 74HC165 that would be ideal for you (this one is 8-bit, but you can cascade two), would probably be still cheaper than obscure 10 bit oneUnless you need to only use gates, in which case you probably would not be OK using 74*74 D flip flops as well, good luck with all these gates...

author: hlavac
author_rank: Frequent Contributor
timestamp: May 22, 2013, 10:06:58 am
content: Quote from: mikes on May 21, 2013, 06:41:52 pmI don't agree, logic level at the idle time matters, it must be opposite to start bit, simple waiting would leave the last bit on the line and 50% chance the next bytes start bit will fail to register.

author: PA0PBZ
author_rank: Super Contributor
timestamp: May 22, 2013, 10:54:34 am
content: Quote from: hlavac on May 22, 2013, 10:06:58 amNo no, the idle time is the same polarity as the stop bit; the stop bit is nothing more than saying that the idle time should be at least the length of one bit.

author: mikes
author_rank: Regular Contributor
timestamp: May 22, 2013, 12:01:05 pm
content: Quote from: juanfermed on May 22, 2013, 08:41:59 amFirst, levels in serial EIA232 can get confusing. On the interface, low voltage = 1 = "mark". But, you'll need to use a TTL-EIA232 converter, almost all of which invert things.You tie the D input of the most significant FF to Vcc, so after everything is clocked through, the output sits at 1. After conversion to 232, it's marking time.But, yes, you are going to have to put a "1" bit as the first one output, for synchronization. UARTs usually do this by using a 16x clock, and not clocking out while the register is being loaded - so the first bit is always within 1/16 of the correct length. But you can also do that by using a 1x clock and just clocking out a mark bit first. As long as the line was marking before, it doesn't matter how long that first bit is, it will just be taken as additional marking time.That's different than a stop bit. You're going to have to do something to ensure the shift register won't get loaded until the last load is completely clocked out, so you might as well accommodate a stop bit in that timing.So, in the shift register, you'd load 10 bits (and feed "mark" into data7)data7...data1data0Start bitIdle/sync bitBut you can't do that more often than every 11 clock cycles. I'd probably just do a 4 bit counter, and make things happen every 16 clock cycles.

author: free_electron
author_rank: Super Contributor
timestamp: May 22, 2013, 03:19:00 pm
content: Quote from: juanfermed on May 22, 2013, 08:41:59 amHaven't done any homework , or thought about what i said , have you ?ask yourself these questions :What does a serial port look like when it is in idle ? what is it transmitting ? a 1 ? a 0 ?So, to reiterate what i said :Take a 10 bit parallel loadable , serial in , serial out shift register. if you can;t find a 10 bit , make a 12 bit out of 3 four bitters .Connect serial in to the logic level that is to be transmitted in idle.Connect bit 0 to the polarity of the start bit, connect bits 1 to 8 to the data you want to transmit and connect bit 9 to the stop bit polarity.Connect the remaining parallel inputs to the logic level transmitted in idle.Keep the clock running at all times at 9600 baud.The shift register now simply cycles the idle bits through its pipe..The moment you perform a 'parallel write' operation the pipe gets overwritten by your data + start bit + stop bit and the clock ( which is always running does the rest. the load is asynchronous on these shifters. as long as you hold load the data does not move... since the pipe always begins with 'idle' this has the net effect of not doing anything on the serial pin. no corruption occurs.No need for any stinking counters , no stinking state machines , no stinking and ,or, not, xor, or stinking xnor gates. you don't need anything. you don't even need synchronisation to the 9600 clock. You can be faster or slower. As long as the load pin is active the data does not move in the shift register so the 'idle' level is being broadcast. Only at deassertion of the load pin does the packet begin moving.Just a 9600 hz clock and a parallel loadable shift register that has enough flipflops to hold 8 bit data + start bit + stop bit.Code:module simple_tx_uart (input clk9600, serial_in , input [7:0] data_in , output serial_out . input write)`define idle 1`define startbit 0`define stopbit 1reg [11:0] shifter;assign serial_out = shifter;always_ff @(posegde clk_9600) beginshifter [11:0] <= {shifter 10:0, `idle};if (load) shifter[11:0] = {`idle,`idle,`startbit, data_in[7:0], `stopbit};endmodulethere you go.in TTL :- take 2 74LS165- tie the two pin's 1 together. this is your load input- tie the two pins 2 together and feed this a 9600 Hz ttl compatible square wave- tie all pins 8 to ground- tie all pins 16 to 5 volts- tie all pins 15 to ground- on the first chip : tie pin 10 to the logic level for 'idle'- tie pin 9 of the first chip to pin pin 10 of the second chip.- pin 9 of the second chip is your serial out.- pin 5 and 6 of the second chip are tied to the logic level for idle- pin 4 of the second chip is tied to the logic level for 'startbit'- pin 3 of the second chip is tied to data_7- pin 14 of the second chip is data_6- pin 13 of the second chip is data_5- pin 12 of the second chip is data_4- pin 11 of the second chip is data_3- pin 6 of the first chip is data_2- pin 5 of the second chip is data_1- pin 4 of the second chip is data_0- pin 3 of the second chip is logic level of stopbit- pins 14,13,12 and 11 of first chip are tied to the logic level for idle.GO !just don't throw data in faster than the shifter can move it. that's a matter of tying a counter in that gets loaded with '16' and counts to '0' a 74193 can do the trick. parallel load all '1' the moment you assert the load on the 165's.use the'zero' output of the 193 ( i think this counter has a 'zero' output. called 'borrow' ) to tell you : all has left. by tying this borrow output to the clock enable of the 193 it will stop itself when hitting zero.so you can build this entire thing with 3 ttl ic's.

author: mikes
author_rank: Regular Contributor
timestamp: May 22, 2013, 05:23:06 pm
content: Quote from: free_electron on May 22, 2013, 03:19:00 pmYou can end up with a too-short start bit. If you release half way into a clock cycle, you end up with a 1/2 length start bit. As I mentioned above, that can be fixed by starting with a marking (idle) bit, which can be short since it merely extends the idle time.

author: free_electron
author_rank: Super Contributor
timestamp: May 22, 2013, 05:39:55 pm
content: Quote from: mikes on May 22, 2013, 05:23:06 pmNo you don't . I already took care of that : the first two bits in the pipe are idle states. and i quote myself:QuoteThe ttl example with two 165 starts with 2 idles, startbit , payload , stopbit and is padded with idles at the end.so if you assert load you are forcing idle on the shifter output .This starts any transmission with two idles. Same for my verilog example. i always start with two idles. so synchronisation is not a problem.No matter where you release the load in respect to the clock you are guaranteed to have at least one idle (worst case) or two idles (best case ) the packet also terminates with at least one idle .

author: mikes
author_rank: Regular Contributor
timestamp: May 22, 2013, 06:04:45 pm
content: Actually, what you said wasQuoteWhich differs from what you said in your obtuse, pin oriented explanation. My fault, I assumed you were being consistent.

author: free_electron
author_rank: Super Contributor
timestamp: May 22, 2013, 07:27:12 pm
content: the first explanation with the 10 bit shift register is the concept. See it as the 'ideal opamp' explanation. it;s a concept. you don't worry about clock sync . in an ideal world there are no half clocksand propagation delay doesn't exist.The verilog and the pinwiring is the practical implementation with the kinks and 'gotcha's worked out. there i give the detailed explanation of where the problems are and how to work around them.

author: C
author_rank: Super Contributor
timestamp: May 22, 2013, 08:49:58 pm
content: If you change your thinking around a bit things can get easer and simpler.A serial port is always transmitting a stop bit unless there is data!If your doing a state machine the stop bit should be the first state not the last state. This change also makes it easer with a shift register.By doing this the question becomes is there new data. If there is then move to start bit and if not repeat the stop bit. The same clock that moves you to start bit state can also load the shift register or the output data register.If you are not allowed to use a shift register, then you just need to create a data selector and you can cheat a bit by the fact that the lsb of the state machine changes the same as the data out line.This change also makes it easer for the receive function as the receive function can loop on receiving a stop bit and by seeing the edge of the start bit can then move to receiving the data..C

author: C
author_rank: Super Contributor
timestamp: May 22, 2013, 09:03:09 pm
content: Note:with the stop bit first logic how easy it is to add to the logic for number of data bits, parity and extra stop bit and have no race condition.C

author: amyk
author_rank: Super Contributor
timestamp: May 23, 2013, 11:34:19 am
content: Quote from: juanfermed on May 22, 2013, 08:41:59 amhttp://www.st.com/web/catalog/sense_power/FM137/SC713/SS1525/PF250308

author: juanfermed
author_rank: Regular Contributor
timestamp: June 27, 2013, 11:39:09 pm
content: Hi! I am really sorry or my late reply, I apologize myself for not answering in such a long time. It was the end of the semester and things went crazy there, and I could not access the forum for a strange reason which appears my DNS server wasn't able to resolve eevblog.com address.@free_electron, I apologize myself for not getting your idea at first time. I was really amazed at how simple, functional and versatile it was. I implemented your solution in my circuit and actually made a PCB for it. I dont know what to say but I am sorry and now I understand what a newbie I am. Thanks a lot for such a detailed description of the circuit, and even though I dont understand the verilog code, I really appreciate your time. I learned to think very well of things before replying. Again, I am sorry, please accept my apologies.Here I submit the schematic diagram which you described, for future reference for anybody. It also includes a oscillator to transmit @ 9600 baud/s and a little serial receiver, which consists of a monostable and astable oscillators and a shift register, along with the TTL-RS232 voltage converte (a simple MAX232) and headers that I used as input/output of data. There are two RC high pass filters with an output transistor that generate a little pulse after data is sent or received, which were necessary for my purposes.