PDA

View Full Version : Làm trễ 1 micro giây trong VC++ bằng cách nào?



mtt333
16-06-2005, 07:59
Có bạn nào biết cách làm trễ 1 micro second bằng cách nào không???
Xin chỉ giùm mình với.

evodanh
16-06-2005, 10:09
Điều này không thực hiện được!

mtt333
16-06-2005, 22:36
Điều này không thực hiện được!

Yêu cầu 1 micro giây nếu có lẽ hơi quá khắt khe và nhạy cảm. Tuy nhiên có thể thực hiện được trễ vài chục đến vài trăm micro giây.

LARGE_INTEGER hrRes, hrT1, hrT2, dif;

__int64 *Freq;
__int64 *T1;
__int64 *T2;

// Tần số: số nhịp trong 1 giây
Freq = (__int64*) &hrRes;

// Bộ đếm nhịp.
T1 = (__int64*) &hrT1;
T2 = (__int64*) &hrT2;

// Thời gian cần làm trễ tính theo micrro giây
int DelayTime = 1;

// Bắt đầu làm trễ
if (QueryPerformanceFrequency(&hrRes)) {
QueryPerformanceCounter(&hrT1);
for (QueryPerformanceCounter(&hrT2); ((*T2 - *T1) * 1000000 / (*Freq)) < DelayTime; QueryPerformanceCounter(&hrT2));
}

Với DelayTime là thời gian cần làm trễ tính theo micro giây,

Cách chương tình thực hiện:
- Lệnh QueryPerformanceFrequency(&hrRes) lấy tần số hoạt động của chương trình (số nhịp trong 1 giây)
- QueryPerformanceCounter(&hrT1) lấy nhịp hiện tại khi bắt đầu làm trễ.
- Thực hiện trễ bằng vòng lặp, sau mỗi lần lặp lấy nhịp hiện tại bằng QueryPerformanceCounter(&hrT1).
- Lấy hiệu T2 - T1 ra số nhịp thực hiện từ khi bắt đầu làm trễ.
- Khi hiệu trên thỏa mãn thời gian cần làm trễ trong DelayTime thì dừng vòng lặp --> trễ được DelayTime.

Kiểm nghiệm trên máy của mình:

- Thực tế kiểm nghiệm: khá tốt nếu cần làm trễ hàng chục đến hàng trăm micro giây.
- Với dưới 10 micro giây thì sai số phạm phải lớn hơn. tuy nhiên nếu đòi hỏi đồng bộ không quá khắt khe thì có thể lấy trong khoảng: ví dụ nếu yêu cầu trễ từ 1 micro giây đến 2 micro giây thì có thể đạt được.
- Nếu cần làm trễ nhỏ hơn 2 micro giây trở xuống nữa mà không quan tâm đến độ chính xác thì cho chyaj một vòng lặp là xong:
for(int i = 0; i < 1; i++);

jiSh@n
22-06-2005, 11:01
High Resolution Performance Counter có tần số khoảng 3,5MHz -> có thể delay dưới 1ms.

THE LAST LEAF
22-06-2005, 13:30
Hì lắm bác cứ thích thể hiện nhỉ ....

mtt333
23-06-2005, 13:50
Hì lắm bác cứ thích thể hiện nhỉ ....

Dạ vâng ạ.
Vì có những người khiêm tốn như bác nên lắm lúc em phải tự hỏi, tự bơi rồi tự trả lời???

Không hiểu bác đã đọc truyện "Chiếc lá cuối cùng" mà lấy tên nick là THE LAST LEAF. Sao bác không chịu "thể hiện" một chút để giúp em như ông hoạ sỹ già kia???

htbn_hoang
23-06-2005, 14:36
Chào, tui nghĩ không cần phải làm khó vậy đâu. Riêng công đoạn tính toán của bạn cũng đã tốn hơn 1ms rồi. Vậy thì làm sao thỏa mãn được yêu cầu. Tui nghĩ chỉ cần dùng hàm Sleep(ms) là được rồi với ms là số milisecond. Trên lý thuyết, máy tính có thể gởi thông điệp thời gian vào khoảng mili giây. Tuy nhiên, không có máy tính nào có thể thực hiện được điều đó vì bản thân ngắt đồng hồ trong máy tính chỉ thực hiện được từ vài chục đến vài trăm lần /1 giây thôi. Nếu bạn dùng MFC cũng có thể bắt sự kiện thời gian nhưng khoảng cách giữa hai lần nhận sẽ khá lớn, tùy máy từ vaid chục đến hơn 100.

mtt333
23-06-2005, 16:14
Chào, tui nghĩ không cần phải làm khó vậy đâu. Riêng công đoạn tính toán của bạn cũng đã tốn hơn 1ms rồi. Vậy thì làm sao thỏa mãn được yêu cầu. Tui nghĩ chỉ cần dùng hàm Sleep(ms) là được rồi với ms là số milisecond. Trên lý thuyết, máy tính có thể gởi thông điệp thời gian vào khoảng mili giây. Tuy nhiên, không có máy tính nào có thể thực hiện được điều đó vì bản thân ngắt đồng hồ trong máy tính chỉ thực hiện được từ vài chục đến vài trăm lần /1 giây thôi. Nếu bạn dùng MFC cũng có thể bắt sự kiện thời gian nhưng khoảng cách giữa hai lần nhận sẽ khá lớn, tùy máy từ vaid chục đến hơn 100.

Yêu cầu làm trễ dưới 1ms là một yêu cầu có trong thực tế.
Tình huống hay gặp nhất là khi bạn lập trình giao tiếp với thiết bị ngoại vi.
Phần lớn các thiết bị ngoại vi có tốc độ nhanh dưới 1ms, nếu yêu cầu giao tiếp đồng bộ mà bạn không thể kiểm soát được thời gian của máy tính ở mức dưới 1ms thì sẽ không thể chấp nhận được.

netwalker
23-06-2005, 22:13
Yêu cầu làm trễ dưới 1ms là một yêu cầu có trong thực tế.
Tình huống hay gặp nhất là khi bạn lập trình giao tiếp với thiết bị ngoại vi.
tại sao lại dùng VC/VB/... để lập trình giao tiếp với nó
thường tui thấy dùng asm , đối với asm thì làm trẽ rất đơn giản
chỉ cần loop là ok :D

mtt333
24-06-2005, 08:06
tại sao lại dùng VC/VB/... để lập trình giao tiếp với nó
thường tui thấy dùng asm , đối với asm thì làm trẽ rất đơn giản
chỉ cần loop là ok :D

Cần phải dùng VC/VB vì bạn giao tiếp với phần cứng thì phải có phần mềm tương ứng chứ. Chẳng nhẽ cậu định dùng asm để viết một phần mềm (ví dụ như máy đo điện tim thì phải viết phần mềm hiện sóng đo được trên màn hình chứ: ông mà dùng asm vẽ được đồ thị sóng thì xin bái ông làm sư phụ.

Tất nhiên có thể nhúng asm vào VC, VB để làm trễ, nhưng dùng asm để làm trễ thường dựa vào xung nhịp của chip --> thời gian trễ trên mỗi máy khác nhau --> không đồng bộ được.

THE LAST LEAF
24-06-2005, 12:27
Dạ vâng ạ.
Vì có những người khiêm tốn như bác nên lắm lúc em phải tự hỏi, tự bơi rồi tự trả lời???

Không hiểu bác đã đọc truyện "Chiếc lá cuối cùng" mà lấy tên nick là THE LAST LEAF. Sao bác không chịu "thể hiện" một chút để giúp em như ông hoạ sỹ già kia???

Tôi nói chẳng có gì là không đúng bởi vì bác hỏi chưa ai kịp trả lời nhưng gần như bác lại ngay lập tức tự trả lời, hê hê tất nhiên chẳng ảnh hưởng gì tới tôi nhưng tôi thấy chướng cái lối thể hiện của bác, thà rằng bác làm một bài theo kiểu "[tutor] Làm cách nào ..." còn được

Còn cái nick của tôi thì đúng là tôi thích cái câu chuyện ấy, nhưng truyện kia thì ai cũng biết, ai cũng từng học,vậy tôi thể hiện cái gì.

mtt333
24-06-2005, 12:33
Tôi nói chẳng có gì là không đúng bởi vì bác hỏi chưa ai kịp trả lời nhưng gần như bác lại ngay lập tức tự trả lời, hê hê tất nhiên chẳng ảnh hưởng gì tới tôi nhưng tôi thấy chướng cái lối thể hiện của bác, thà rằng bác làm một bài theo kiểu "[tutor] Làm cách nào ..." còn được

Còn cái nick của tôi thì đúng là tôi thích cái câu chuyện ấy, nhưng truyện kia thì ai cũng biết, ai cũng từng học,vậy tôi thể hiện cái gì.

Phải nhìn thời gian chứ, tôi hỏi vào buổi sáng, phải hỏi trên nhiều diễn đàn, đọc thêm nhiều sách mới có được một cách nên đến tối mới đưa ra đây một phương án, mong mọi người chỉ cho những phương án tốt hơn.

Bác không giúp đỡ, xây dựng gì thì thôi chứ đừng có lên đây phá.

9m4re
24-06-2005, 15:04
+ Việc delay đó theo tớ nếu muốn chính xác với sai số rất nhỏ thì điều đó là không thể thực hiện được. Ví dụ như điều khiển thiết bị ngoại vi, việc delay chính xác cỡ uS là cần thiết.
+ Lý do rất đơn giản là Windows không phải là hệ điều hành realtime (realtime - OS)
+ Ví như nếu bạn có một thread, làm nhiệm vụ loop để delay chẳng hạn thì chưa chắc CPU TIME đã dành cho thread đó 1 lần , ý là thread đó có thể sẽ bị ngắt giữa chừng, CPU lúc này sẽ xử lý thread khác, việc ngắt đó tùy thuộc vào Priority ( USER MODE) hoặc IRQL ( Kernel mode) trong đó khả năng ngắt cao nhất thuộc về HIRQL ( ngắt của thiết bị phần cứng)

Vậy theo tớ để làm chính xác 99% thôi cũng không được.

mtt333
04-07-2005, 13:43
+ Việc delay đó theo tớ nếu muốn chính xác với sai số rất nhỏ thì điều đó là không thể thực hiện được. Ví dụ như điều khiển thiết bị ngoại vi, việc delay chính xác cỡ uS là cần thiết.
+ Lý do rất đơn giản là Windows không phải là hệ điều hành realtime (realtime - OS)
+ Ví như nếu bạn có một thread, làm nhiệm vụ loop để delay chẳng hạn thì chưa chắc CPU TIME đã dành cho thread đó 1 lần , ý là thread đó có thể sẽ bị ngắt giữa chừng, CPU lúc này sẽ xử lý thread khác, việc ngắt đó tùy thuộc vào Priority ( USER MODE) hoặc IRQL ( Kernel mode) trong đó khả năng ngắt cao nhất thuộc về HIRQL ( ngắt của thiết bị phần cứng)

Vậy theo tớ để làm chính xác 99% thôi cũng không được.

Đồng ý với ý kiến của bạn.
Nhưng mình nghĩ nhu cầu trao đổi dữ liệu với thiết bị ngoại vi với máy PC là nhu cầu thực tế. Vậy có thể có giải pháp nào không???

Vào ra bằng DMA hoặc bằng ngắt chăng??? Nếu vậy thì lập trình phải như thế nào???

netwalker
04-07-2005, 17:12
Cần phải dùng VC/VB vì bạn giao tiếp với phần cứng thì phải có phần mềm tương ứng chứ. Chẳng nhẽ cậu định dùng asm để viết một phần mềm (ví dụ như máy đo điện tim thì phải viết phần mềm hiện sóng đo được trên màn hình chứ: ông mà dùng asm vẽ được đồ thị sóng thì xin bái ông làm sư phụ.

Tất nhiên có thể nhúng asm vào VC, VB để làm trễ, nhưng dùng asm để làm trễ thường dựa vào xung nhịp của chip --> thời gian trễ trên mỗi máy khác nhau --> không đồng bộ được.
tất nhiên là không dùng asm rồi, nhưng làm trể thì dùng asm, vd như khi cần làm trề thì cho chạy file asm đấy, đến khi kết thúc là làm trể xong .

nhưng sau khi nghĩ xong thì ông đúng :D
khó mà làm trên asm được vì tác vụ phức tạp quá

ntmq
23-07-2005, 10:46
Các bạn nói cao siêu quá, mình đọc mà không hiểu gì nhiêu hết. trễ 1 micro second thì nhỏ quá, bây giờ nếu muốn trễ 1 hoặc 2 s trở lên thì dùng hàm gì ? (trong pascal đó là delay)
Thanks for reading my post

9m4re
23-07-2005, 13:26
asm cũng không được. vì asm trên userland thì cũng bị kernel quản lý theo dạng thread, chảng thể delay cỡ uS được.
@ntmq:

LARGE_INTEGER hrRes, hrT1, hrT2, dif;

__int64 *Freq;
__int64 *T1;
__int64 *T2;

// Tần số: số nhịp trong 1 giây
Freq = (__int64*) &hrRes;

// Bộ đếm nhịp.
T1 = (__int64*) &hrT1;
T2 = (__int64*) &hrT2;

// Thời gian cần làm trễ tính theo micrro giây
int DelayTime = 1;

// Bắt đầu làm trễ
if (QueryPerformanceFrequency(&hrRes)) {
QueryPerformanceCounter(&hrT1);
for (QueryPerformanceCounter(&hrT2); ((*T2 - *T1) * 1000000 / (*Freq)) < DelayTime; QueryPerformanceCounter(&hrT2));
}

Với DelayTime là thời gian cần làm trễ tính theo micro giây,
@mt333:mình hiện giờ cũng chưa biết phải làm thế nào để delay cỡ uS. Nếu việc ra quyết định delay đó từ trên UserLand thì chắc chắn là k0 được
nhưng nếu việc delay đó được thực hiện trong một routine nào đó của mình viết ở kernel thì có thể đúng đựơc cớ 80% ?? (cái này mình chưa có thử).
Nhưng bình thường giao tiếp với ngoại vi, thì việc delay đó mình thường để cho MCU làm vì MCU với f dao động cố định, ta có thể hoàn toàn tính được cần delay uS dựa trên thời gian thực hiện 1 instruction của MCU.

nm.

jiSh@n
23-07-2005, 23:11
Vậy thì đặt priority lên mức RealTime thử xem.

working_m
23-07-2005, 23:40
nhân tiện chủ đề này, tôi muốn hỏi cách làm delay giữa các frame trong các chương trình video players theo nguyên tắc nào nhỉ?

Ví dụ: muốn play 1 file video với frame rate 30 fps thì delaytime time của 1 frame = 1/30 = 0.333s. Nếu dùng hàm sleep hoặc delay để delay 1 khoảng 0.333s có phải là giải pháp hợp lý? có cách nào đánh giá sai số là bao nhiêu ? hoặc dùng phương thức nào khác để thực hiện delay? mong các bác chỉ giáo.

mtt333
23-07-2005, 23:48
nhân tiện chủ đề này, tôi muốn hỏi cách làm delay giữa các frame trong các chương trình video players theo nguyên tắc nào nhỉ?

Ví dụ: muốn play 1 file video với frame rate 30 fps thì delaytime time của 1 frame = 1/30 = 0.333s. Nếu dùng hàm sleep hoặc delay để delay 1 khoảng 0.333s có phải là giải pháp hợp lý? có cách nào đánh giá sai số là bao nhiêu ? hoặc dùng phương thức nào khác để thực hiện delay? mong các bác chỉ giáo.

Nếu không yêu câu chính xác thì delay khoảng 33 ms hoặc 34 ms là được, không có hàm cho phép delay nhỏ hơn. Sau một khoảng thời gian có thể cho delay nhanh lên hoặc chậm hơn một mộ chút trong một lúc để bù lại thời gian sai số.
Với người trần mắt thị thì không có khả năng phát hiện ra điều này.

pinochu
11-01-2006, 12:59
bác chèn code asm vô code C xem sao,
__asm