Maker Pro
Maker Pro

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

Jonathan Kirwan

Jan 1, 1970
0
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;
}

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
 
Some things cross my mind. Why do you need to generate a clock?
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
you sure the LPT signals on your computer are electrically compatible
with the circuit? Does it have a separate power supply?
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.
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.)

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


What's wrong with:

for(;;){
pin = 0;
wait_a_very_precise_amount_of_time();
pin = 1;
wait_a_very_precise_amount_of_time();
}
 
What's wrong with:

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

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
 
P

PeteS

Jan 1, 1970
0
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

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
 
L

Leon

Jan 1, 1970
0
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;
}

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
 
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.

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

GM

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

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
 
J

Jonathan Kirwan

Jan 1, 1970
0
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
<snip>

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
 
Jonathan said:
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.


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

The download link is kinda "hidden" (took me awhile to find it, I
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
 
J

Jonathan Kirwan

Jan 1, 1970
0
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

The download link is kinda "hidden" (took me awhile to find it, I
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.)

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

Jon
 
Top