mong các bác giúp e đoạn code thực hiện Delay 1s viết bằng C cho 8051 sử dụng bộ định thời ... cái hàm này trong ASM thì e viết được nhưng chuyển sang C thì e ko biết...cảm ơn các bác
Thông báo
Collapse
No announcement yet.
hỏi về hàm Delay 1s viết bằng C cho 8051
Collapse
X
-
1s đây sao ? Nếu muốn delay 2s thì sao nhỉ ?
Nhớ khai báo biến i nếu không nó báo lỗi.Last edited by Multi System; 02-05-2009, 01:27.
Comment
-
- Nếu chỉ dùng timer thì bạn có thể tạo được độ trễ tối đa là 65,536ms với thạch anh 12M khi giá trị nạp vào TH, TL là 0000. Muốn tạo độ trễ lớn hơn thì bạn phải sử dụng thêm vòng lặp.
nếu mình muốn dùng ngắt bởi bộ định thời Timer 0 chẳng hạn thì cụ thể sẽ như thế nào
#include <at89x51.h>
void InitSystem();
void main (void)
{
InitSystem();
while(1);//Chờ ngắt timer0
}
void InitSystem()
{
TMOD = 0x01;//Timer0
TH0 = 0x00;
TL0 = 0x00;
ET0 = 1; //Cho phép ngắt Timer0
EA = 1; //Cho phép ngắt toàn cục
TR0 = 1;//Cho Timer0 chạy, đợi tràn
}
void Timer0Interrupt (void) interrupt TF0_VECTOR
{
TR0 = 0;//Dung Timer0
TH0 = 0x00;
TL0 = 0x00;
TR0 = 1;//Tiếp tục cho chạy
//Làm gì thì làm ở đây
}For a better world
Comment
-
cám ơn bạn Toan.Lv nhưng mà mình thắc mắc cái này, theo như bạn nói nhé:nếu dùng ngắt thì sẽ không gọi là delay nữa vì bản chất của delay là thời gian giữ chậm, trong thời gian này thì vdk sẽ chỉ chờ thôi, chẳng làm được việc gì khác cả
Nhưng mà theo mình thấy thì kể cả khi dùng ngắt,trong cái bài toán Delay1s này thì lúc chờ ngắt Timer0 thì VĐK cũng chỉ chờ cho cờ TF được set thì cho phét ngắt thôi mà nhỉ ( cái vòng lặp vô tận While(1) {} ấy ) ...và như vậy mình đang thắc mắc là viết hàm delay sử dụng Timer đơn thuần như bạn Angort thì có khác j sử dụng ngắt của Timer...Mong bạn jải đáp hộ mình ..rất cảm ơn bạn|
Comment
-
Việc sử dụng timer để tạo hàm delay đơn thuần so với việc sử dụng ngắt có sự khác nhau rất lớn mà rõ ràng và quan trọng nhất là việc phân quyền sử dụng tài nguyên CPU. Tôi có thể lấy một ví dụ đơn giản để bạn hình dung. Giả sử CPU của VDK là bạn, còn timer0 là cái đồng hồ đeo tay của bạn thế thì:
- Đối với hàm delay bình thường dùng timer:Giả sử bạn muốn chờ từ 2h đến 3h để làm một việc gì đó. bạn phải ngồi và nhìn kim đồng hồ quay. Bạn luôn luôn phải theo dõi cái kim đồng hồ mà không được phép làm bất kì điều gì khác ngoài việc đó. Tuy nhiên từ 2h đến 3h bạn còn rất nhiều kế hoạch cần làm, trong khi lại cứ phải ngồi chờ một cách vô vị, như thế thật là nhàm chán và lãng phí thời gian. Giải pháp cho bạn là hãy sử dụng chế độ hẹn giờ
- Dùng ngắt timer tương tự như việc bạn đặt hẹn giờ. Thay vì ngồi chờ từ 2h đến 3h bạn hãy đặt hẹn giờ, cứ sau bao nhiêu lâu thì cái đồng hồ nó lại nhắc bạn một lần để bạn biết đến lúc phải làm điều gì đó. Còn khi nó không nhắc thì bạn cứ làm việc của mình. Như vậy thì bạn vừa có thể làm được rất nhiều việc, vừa không quên việc cần làm.
Trong ví dụ ở bài trước, tôi chỉ viết mẫu cái hàm cho phép và phục vụ ngắt timer thôi, còn ở chương trình chính thì muốn làm gì thì làm, không làm thì ngồi chờ. Nhưng sự khác nhau cơ bản giữa delay và ngắt có thể thấy trong ví dụ vừa nêu. Mong có thể giúp ích cho bạn đôi điều.
Thân mến,For a better world
Comment
-
mình trình bày 2 điểm theo như mình hiểu hiện tại sau đây : đối với hàm Delay
Thứ nhất:
Trong hàm main, sau khi ta gọi hàm khởi tạo initSystem()
void main (void)
{
InitSystem();
while(1);//Chờ ngắt timer0
}
Thứ hai:
Trong ISR, mình thắc mắc điểm này
void Timer0Interrupt (void) interrupt TF0_VECTOR
{
TR0 = 0;//Dung Timer0
TH0 = 0x??;// cái này tự mình tính toán hoặc sủ dụng thêm vòng lặp để
TL0 = 0x??;// tạo khoảg thời gian trễ là 1s
TR0 = 1;//Tiếp tục cho chạy
//Làm gì thì làm ở đây
}|
Comment
-
mình biết là 1s thì fải sử dụng thêm vòng lặp rồi nhưu mà để đơn giản chúng ta cứ giả sử như thế đi
Mình nghĩ là nếu để những lệnh "Làm gì thì làm ở đây" sau lệnh TR0=1 thì kể từ thời điểm set TR0=1 và thựuc hiện tiếp 1 số lệnh ( giả sử tổng số chu kì lệnh là 100 thì Timer sẽ hoạt động và sau khi ra khỏi chương trình con phục vụ ngắt , chỉ sau (1 triệu - 100) = 999900 chu kì lệnh tức là 0.9999s thì chưong trình chính sẽ lại cho fép ngắt Timer0 ....Tất nhiên sai số không đáng kể nhưng mình vẫn muốn biết rõ cơ chế của nó Mong bạn jải đáp hộ mình
+ Dừng timer (TR0 = 0) hết 1 chu kỳ máy
+ Nạp lại giá trị cho TH (TH0 = 0x00) hết 1 chu kỳ máy
+ Nạp lại giá trị cho TL (TL0 = 0x00) hết 1 chu kỳ máy
+ Cho phép timer0 tiếp tục đếm (TR0 = 1) hết 1 chu kỳ máy
Sau lệnh này thì timer lại bắt đầu thực hiện chu kỳ buồn bã của nó là đếm và đếm. Nó chỉ dừng lại trong 4 chu kỳ máy để CPU nạp lại các giá trị cần thiết cho TH và TL mà thôi.
+ Các lệnh thuộc vùng (//làm gì thì làm ở đây) không hề liên quan gì đến timer, đó là tác vụ của CPU vì thế thời gian thực hiện của các lệnh này không ảnh hưởng đến thời gian ngắt của timer. Tuy nhiên timer sẽ lại tiếp tục ngắt sau đúng thời gian quy định. Nếu như thời gian xử lý các tác vụ trong ngắt trước chưa xong thì sẽ xảy ra trường hợp ngắt trong ngắt. Vì thế các tác vụ xử lý trong ngắt người ta cố gắng để xử lý càng nhanh càng tốt. Nếu các việc cần làm quá dài, thì trong ngắt có thể bật một cờ để đánh dấu việc cần làm sau đó trở về chương trình chính để thực hiện việc đó.
Thân mến,For a better world
Comment
-
Xin lỗi đã cắt ngang đoạn trao đổi của 2 bạn, cũng là delay các bạn có thể giải thích cơ chế của hàm này giúp mình với, mình mới tập làm quen.
void delay (unsigned int ms)
{
unsigned char i;
while(ms)
{
i = 200;
while (i--);
ms--;
}
}
Cám ơn các bạn !
Comment
-
#2
void delay() {
for(i=0;i<20;i++) { //50000 x 20 = 1s
TH0=0x3c; //-50000 us
TL0=0xb0;
TR0=1;
while(!TF0); //cho timer0 tràn
TF0=TR0=0;
}
}
void timer0_init()
{
TMOD|=0x01;
ET0=1;
EA=1;
TR0=1;
TH0=0x3C; // 3CB0 tuong duong voi -50000
TL0=0xB0; //
}
//*********các chuong trình phuc vu ngat*********
void chuongtrinh_timer0 (void) interrupt 1 // so hieu ngat cua timer 0 la 1
{
count++;
while (count <= 20)
{
TR0=0;
TH0=0x3C;
TL0=0xB0;
if (count =20)
{
P2_0=~P2_0;
count = 0;
}
TR0=1;
}
}
thế là có sự khác nhau jữa khoảng thời jan lý thuyết 1s và thực tế...vậy đâu là nguyên nhân hả bạn??? Do Proteus hay do mình đã sai ở chỗ nào trong chương trình ... hay là fải nạp thử vào mạch thật thì mới chính xác và tại sao lại có sự khác nhau jữa Delay dùng Timer đơn thuần và Delay dùng ngắt cho timer ( với cùng já trị của TH0 và TL0 là 3CB0H)
chương trình chính đây
void main()
{
P2_0=1;
timer0_init(); // neu dung Delay bang Timer don thuan thi bo lenh nay di
while (1)
{
//delay();
//P2_0=~P2_0;
}
}|
Comment
-
Chắc do bạn có thể chưa khai báo timer0 trong đoạn chương trình của mình, mình đã thử lại thì nó đúng 1s, bạn thử lại xem nhé.
Đây là chương trình:
#include <at89x52.h>
void delay(unsigned char t){
unsigned char i;
for(i=0;i<t;i++){
TH0=0x3c; //-50000 us
TL0=0xb0;
TR0=1;
while(!TF0); //cho timer0 tràn
TF0=TR0=0;
}
}
void main(void){
TMOD=0x01;
while(1){
delay(20);
P1_0=1;
delay(20);
P1_0=0;
}
}
Comment
-
Nguyên văn bởi agnort Xem bài viếtChắc do bạn có thể chưa khai báo timer0 trong đoạn chương trình của mình, mình đã thử lại thì nó đúng 1s, bạn thử lại xem nhé.
Đây là chương trình:
#include <at89x52.h>
void delay(unsigned char t){
unsigned char i;
for(i=0;i<t;i++){
TR0=0; // Dừng bộ định thời
TH0=0x3c; //-50000 us
TL0=0xb0;
TR0=1;
while(!TF0); //cho timer0 tràn
TF0=TR0=0;
}
}
void main(void){
TMOD=0x01;
while(1){
delay(20);
P1_0=1;
delay(20);
P1_0=0;
}
}
Theo mình nghĩ là khi đó chưa khởi động bộ định thời nên không cần.
Cám ơn các bạn !
Comment
Bài viết mới nhất
Collapse
-
Trả lời cho Hỏi cách điều chế xungbởi thetungBạn cho qua cái Tờ ri gơ Sờ mít ấy ......
-
Channel: Kỹ thuật điện tử tương tự
16-12-2024, 11:26 -
-
Trả lời cho Hỏi cách điều chế xungbởi nguyendinhvanCó gì mà khó ?
Răn cưa vuông đây
...-
Channel: Kỹ thuật điện tử tương tự
15-12-2024, 23:36 -
-
Trả lời cho hỏi về tụ điệnbởi ndp62Chữ " VENT" không phải là tên hãng sx tụ đâu ,vó thế là 1 ký hiệu liên quan tụ lowesr ?
-
Channel: Điện thanh
15-12-2024, 18:24 -
-
Trả lời cho Thắc mắc về nguồn tổ ong 12vbởi bqvietTrừ trường hợp công suất (rất) thấp, hầu như tất cả các loại nguồn xung thông thường đều có tụ nhỏ 1 - 10nF nối giữa sơ cấp và thứ cấp, để thoát nhiễu và để chống hiện tượng tương tự tĩnh điện. Vụ này đã thảo luận vài...
-
Channel: Điện tử dành cho người mới bắt đầu
14-12-2024, 22:02 -
-
Trả lời cho Thắc mắc về nguồn tổ ong 12vbởi namlangnhoE thử 3 cái nguồn nó đều giống nhau. Nên e làm tiếp địa luôn.
-
Channel: Điện tử dành cho người mới bắt đầu
14-12-2024, 19:58 -
-
Trả lời cho Thắc mắc về nguồn tổ ong 12vbởi mèomướpDạ chú sắm con át chống giật và thay nguồn tổ ong khác cho an toàn ạ. Đa phần nguồn xung đều xả nhiễu của bên thứ cấp về điện lưới qua 1 con tụ nên cảm giác tê sẽ khó xác định rõ ràng là do rò điện hay là nó vốn vậy...
-
Channel: Điện tử dành cho người mới bắt đầu
14-12-2024, 18:51 -
-
bởi namlangnhoXin chào mọi người. E có sử dụng 1 cục nguồn tổ ong 12v-30A chạy đèn led xe trà sữa. Mà thợ thi công bị rò điện nên điện rò ra khung xe. E dùng đồng hồ đo điện ở khung xe và cả output thì thấy có dòng điện xoay chiều hơn 100v. Nên chạm...
-
Channel: Điện tử dành cho người mới bắt đầu
14-12-2024, 00:12 -
-
bởi Manh.n.trCác bác cho em hỏi cách điều chế xung răng cưa sang xung vuông với ạ. Em đang thấy khó ạ...
-
Channel: Kỹ thuật điện tử tương tự
13-12-2024, 20:46 -
-
Trả lời cho hỏi về thiết kế mạch tuần tự trên proteusbởi Hatruong1309
-
Channel: Hỗ trợ học tập
12-12-2024, 00:33 -
-
bởi Hatruong1309Cho e hỏi là phần chân X thì nối cái j thì mạch mới chạy được ạ và kiểm tra đúng sai kiểu j ạ
Đề bài thiết kế mạch dãy đồng bộ nhận biết dãy tín hiệu vào ở dạng nhị phân được đưa liên tiếp ở đầu vào X và được đồng...-
Channel: Hỗ trợ học tập
12-12-2024, 00:33 -
Comment