LPT square wave

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; }

Reply to
rpodraza
Loading thread data ...

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

Reply to
Jonathan Kirwan

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.
Reply to
rpodraza

What's wrong with:

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

Reply to
mrdarrett

FIrst of all, a very precise amount of time is usually not easy to achieve. Take into consideration

- Threading (in Wingroze)

- The program has to do something else in the meantime

Reply to
rpodraza

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

Reply to
PeteS

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

Reply to
Leon

Thanks for the answer. Can you tell me is it better to use some kind of timer or just plain delays?

Reply to
docent

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

formatting link

Regards GM

Reply to
GM

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

GM wrote:

Reply to
docent

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 something works (WinXP) blocking all access to I/O addresses and 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

Reply to
Jonathan Kirwan

Borland... sure is. Turbo C++ 1.01 for DOS was released to Borland's museum:

formatting link

The download link is kinda "hidden" (took me awhile to find it, I reproduce it here for others' convenience):

formatting link

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

Reply to
mrdarrett

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

Jon

Reply to
Jonathan Kirwan

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.