Thông báo

Collapse
No announcement yet.

hỏi về hàm Delay 1s viết bằng C cho 8051

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • #16
    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.
    Trích:
    void delay (unsigned int ms)
    {
    unsigned char i;
    while(ms)
    {
    i = 200;
    while (i--);
    ms--;
    }
    }
    Ý nghĩa của từng câu lệnh, và ứng với câu lệnh đó thì CPU xử lí thế nào?
    Cám ơn các bạn !
    - Đây là chương trình con tạo trễ dùng vòng lặp while. Hàm này có một tham số là ms. Khi gọi hàm này, CPU sẽ xử lý như sau:
    B1: Khai báo sử dụng biến i
    B2: Kiểm tra ms, nếu ms khác 0 thì chuyển sang bước 3, nếu bằng 0 thì thoát
    B3: Gán giá trị 200 cho biến i
    B4: Giảm i đi một đơn vị, kiểm tra xem có khác 0 hay không, nếu chưa thì tiếp tục giảm rồi lại kiểm tra, nếu bằng 0 thì chuyển qua bước 5
    B5: Giảm ms đi 1 rồi quay về bước 2

    Như vậy chương trình tạo trễ này yêu cầu CPU làm ms lần đếm lùi từ 200 về 0.

    Thân mến,
    For a better world

    Comment


    • #17
      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)
      - Tại hạ ít sử dụng proteus nên không biết nó có gây lỗi ở hàm delay hay không, hi vọng những cao thủ proteus trên diễn đàn có thể giải thích thắc mắc này giúp bạn machithanh.
      - Tuy nhiên khi lập trình, muốn dùng timer làm bộ định thời và tạo ra độ trễ thời gian là bao nhiêu là hoàn toàn nằm trong ý muốn chủ quan của người lập trình. Chúng ta phải tính toán trước giá trị nạp cho timer và số lần lặp để có được độ trễ thời gian mong muốn. Và đương nhiên khi ta nạp nó vào chíp, (hay mô phỏng) ta mong muốn thời gian trễ đó đúng với những điều ta đã tính toán trước đó. Nếu mạch dao động của VDK nối đúng và hoạt động tốt, chắc chắn độ trễ thời gian thực tế sẽ phản ánh đúng những gì ta tính toán. Nếu thời gian thực tế không như ta nghĩ, chỉ có một giải thích là ta đã tính toán sai ở đâu đó.
      - Về bản chất, timer chỉ có một nhiệm vụ duy nhất là đếm xung nhịp. Khi xung nhịp đưa vào đếm ở timer là xung nhịp của hệ thống (xung nhịp của CPU) thì ta gọi nó là bộ định thời (theo đúng nghĩa timer). Đặc điểm của xung nhịp hệ thống là nó rất đều, vì thế có thể dùng để định thời gian. Cứ mỗi lần có một xung đi vào timer, thì giá trị của nó tăng lên 1 đơn vị. Như vậy nếu sau một thời gian nào đó, ta đọc được ở timer giá trị n thì tức là nó đã đếm được n xung nhịp. Từ đó tính ra thời gian bằng cách lấy n nhân với thời gian của một chu kỳ máy.
      - Nếu thạch anh ngoài là 12M. Tần số clock CPU của 8051 bằng tần số clock thạch anh ngoài chia cho 12. Từ đó mỗi xung clock của CPU xuất hiện trong 1us. Vậy thời gian trễ nhận được sau n lần đếm là: n us
      - Tuy nhiên bạn chú ý rằng cả hai thanh ghi chứa giá trị khởi đầu của timer là TH và TL chỉ có độ dài 8bit, tức là giá trị tối đa có thể chứa trong 2 thanh ghi này chỉ là FFFFH. Vậy timer chỉ có thể đếm lớn nhất đến FFFF (65536) xung. Từ đó nếu chỉ dùng timer bạn tạo được thời gian trễ tối đa là 65536us = 65,536 ms. Nếu muốn tạo thời gian trễ lớn hơn, bạn phải sử dụng thêm vòng lặp.

      Thân mến,
      For a better world

      Comment


      • #18
        mình dùng Delay bằng ngắt thì ra mạch thậ ngáo ngơ lắm, im thin thít
        nhưng mà dùng Timer tạo hàm Delay ( chờ Timer tràn đơn thuần ) thì ok. Mạch ổn định

        Nhưng có điều là khoảng thời gian tính toán lý thuyết khác với thực tế nhiều lắm
        Lý thuyết
        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;
        }
        }
        _thực tế mạch thật mình chạy nếu muốn Delay 1s thì phải set là:
        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;
        }
        }

        mai()
        ....
        delay(150);//150*50000=7,5s
        thế là thế nào hả các ae ???

        Comment


        • #19
          mình dùng Delay bằng ngắt thì ra mạch thậ ngáo ngơ lắm, im thin thít
          nhưng mà dùng Timer tạo hàm Delay ( chờ Timer tràn đơn thuần ) thì ok. Mạch ổn định

          Nhưng có điều là khoảng thời gian tính toán lý thuyết khác với thực tế nhiều lắm
          Lý thuyết
          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;
          }
          }
          _thực tế mạch thật mình chạy nếu muốn Delay 1s thì phải set là:
          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;
          }
          }

          mai()
          ....
          delay(150);//150*50000=7,5s
          thế là thế nào hả các ae ???
          |

          Comment


          • #20
            Bạn dùng thạch anh bao nhiêu vậy ?
            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); // chờ 1s
            P1_0=1; // tắt led (Ví dụ +5V->R->Led->P1_0)
            delay(20);// Chờ 1s
            P1_0=0; // bật led
            }
            }
            Kết quả: led sáng trong 1s sau đó lại tắt trong 1s.
            Lý thuyết là như vậy và thực tế cũng vậy (Với thạch anh 11.0592)
            Last edited by Multi System; 07-05-2009, 18:21.

            Comment


            • #21
              Bạn dùng thạch anh bao nhiêu vậy ?
              mình dùng con thạch anh có ghi ở trên số 12.000
              bó tay hay là ghi như vậy mà ko fai? như vậy hả cac bạn
              |

              Comment


              • #22
                Bạn thay con 89 khác thử xem sao.
                Hay là bạn cho mình xem toàn bộ chương trình của bạn đi. OK !

                Comment


                • #23
                  ok, chương trình của mình đây, điều khiển mạch giao thông Nhờ các ae trong diễn đàn và đặc biệt cám ơn bạn Toan.LV đã jup minh` viết bài này mình viết hơi xôi thịt còn non kém mà có lẽ mình sẽ fat triển dần lên cho gọn gàng hơn
                  #include <REGX51.H>
                  int count;
                  unsigned char hangchuc, hangdonvi, dem1, dem2;

                  sbit do1=P2^0;
                  sbit xanh1=P2^1;
                  sbit vang1=P2^2;
                  sbit do2=P2^3;
                  sbit xanh2=P2^4;
                  sbit vang2=P2^5;

                  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 display1()
                  {
                  hangdonvi = dem1%10;//Tách hàng ?o+n vi.
                  hangchuc = dem1 /10;//Tách hàng chu.c
                  hangchuc =hangchuc << 4; //?u+a 4 bít tha^'p lên 4 bít cao
                  P1 = hangchuc | hangdonvi;//Out ra co^?ng
                  }


                  void display2()
                  {
                  hangdonvi = dem2%10;//Tách hàng ?o+n vi.
                  hangchuc = dem2 /10;//Tách hàng chu.c
                  hangchuc =hangchuc << 4; //?u+a 4 bít tha^'p lên 4 bít cao
                  P0 = hangchuc | hangdonvi;//Out ra co^?ng
                  }


                  void main()
                  {
                  do1=xanh1=vang1=do2=xanh2=vang2=0;

                  while(1)
                  {




                  dem1=35;
                  dem2=31;
                  while(dem2+1)
                  {
                  P2=0;
                  do2=1;
                  xanh1=1;
                  display1();
                  display2();
                  delay(150);
                  dem1=dem1-1;
                  dem2=dem2-1;
                  }

                  dem2=3;
                  dem1=3;
                  while (dem1+1)
                  {
                  P2=0;
                  do2=1;
                  vang1=1;
                  display1();
                  display2();
                  delay(150);
                  dem1=dem1-1;
                  dem2=dem2-1;
                  }

                  dem1=31;
                  dem2=35;

                  while(dem1+1)
                  {
                  P2=0;
                  do1=1;
                  xanh2=1;
                  display1();
                  display2();
                  delay(150);
                  dem1=dem1-1;
                  dem2=dem2-1;
                  }
                  dem2=3;
                  dem1=3;

                  while (dem2)
                  {
                  P2=0;
                  do1=1;
                  vang2=1;
                  display1();
                  display2();
                  delay(150);
                  dem1=dem1-1;
                  dem2=dem2-1;
                  }

                  }

                  }
                  |

                  Comment


                  • #24
                    TMOD của bạn đâu rồi ?
                    Chết ấy chứ !
                    Last edited by Multi System; 07-05-2009, 19:22.

                    Comment


                    • #25
                      main()
                      {
                      TMOD=0x01;
                      ....
                      delay(20);
                      ....

                      }
                      chuẩn rồi bạn à...rất cám ơn
                      |

                      Comment


                      • #26
                        Cho TMOD vào trong main cũng không sao.
                        Theo đúng cách lập luận bạn nên xác định TMOD trước khi nạp giá trị cho 2 thằng TH và TL, như vậy cho đỡ quên.

                        Comment


                        • #27
                          thanks mình sẽ chú ý
                          |

                          Comment


                          • #28
                            bạn dùng thạch anh 12M thì nhập giá trị nạp cho TH và TL
                            TH=0x3C;
                            TL=0xB0;
                            là đúng 1s khi delay(20);
                            Last edited by Multi System; 07-05-2009, 22:46.

                            Comment


                            • #29
                              bạn dùng thạch anh 12M thì phải nhập lại giá trị nạp cho TH và TL thì mới đúng 1s
                              TH=0x3C;
                              TL=0xAF;
                              ừ thì thực ra 3CAF +1 = 3CB0 mà nên khác nhau quá nhỏ có 1 micro giây mà Multi system
                              |

                              Comment


                              • #30
                                Không !
                                Mình tính nhầm qua công thức Hexa, giá trị bạn nạp là đúng rồi.
                                Thuật toán đếm lùi số của bạn là gì vậy ?

                                Comment

                                Về tác giả

                                Collapse

                                machithanh Tìm hiểu thêm về machithanh

                                Bài viết mới nhất

                                Collapse

                                Đang tải...
                                X