Создание задержки <= 1мкс
Но в asm-вставке вызов прерывания не проходит. Можно ли обойти проблему, связанную с вызовом прерывания и если да, то как?
Или есть другие способы создания такой задержки?
Вообще задержку в 1 мкс мона сделать при помощи функции sleep
Поищи ее реализацию, либо поставь опцию компилятора выдать тебе ассемблерный код ее и глянь как реализована она если нужно меньше 1 мкс.
Функция Sleep работает с миллисекундами (10^-3 сек.), а не с микросекундами (10^-6 сек.), но даже она не генерит "честных" задержек, т.к. задержка не системная, а потока программы.
Сделать программно задержку меньше 1 микросекунды (несколько наносекунд) в винде не реально. Да и микросекундную задержку тоже.
Кстати, а для чего такие маленькие задержки понадобились? Для какой то коммуникации?
Есть функция на ассемблере, которая делает задержку на заданное число тиков таймера. Эта задержка большая по сравнению с 1 мкс:
1 / 18.2 с = 55мс. Но в той функции тоже используются прерывания в asm-вставке:
#include <conio.h>
void tm_delay(int ticks) {
_asm {
push si
mov si, ticks
mov ah, 0
int 1ah
mov bx, dx
add bx, si
delay_loop:
int 1ah
cmp dx, bx
jne delay_loop
pop si
}
}
Можно ли ее как-нибудь адаптировать для использования в BCB?
Можно немного конкретики, что за устройство, какой интерфейс?
Контроллер(в спец. датчике с которого надо очень быстро снимать показания) с i2c-интерфейсом через спец. адаптер соединен с параллельным портом. На определенных контактах порта для соблюдения протокола трбуется удерживать заданный уровень(1 или 0) сигнала не менее X мкс. Но более X мкс тоже нельзя удерживать(этого уже требует специфика задачи). Эти X - разные, но все очень маленькие(все они есть в описании i2c-интерфейса): по 4, по 5 мкс.
Адаптер(устройство сопряжения) очень простой и никак задержками манипулировать не может. Поэтому это возлагается на программу.
Вы переключаете скоростной режим Com порта и шлете пакеты с нужным Вам распределением задержек.
К примеру, Com порт переведен в режим 9600 бод. Значит за 1 секунду он передает 9600 бит. Отсюда вычисляем, что на один бит уходит примерно 0,0001секунда. Т.е. 10 мкс. Соответственно отсылая пакет 0101, мы получаем 10микросекундную задержку между отправкой единичек.
При этом увеличивая скорость com порта, мы можем генерить еще более точные задержки.
При этом тайминги непосредственно между отсылаемыми пакетами не так критичны и могут составлять секунды. Т.е. комманды можно отсылать хоть вручную.
Параллельный порт работает в режиме SPP, со скорость присущей этому режиму(я читал, что при полной загрузке процессора удавалось разгонять порт до 100 - 150 Кбайт/с).
Поэтому задержки в программе нужны хотя бы для того, чтобы то, что записано в регистры порта успевало выплюнуться раньше, чем содержание регистров обновиться. Непосредственно в регистры пишет моя программа.
А что, буфер приема и буфер передачи и порта один и тот же?
Т.е. грубо говоря, Вам нужно удостовериться, что времени выполнения программы хватит для забивания регистра?
Неужели в I2C протоколе такие маленькие задержки между командами? А иначе, что мешает Вам заранее подготовить нужный пакет и поместить его в буфер для отправки?
{
unsigned clock0 = 0;
unsigned clock = 0;
extern int FcpuMHz; //частота процессора в МГц
__asm rdtsc; //получаем текущий такт процессора (в eax)
__asm mov [clock0], eax; //переписываем eax в clock0
do
{
__asm rdtsc; //получаем текущий такт процессора (в eax)
__asm sub eax, [clock0]; //eax = eax - clock0
__asm mov [clock], eax; //переписываем eax в clock
}
while (clock < (FcpuMHz * time));
}