Solved

Generating a Software Clock Pulse

Posted on 2000-02-23
20
723 Views
Last Modified: 2011-04-14
Ok, i'm not sure if any of you guys have had experience with Hardware and Software I/O interfacing. But none the less, I'll give this a shot. I'm working on a fairly simple project involving a ADC0809 ( analog to digital convertor) It requires a 640 KHz clock pulse. Of course it can be supplied using a tripple 5 timer etc, but I want to use a software method.
I'm using Borland C 2.0 for DOS
It has a delay() function already predefined in it. the problem is, the period of this pulse if less than 1 ms.
Any solutions will be appreciated, thank you. If maybe U need me to tell u how this specific adc functions, just ask.
0
Comment
Question by:Kelvin_King
  • 7
  • 2
  • 2
  • +7
20 Comments
 
LVL 13

Author Comment

by:Kelvin_King
ID: 2549817
ok ok .. I forgot to add something important. The address of my adc is 0x303 ( i'm working in hexa )so when I'm reading from a port i use
inportb(portc);
and write to a port I use
outportb(portc, 0xXX);
just an example.
0
 
LVL 3

Expert Comment

by:ufolk123
ID: 2549931
Hi ,

In dos there is no other way to get a pause of less than that resoultion.For getting high resolution you do something like this.

while(count)
{
some dummy assignment or instruction //
}
note the time taken by this loop and use it for providing an abstraction for pause of high resolution.

Like if you are using assembly
loop of NOP instruction will do.


This way you can get a fine resolution delay but you may have to do some experimenting with the time taken by loop and instructions inside the loop.


0
 

Expert Comment

by:vissteve
ID: 2550078
hi,
   can u give the details of the adc.how fns?what r u using?............
               thank u.
0
 
LVL 13

Author Comment

by:Kelvin_King
ID: 2550323
Hmmm, I'm firmiliar with Assembly Language instructions like NOP, but in C, what instruction has the same function ? ( does'nt nothing but waste time )
Also, is there some kind of book which tells u the duration if each operation, like in assembly language ?

vissteve>>
I'm using a motorola ADC 0809
which is an 8 input step convertor.
We start conversion by sending selecting the input and a '1' to the active high "start conversion " pin.
When the conversion is done, it will send a '1' at the "inturrupt " pin. but what I'm interested in is the clock cycle.
0
 
LVL 1

Expert Comment

by:Ernest022699
ID: 2553224
You're far better off using a hardware timer.  Tight loops incrementing values stored in memory locations or doing some complex math may seem like a good solution, but you'll spend forever tweaking things.  And if you need to do other stuff later, ....
0
 
LVL 13

Author Comment

by:Kelvin_King
ID: 2554363
Thank U for that advise ernest. But I'm looking for software solutions.
0
 
LVL 13

Author Comment

by:Kelvin_King
ID: 2554386
I was thinking about something likevoid adc_conversion();
{
      outportb(PORTA,address);
      outportb(PORTC, 0x00);            //disable all bits
      outportb(PORTC, 0x80);            //activate WR
        outportb(PORTC, 0x10)  
        //this is the bit for the clock
        //maybe I can toggle it in a loop for 8 times...bacause the ADC requires 8 clock pulese to to a conversion then just go on to the next step//
   
      outportb(PORTC, 0x00);            // also possible to use xor
      do
      {
            ready = inport(PORTC);      //read portc
            ready = ready & 0x01;
      }
      while(ready!=0x01);             //LOOP IF CONVERSION NOT ENDED

}


0
 
LVL 13

Author Comment

by:Kelvin_King
ID: 2554387
I was thinking about something like
void adc_conversion();
{
      outportb(PORTA,address);
      outportb(PORTC, 0x00);            //disable all bits
      outportb(PORTC, 0x80);            //activate WR
        outportb(PORTC, 0x10)  
        //this is the bit for the clock
        //maybe I can toggle it in a loop for 8 times...bacause the ADC requires 8 clock pulese to to a conversion then just go on to the next step//
   
      outportb(PORTC, 0x00);            // also possible to use xor
      do
      {
            ready = inport(PORTC);      //read portc
            ready = ready & 0x01;
      }
      while(ready!=0x01);             //LOOP IF CONVERSION NOT ENDED

}


0
 
LVL 13

Author Comment

by:Kelvin_King
ID: 2554391
Open for Discussion
0
 
LVL 24

Expert Comment

by:SunBow
ID: 2555428
I agree w/ Ernest, you'd need to know the cpu, its implementation of cycles, its speed, the compiler's method of impementing machine code (why not Borland v3?), and more.  
But then, I do no not understand the purpose. I want to read as:

Wait (small time less than 1 ms)
  {
  Do stuff
  }

So you would ask about what is 'do stuff'.  But I cannot, I am likely confused on the issue. I want to suggest that the 'do stuff' part uses hardware options to fixate on specific time(s), with software parts determining elapsed time. If so the question would involve: how much time to wait.

I don't know, but believed that 1 ms & ~ 1/18th (tic) were readily available units, as well as a smaller measure.

But if you are only playing on a single unit, approaches I have taken before use nested loops.  Find a bigger time increment that you can realy on, like 1 second.  Then massage the looping to accomodate. Nested loops of 1 to 1000 work well.  For improved accuracy, tune to outer loop of minute, hour day, and adjust the loops accordingly (60,60,24). This time is used to refine the inner loops.  A single increment command could be the only statement used for this purpose. Innermost loop of 1000 may be nice. Tune the length of subsequent loops until the whole thing runs, say 10 seconds. That'll give you good approx. for how many inc's your machine needs for your standard small amount of time. Accuracy improves by lengthening the total program runtime.

Problem is in porting this method elsewhere. So I'd go for software access to h/w timer functions for portability.  But I suspect I am missing your point. I am not very expert on any of these issues, including ADC -clock...

Are you trying to assess the time elapsed between the active high "start conversion " pin and when it will send a '1' at the "inturrupt " pin? Or use that period to time something else?
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 3

Expert Comment

by:Norbert
ID: 2557508
>>>It requires a 640 KHz clock
640 kHz = 640000 kHZ = 0.0000015625 s

that means 1.563 micro seconds
how exact the clock must be ?
remember: No PC is deterministic!
There are interrupts for ram refresh, PC clock, keyboard input and so on.
These will disturb your Clock tick.
So the Ticker will not always have the same distance.
My be a hardware clock would be the better solution
0
 
LVL 24

Expert Comment

by:SunBow
ID: 2558776
..speed of cache, ram, i/o, all them thar bus paths...
0
 
LVL 2

Expert Comment

by:kinross
ID: 2560782
KISS keep it simple stupid :)

What you are proposing to do will cause you nothing but frustration.
My suggestion would be is get a hardware clock. Since you want to do it in software, tweak away.  Here's how to do it.

First you need to disable all optimizations on your compiler or it will delete the following code because it thinks it's useless.

asm
{
nop
nop
nop
nop
nop
}

outportb(PORTA,address);
outportb(PORTC, 0x00); //disable all bits
outportb(PORTC, 0x80); //activate WR outportb(PORTC, 0x10)  
//this is the bit for the clock
//maybe I can toggle it in a loop for 8 times...bacause the ADC requires 8 clock pulese to to a conversion then just go on to the next step//
                                 
outportb(PORTC, 0x00)

Now all of your outportx() functions are precompiled binaries that are linked in so there is no way for you to now the timing of these function other than by trial and error.   Keep adding nops until you get the timing just right, have fun in the build, run, test, tweek cycle.  Do not put the nops in a loop.  This will generate branches and could mess up your timing even more.  Do not make a function out of the nops,  you must have the nops followed immeadiatly after the outport stuff otherwise you will have to worry about stack timing.

Now my guess is that you are over killing a project with a processor on hand  that you are familiar with therby trying to fit a square peg in a round hole.  I wold suggest going to an architecture that is more suited for embedded applications, that sounds like what you ar doing.  You can find processors with real time clocks that generate interrupts down to the clock pulse.  They also have a2d built right into the cpu.
0
 
LVL 2

Expert Comment

by:tdubroff
ID: 2562535
Kelvin,

If you can use a 555, use it.  They are easy to set up and if you put an op-amp comparator on the output you should get a nice square wave clock. If you still want some control of the 555 through software, you could conceivably add an enable pin that is I/O-mapped to your computer.  Or likewise you could add a voltage-controlled resistor, or a voltage-controlled capacitor that is controlled by software but affects the 555's pulses.

In general though, anytime you need a real-time clock, there is no other solution than a hardware solution.

-Ted
0
 
LVL 3

Expert Comment

by:LucHoltkamp
ID: 2564387
I agree with tdubroff, although you can make a clock in software, it will never be very reliable, the PC OS's are not intended as a real-time OS...
My advice is to use the 555
Luc
0
 
LVL 13

Author Comment

by:Kelvin_King
ID: 2568388
Interesting Conversation !!
Yes.. I agree, Using the 555 is more efficient.
I did'nt have much time to do that project anyway, so I decided on a hardware clock. But If given more time, I would have tried for a software clock. Thanks anyway for all your help.
I'll just give this on to kinross ;)
0
 
LVL 2

Expert Comment

by:obg
ID: 2569208
The standard PC architecture does not provide any counter better than the timer, which runs at 1.19 MHz (as far as I know). If you want 640 kHz you'd want triggers at 1.28 MHz, but if you could settle with 1.19, you could read the CRTL source of delay() from your Borland C installation to see how this is done. By the way, I'm not sure that the source is included in 2.0. Drop in a msg and I'll post it.
0
 
LVL 2

Accepted Solution

by:
kinross earned 200 total points
ID: 2569449
KISS keep it simple stupid :)

What you are proposing to do will cause you nothing but frustration.
My suggestion would be is get a hardware clock. Since you want to do it in software, tweak away.  Here's how to do it.

First you need to disable all optimizations on your compiler or it will delete the following code because it thinks it's useless.

asm
{
nop
nop
nop
nop
nop
}

outportb(PORTA,address);
outportb(PORTC, 0x00); //disable all bits
outportb(PORTC, 0x80); //activate WR outportb(PORTC, 0x10)    
//this is the bit for the clock
//maybe I can toggle it in a loop for 8 times...bacause the ADC requires 8 clock pulese to to a conversion then just go on to the next step//
                                 
outportb(PORTC, 0x00)

Now all of your outportx() functions are precompiled binaries that are linked in so there is no way for you to now the timing of these function other than by trial and error.   Keep adding nops until you get the timing just right, have fun in the build, run, test, tweek cycle.  Do not put the nops in a loop.  This will generate branches and could mess up your timing even more.  Do not make a function out of the nops,  you must have the nops followed immeadiatly after the outport stuff otherwise you will have to worry about stack timing.

Now my guess is that you are over killing a project with a processor on hand  that you are familiar with therby trying to fit a square peg in a round hole.  I wold suggest going to an architecture that is more suited for embedded applications, that sounds like what you ar doing.  You can find processors with real time clocks that generate interrupts down to the clock pulse.  They also have a2d built right into the cpu.

0
 
LVL 2

Expert Comment

by:obg
ID: 2572476
Ok, to keep it simple (though I don't like the attitude), why not just make a loop for a million laps (or so), meassure how long time it took, and from there calculate the necessary amount of laps to generate the pulse. (Of course, to be accurate, you'd need to meassure a lot of outportbs as well.)

- Simple AND PORTABLE!
0
 
LVL 3

Expert Comment

by:LucHoltkamp
ID: 2576149
// next code works reasonable
// GetTickCount returns the tick count from the real time clock (increased
// every 50 ms or so)
// it's a win32 function, but there are similar functions in other OS's

double one_micro_sec;

void calibrate()
{
   volatile DWORD start = GetTickCount(), end;
   unsigned teller = 0;
   // wait until clocktick flips over
   do end = GetTickCount();
   while (start == end);
   // actual calibration loop
   start = end;
   do
   {
      ++teller;
      end = GetTickCount();
   }
   while (start == end);
   one_microsec = teller/(1000.0*(end - start));
}

void wait(unsigned micro_sec)
{
   if (!micro_sec) return;
   unsigned count = micro_sec*one_microsec + 0.5; // number of iterations
   volatile DWORD dummy;
   while (count--) dummy = GetTickCount();
}
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now