Thông báo

Collapse
No announcement yet.

Giải thích đoạn code CCS về timer0 ???

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

  • Giải thích đoạn code CCS về timer0 ???

    Các huynh ai thấm nhuần cái này mong giải thích cách thức mà từng lệnh nó chạy ( tóm lại là trình tự hoạt động từ đầu đến lúc kết thúc của đoạn code). Ý nghĩa của mỗi lệnh và tính thời gian thì em đã hiểu, chỉ còn vấn đề trên mà thôi ??? Mong giúp! cảm ơn mấy huynh trước !
    Attached Files

  • #2
    #include <16f877a.h> // su dung cac dinh nghia lien quan ( ban cu mo len thí e rõ)
    #include <def_877a.h>
    #device *=16 ADC=8 // con tro 16 bit de su dung het RAM, ADC thiet lap su dung 8 bit ( mac du 16f887 la 10 bit nhung ban su dung che do 8 bit thoi)
    #FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT // cau hinh - khong watdog timer, chế độ nguồn cung clock cao - HS, không bảo về code trong bộ nhớ, không tự động reset khi nguồn không ổn định,...
    #use delay(clock=20000000) // sử dụng lệnh delay thì phải khai báo cái này
    int8 a;
    int16 count;
    #int_timer0
    void ngat_timer0()
    {
    tmr0if=0; // xóa cờ , mỗi khi timer0 đếm lên 255 thì xảy ra tràn, cờ này set lên 1 và nếu cho phép ngắt thì ngắt xảy ra. tóm lại mỗi khi có ngắt thì xóa nó để lần tiếp sẽ lại ngắt
    set_timer0(130);
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16); //125*16*0.2us=400us
    count++; // mỗi khi ngắt thì biến count tăng lên 1
    if(count==2500) // nếu biến count = 2500 thì cho biến cout bằng 0 để đếm tiếp, đồng thời xoay biến a sang trái 1 bit. kiểm tra tiếp nếu biến a = 256 hay 0xff ( toàn số 1) thì gán lại a = 1
    {count=0;
    a=a<<1;
    if (a==256) a=1;
    }
    }

    // chương trình chính giải thích như sau:
    - lệnh tris đầu tiên cho = 0 để cấu hình port d là ngõ ra, nếu cho = 0xff hay 0b11111111 thì là ngõ vào.
    - cho phép biến ngắt toàn cục, ngắt chỉ xảy ra nếu cho phép 2 bit ngắt là bit ngắt toàn cục và bit ngắt timer 0.
    -
    void main(void)
    {
    trisd=0;
    ENABLE_INTERRUPTS(Global);
    ENABLE_INTERRUPTS(INT_TIMER0);

    set_timer0(130); // lẹnh này đặt giá trị ban đầu cho timer 0, nó không bắt đầu đếm từ 0 mà từ 130.
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16); //set timer cho nay de nhay vo ct ngat phai ko?
    count =0; //trong ct ngat da co tai sao phai gan’ o~ day??
    a=1; // nhu tren??
    while(true) //neu da “true” thi no luon nam trong while nay thi lam sao ma ngat dc nua~ ??? - bạn không hiểu về ngắt rồi, ngắt làm việc độc lập, bạn hiểu không. mỗi lần xảy ra ngắt là mỗi lần bạn cho biến đếm tăng lên 1, và khi ngắt đủ 2500 lần thì thay đổi biến a rồi xuất ra portd và lại đặt biến count về = 0, lại ngắt xảy ra, biến count lại tăng lên, tăng lên 2500 thì lại cho a xoay 1 bit rồi lại xuất ra portd, nếu a = 256 tức led sáng hết rồi thì gán lại cho nó = 1 để xoay lại từ đầu nhé. tóm lại là cho led sáng dần ấy mà.
    - tóm lại bạn phải hiều về ngắt, chương trình chính cứ thực thi, nếu có ngắt xảy ra thì dừng chương trình chính lại và thwucj hiện ngắt, xong rồi lại quay lại chương trình chính. vì việc này thực thi rất nhanh nên có cảm giác vi điều khiển làm được nhiều việc cùng một lúc, thực ra mỗi thời điểm nó chỉ làm một việc thui nhé.
    {
    portd=a; //chang nhe luc nao portd cung bang 1 ?? - trời ơi, port d = giá trị biến a
    - giả sử lúc đầu a = 1 tức 0b00000001 tức 1 led sáng ở portd, timer0 cứ chạy , chạy đến khi tràn thì ngắt, ngắt thì biến count tăng lên 1 đơn vị, ngắt đủ 2500 lần thì biến count = 2500, lúc đó a thay đổi ( xoay trái), a = 3 ( thập phân ) hay a = 0b00000011- nhị phân => có 2 led ở portb sáng. hết


    - sắp sáng, em buồn ngủ quá nên viếc nếu sai thì thông cảm, không thì thanks cho cái để ngủ ngon nhá
    }
    }
    Be quan. Plz contact through email:

    Comment


    • #3
      Nguyên văn bởi Lenh Ho Xem bài viết
      #include <16f877a.h> // su dung cac dinh nghia lien quan ( ban cu mo len thí e rõ)
      #include <def_877a.h>
      #device *=16 ADC=8 // con tro 16 bit de su dung het RAM, ADC thiet lap su dung 8 bit ( mac du 16f887 la 10 bit nhung ban su dung che do 8 bit thoi)
      #FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT // cau hinh - khong watdog timer, chế độ nguồn cung clock cao - HS, không bảo về code trong bộ nhớ, không tự động reset khi nguồn không ổn định,...
      #use delay(clock=20000000) // sử dụng lệnh delay thì phải khai báo cái này
      int8 a;
      int16 count;
      #int_timer0
      void ngat_timer0()
      {
      tmr0if=0; // xóa cờ , mỗi khi timer0 đếm lên 255 thì xảy ra tràn, cờ này set lên 1 và nếu cho phép ngắt thì ngắt xảy ra. tóm lại mỗi khi có ngắt thì xóa nó để lần tiếp sẽ lại ngắt
      set_timer0(130);
      setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16); //125*16*0.2us=400us
      count++; // mỗi khi ngắt thì biến count tăng lên 1
      if(count==2500) // nếu biến count = 2500 thì cho biến cout bằng 0 để đếm tiếp, đồng thời xoay biến a sang trái 1 bit. kiểm tra tiếp nếu biến a = 256 hay 0xff ( toàn số 1) thì gán lại a = 1
      {count=0;
      a=a<<1;
      if (a==256) a=1;
      }
      }

      // chương trình chính giải thích như sau:
      - lệnh tris đầu tiên cho = 0 để cấu hình port d là ngõ ra, nếu cho = 0xff hay 0b11111111 thì là ngõ vào.
      - cho phép biến ngắt toàn cục, ngắt chỉ xảy ra nếu cho phép 2 bit ngắt là bit ngắt toàn cục và bit ngắt timer 0.
      -
      void main(void)
      {
      trisd=0;
      ENABLE_INTERRUPTS(Global);
      ENABLE_INTERRUPTS(INT_TIMER0);

      set_timer0(130); // lẹnh này đặt giá trị ban đầu cho timer 0, nó không bắt đầu đếm từ 0 mà từ 130.
      setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16); //set timer cho nay de nhay vo ct ngat phai ko?
      count =0; //trong ct ngat da co tai sao phai gan’ o~ day??
      a=1; // nhu tren??
      while(true) //neu da “true” thi no luon nam trong while nay thi lam sao ma ngat dc nua~ ??? - bạn không hiểu về ngắt rồi, ngắt làm việc độc lập, bạn hiểu không. mỗi lần xảy ra ngắt là mỗi lần bạn cho biến đếm tăng lên 1, và khi ngắt đủ 2500 lần thì thay đổi biến a rồi xuất ra portd và lại đặt biến count về = 0, lại ngắt xảy ra, biến count lại tăng lên, tăng lên 2500 thì lại cho a xoay 1 bit rồi lại xuất ra portd, nếu a = 256 tức led sáng hết rồi thì gán lại cho nó = 1 để xoay lại từ đầu nhé. tóm lại là cho led sáng dần ấy mà.
      - tóm lại bạn phải hiều về ngắt, chương trình chính cứ thực thi, nếu có ngắt xảy ra thì dừng chương trình chính lại và thwucj hiện ngắt, xong rồi lại quay lại chương trình chính. vì việc này thực thi rất nhanh nên có cảm giác vi điều khiển làm được nhiều việc cùng một lúc, thực ra mỗi thời điểm nó chỉ làm một việc thui nhé.
      {
      portd=a; //chang nhe luc nao portd cung bang 1 ?? - trời ơi, port d = giá trị biến a
      - giả sử lúc đầu a = 1 tức 0b00000001 tức 1 led sáng ở portd, timer0 cứ chạy , chạy đến khi tràn thì ngắt, ngắt thì biến count tăng lên 1 đơn vị, ngắt đủ 2500 lần thì biến count = 2500, lúc đó a thay đổi ( xoay trái), a = 3 ( thập phân ) hay a = 0b00000011- nhị phân => có 2 led ở portb sáng. hết


      - sắp sáng, em buồn ngủ quá nên viếc nếu sai thì thông cảm, không thì thanks cho cái để ngủ ngon nhá
      }
      }
      Nhầm một chỗ lệnh dịch bit, bạn xem lại nhé
      a=1; (0b00000001)
      a=a<<1 ; //a now is 2 (0b00000010) , not 3 (0b00000011)

      // neu a dich trai n bit thì tương đương a*2^n

      Comment


      • #4
        Thông cảm nhé! tại đệ đang tự tìm hiểu về VĐK! huynh chỉ cần nói "nó hoạt động độc lập" là đệ thông suốt rồi ! tại cứ tưởng chương trình chạy tuyến tính con trỏ gặp lệnh nào thì giải quyết lệnh đó! không biết cái ngắt nó hoạt động độc lập nên.....ù ờ! sẳn huynh cho hỏi muốn ngắt do RB0 thì khai báo INT_?...? . còn cái ngắt ngoài INT_EXT ý nghĩa của nó có phải là bất kì pin nào bị tác động thì đều ngắt phải ko? nhưng sao lập trình thì nó chỉ ngắt khi RB0 bị tác động! 2 cái này là một àh, thế còn cái INT_EXT1,2 là ngắt gì vậy??? Còn các timer0,1,2 ngoài mục đích dùng kèm với ngắt, delay, tạo xung thì mình còn làm gì được với nó nữa ! sẵn làm ơn cho chót xin mạn phép nhờ huynh tút cho đoạn code dùng timer làm delay lun! thanhk trước ! các huynh ai biết chỉ với!

        Comment


        • #5
          EXT1, EXT2 thì nhìn vào datasheet con MCU nó nằm trên chân nào ấy.
          Ví dụ PÍC6F877A thì INT_EXT là RB0.
          Khi sử dụng. Mỗi khi chân này thay đổi từ 0 > 1 sẽ xảy ra ngắt.

          Comment


          • #6
            biểu dương tinh thần của các bạn đi trước.!! mình thấy rất hữu ích và chi tiết.

            Comment

            Về tác giả

            Collapse

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

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

            Collapse

            Đang tải...
            X