# LPT square wave

Discussion in 'Electronic Design' started by [email protected], Oct 3, 2006.

1. ### Guest

Hi,

I'm trying to write a program in C++ to communicate with an AVR
microcontroller's SPI via the LPT port.

I have to generate a clock (SCK) signal on one of the pins of the LPT.
I am using the WinIO library. I'd like to have way to create a square
wave of a given frequency (within some limit of course).

My question is: what is the best way to generate such signal and what
is the maximum frequency one can obtain? Excluding of course such code:
Code:

for (; {
pin = 0; pin = 1;
}

2. ### Jonathan KirwanGuest

Some things cross my mind. Why do you need to generate a clock? Are
you sure the LPT signals on your computer are electrically compatible
with the circuit? Does it have a separate power supply? How precise
do you need this clock? What do you mean by "best way?"

A perfectly good way of generating a clock might very well be
something similar to what you wrote. Why do you exclude it?
(Especially since it may very well be the maximum frequency you can
achieve, in this case.)

Jon

3. ### Guest

I am using SPI protocol (which is synchronous protocol) where PC is
Master, so it has to provide a clock signal to the circuit.

Are
It is 100% compatible. The LPT output level is TTL so no problems here.
Also i have programmer which is interfaced via LPT and also uses SPI,
works.
The example will not work, because the microcontroller is running at
16MHZ. The AVR documentation says that the clock signal must stay
unchanged for at least 3 CPU (AVR) cycles because only then the uC will
be able to sample it properly.
The conclusion is that I need to generate a clock having 15MHZ or
lower.
On the other hand, with the 1KHZ frequency I get only 125 bytes / sec
which is pretty low.

4. ### Guest

What's wrong with:

for(;{
pin = 0;
wait_a_very_precise_amount_of_time();
pin = 1;
wait_a_very_precise_amount_of_time();
}

5. ### Guest

FIrst of all, a very precise amount of time is usually not easy to
achieve. Take into consideration
- The program has to do something else in the meantime

6. ### PeteSGuest

SPI does not require precise amounts of time. Unless you are trying to
communicate at some specific rate, then live with the inaccuracies
added by Winblows and simply run the clock at whatever you can get.
Just make sure you transition the data bits well clear of the clock
transitions (which is not easy when the OS gets in the way - one of the
reasons I detest OSs which do not permit me full access to the hardware
in situations where I actually need it).

Cheers

PeteS

7. ### LeonGuest

Generating SPI with software using the PC printer port is quite easy,
just follow the timing diagram. The clock doesn't have to be a
conventional square wave, just drive it high and low at the correct
time with the data line held high or low. Connecting a 74HC595 with
LEDs on the outputs to the printer port can be useful when debugging
the software, the 74HC595 is SPI-compatible and makes it easy to see
when you have got it right. I have one mounted on a small PCB with the
LEDs.

Leon

8. ### Guest

Generating SPI with software using the PC printer port is quite easy,
Thanks for the answer. Can you tell me is it better to use some kind of
timer or just plain delays?

9. ### GMGuest

Plain delays (for example 'for' loops) will be depended on the system speed.
In other words, as an example, the same loop would be faster in a Pentium
than in a 486. In a Windows program that I've coded for programming AVR
chips, I used the High-Performance Timer instead of the plain old Timer that
gives no less than 10ms interval, thus achiving tolerant (from the user's
view) programming speeds
Here is a link on how to use it
http://www.mtsu.edu/~csjudy/directX/HighPerformanceTimer.html

Regards
GM

10. ### Guest

Thanks a lot. I'll try it.
Regards,
Mike

11. ### Jonathan KirwanGuest

Printer port I/O is handled via the legacy ISA bus transaction
mechanism. There is a precisely defined I/O cycle there, so on modern
computers which are way way faster the limiting time will be this
cycle time. For an 8MHz bus (I think the BIOS can allow this setting
on many systems), this is 6 cycles or 750ns per I/O. I don't think it
can be affected by read-around-writes, caches, etc. It's supposed to
operate like an ISA bus, even if there isn't a physical ISA bus
present (it's just internal to the chip set in those cases.)

My preference for things like this is to actually use DOS on an older
slow Pentium (one of the early ones running at 66MHz or so) or else to
use a 80486 or a system actually sporting a true ISA bus on-board. I
puchased a lot of copies of DOS 5.0 just for the purpose of legally
installing them, as needed. I also keep a bevy of old DOS compilers
that I own, from Microsoft C 4.0 up through their last 16-bit version,
that is VC++ 1.52C. Plus their QuickC 2.0, various QB's and VB-DOS
1.0, etc. Borland tools are also available, even today I think, for
free. But under DOS you don't have WinOldAP (Win95, Win98) or else
double-checking, with all the attendant delays to it. You do the I/O
and the I/O transactions happen. You can grab timers and the
interrupt vector will take you to your code right away, rather than
through some Windows mapping that eventually, someday, gets you there
after who knows how much internal hand-wringing.

Jon

12. ### Guest

Borland... sure is. Turbo C++ 1.01 for DOS was released to Borland's
museum:
http://bdn.borland.com/article/0,1410,21751,00.html

reproduce it here for others' convenience):
http://bdn.borland.com/article/images/21751/tcpp101.zip

The newer Borland C++ 5.5 command line tools don't support delay() and
outportb() anymore, from what I understand. (I could be wrong.)

Michael

13. ### Jonathan KirwanGuest

Write the routines in assembly, if needed. I do it all the time.

Jon