Thông báo

Collapse
No announcement yet.

Lập trình ngắt ngoài trong MikroC như thế nào?

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

  • Lập trình ngắt ngoài trong MikroC như thế nào?

    Mình thấy với KeilC thì lập trình ngắt cho 89C51 khá đơn giản (chắc tại có nhiêu code mẫu), nhưng khi dùng MikroC khì không biết phải làm như thế nào, nhất là khởi tạo ngắt. Đọc trong phần hướng dẫn cũng không thấy nói nhiều về phần này, tìm trên mạng cũng rất ít ví dụ cụ thể. Bác nào làm việc nhiều với MikroC có thể cho mình một ví dụ về lập trình ngắt ngoài được không? Thanks!

  • #2
    Đây là ví dụ ngắt ngoài cho AT89S8253 của mikroC ( Lấy trong mục Mẫu Ví dụ của nó ). Chắc AT89C51 cũng tương tự !!!
    Code:
    /* Project name:
         External Interrupt on Port0 (Simple 'Hello World' project)
     * Copyright:
         (c) Mikroelektronika, 2010.
     * Revision History:
         20101007:
          - initial release;
         20110224(TL):
          - adapted for PRO version
     * Description:
         This is a simple 'Hello World' project. It counts presses on PORT3.2 and
         shows result on diodes connected to PORT0.
     * Test configuration:
         MCU:          AT89S8253
         http://www.atmel.com/dyn/resources/prod_documents/doc3286.pdf
         Dev.board:    Easy8051 v6
                       http://www.mikroe.com/easy8051/
         Oscillator:   HS, 10.0000 MHz
         Ext. Modules: -
         SW:           mikroC PRO for 8051
                       http://www.mikroe.com/mikroc/8051/
     * NOTES:
         - Make sure you turn ON the PORT0 LEDs (SW7.1), set Pull up PORT3.2 (SW4.3) and set jumper J4 in GND position
     */
    
    int tmp = 0, cnt = 0xFF;                    // Global variable cnt and tmp with starting values
    
    void External_ISR()org 0x0003 ilevel 0 {    // Interrupt rutine
      EA_bit = 0;                               // Disable Interrupts
      tmp = 1;                                  // Increment variable cnt
      EA_bit = 1;                               // Enable Interrupts
    }
    
    void main() {                               // Main program
    
      P0 = 0xFF;                                // Set P0 as output
      P3 = 0xFF;                                // Set P3 as input
    
      IE = 0x81;                                // Setting the Interrupts:
    
      while(1){                                 // Unending loop
        if (tmp) {                          // tmp is temporary variable that enables us to control Interrupt counting
          cnt = cnt - 1;                      // Decreasing cnt variable (negative logic)
          tmp = 0;                            // Deleting tmp variable
        }
        P0 = cnt;                             // Write on Port0 value of varibale cnt
        delay_ms(250);                         // This is needed for button debounce
      }
    }
    Module RF chuyên dụng điều khiển, truyền dữ liệu, thiết kế đề tài, dự án điện tử - chuyển giao công nghệ... ĐT: 0904964977 - email: dientuqueduong@yahoo.com

    Comment


    • #3
      Em thấy KeilC khởi tạo ngắt ngoài INT0 bằng đoạn code
      P3_2=1; // khai báo chân lấy tín hiệu
      EA=1; // cho phép ngắt toàn cục
      EX0=1; // cho phép ngắt ngoài 0
      Trong ví dụ của MikroC, em không nhìn ra nó khai báo INT0 hay INT1 bằng câu lệnh nào anh nhỉ hay chính là đoạn org 0x0003 ilevel 0?

      Comment


      • #4
        Nguyên văn bởi tmtm Xem bài viết
        Em thấy KeilC khởi tạo ngắt ngoài INT0 bằng đoạn code

        Trong ví dụ của MikroC, em không nhìn ra nó khai báo INT0 hay INT1 bằng câu lệnh nào anh nhỉ hay chính là đoạn org 0x0003 ilevel 0?
        Mình bỏ thằng 89 của ATMEL lâu rồi , nên không nhớ rõ ... cái địa chỉ đó chỉ là định địa chỉ cho chương trình ngắt làm việc thôi ( trong 1 số trường hợp chẳng cần nó cũng chạy tốt - Ví dụ như ta không trồng cây ( trồng rau sạch) ở dưới đất mà mang lên Nóc nhà trồng chẳng hạn ).

        --- Còn Ngắt ngoài 0 hay 1 ( INT0 , INT1 ... đều do thanh ghi IE quản lý :

        IE = 0x81 ===> tương đương với EA_bit = 1 , EX0_bit =1 , Cũng vậy IE = 0x84 thì hoạt động trên INT1 ( EX1_bit =1)


        Có thể xem datasheet để hiểu về thanh ghi này .

        Trong chương trình : thay vì viết cả thanh ghi IE = 0x81 ;
        cũng có thể viết :
        EA_bit =1 ;
        EX0_bit =1;

        hoặc IE=0x84
        EA_bit =1;
        EX1_bit =1;

        CÓ THỂ đều cho kết quả là như nhau . MikroC rất " dễ tính " ... Các cách viết của các trình dịch khác đều có thể viết được bằng mikroC , bạn có thể thử xem có được không !?
        Module RF chuyên dụng điều khiển, truyền dữ liệu, thiết kế đề tài, dự án điện tử - chuyển giao công nghệ... ĐT: 0904964977 - email: dientuqueduong@yahoo.com

        Comment


        • #5
          ........................................

          Comment


          • #6
            Em đang tìm hiểu cách viết dùng cấu trúc
            switch(mode)
            {
            case 1:mode1();break;
            case 2:mode2();break;
            }
            để thực hiện một bài toán đơn giản ví dụ như bấm nút lần thứ nhất thì 1 cổng ra có tín hiệu, bấm lần thứ 2 thì cổng khác có tín hiệu chảng hạn. Với PIC + CCSC thì em làm được rồi, với thằng này em thử cắt ghép mà vẫn chưa thành công.
            Em mới chỉ viết được theo cách thông thường để mỗi khi bấm nút thì ngắt xảy ra, ví dụ như điều khiển 1 LED nhấp nháy tại P1^0 như sau:
            int tmp = 0;
            void External_ISR()org 0x0003 ilevel 0
            {
            EA_bit = 0;
            tmp = 1;
            EA_bit = 1;
            }

            void main() {

            P1 = 0xFF;
            P3 = 0xFF;
            IE = 0x81;
            while(1)
            {
            if (tmp) {
            P1 = 1;
            delay_ms(1000);
            P1 = 0;
            delay_ms(1000);

            tmp = 0;
            }
            P1 = 0; }
            }
            Các bác có thể bớt chút thời gian chỉ giúp em cách thực hiện được không ạ! Em xin cảm ơn các bác rất nhiều!

            Comment


            • #7
              Thì cứ việc lồng vào là được thôi mà, trong ngắt cứ tăng hoặc giảm biến tmp rồi trong main quét lệnh switch(tmp) là xong.

              Comment


              • #8
                Vấn đề là em không ''cứ lồng vào'' được nên mới cần các bác giúp một tay.

                Comment


                • #9
                  không được là thế nào, có phải thế này không.
                  VD:
                  Code:
                  int tmp = 0;
                  void External_ISR()org 0x0003 ilevel 0
                  {
                  EA_bit = 0;
                  if(++ tmp >= 3)tmp  = 1;
                  EA_bit = 1;
                  }
                  
                  void main() {
                  
                  P1 = 0xFF;
                  P3 = 0xFF;
                  tmp = 0;
                  IE = 0x81;
                  // nhớ là dùng ngắt sườn nhé
                  while(1)
                             {
                                            switch(tmp){
                                                            case 1 : P1 = 1;break;
                                                            case 2 : P1 = 0;break;
                                                            default  break;
                                             }
                             }
                  }

                  Comment


                  • #10
                    Nguyên văn bởi thientanvt Xem bài viết
                    không được là thế nào, có phải thế này không.
                    Em đã sửa như thế sau, nhưng nó chạy loạn lên. Mà em thấy biến tmp được dùng để kiểm tra nút bấm có được bấm không chứ sao lại ''if(++ tmp >= 3)'' nhỉ?
                    void External_ISR()org 0x0003 ilevel 0
                    {
                    EA_bit = 0;
                    if(++ tmp >= 3)tmp = 1;
                    EA_bit = 1;
                    }

                    void main() {

                    P1 = 0xFF;
                    P3 = 0xFF;
                    tmp = 0;
                    IE = 0x81;
                    IT0_bit = 0;// nh? là dùng ng?t su?n nhé
                    while(1)
                    {
                    switch(tmp){
                    case 1 : P1 = 1;break;
                    case 2 : P1 = 0;break;
                    default : break;
                    }
                    }
                    }
                    Attached Files

                    Comment


                    • #11
                      Nguyên văn bởi tmtm Xem bài viết
                      Em đã sửa như thế sau, nhưng nó chạy loạn lên. Mà em thấy biến tmp được dùng để kiểm tra nút bấm có được bấm không chứ sao lại ''if(++ tmp >= 3)'' nhỉ?
                      Chạy loạn lên có thể nó nhảy vào ngắt quá nhiều , bạn phải khống chế ngắt , chống rung phím, khi cần mới cho ngắt hoạt động trở lại

                      Code:
                      void External_ISR()org 0x0003 ilevel 0
                      {
                      EA_bit = 0;
                      if(++ tmp >= 3)tmp  = 1;   // quay lại từ đầu : 1 2 3 1 2 3 1 2 3 ......
                      
                      }
                      
                      void main() {
                      
                      P1 = 0xFF;
                      P3 = 0xFF;
                      tmp = 0;
                      IE = 0x81;
                      IT0_bit = 0;// nh? là dùng ng?t su?n nhé
                      while(1)
                                 {
                                                switch(tmp){
                                                                case 1 : P1 = 1; delay_ms(200); EA_bit = 1; break;    // sau khi làm xong việc mới bật ngắt lên
                                                                case 2 : P1 = 0; delay_ms(200); EA_bit = 1;  break;   // delay để chống rung phím đơn giản  .
                                                                default :  break;
                                                 }
                                 }
                      }
                      Module RF chuyên dụng điều khiển, truyền dữ liệu, thiết kế đề tài, dự án điện tử - chuyển giao công nghệ... ĐT: 0904964977 - email: dientuqueduong@yahoo.com

                      Comment


                      • #12
                        Không biết sao chứ em thử mô phỏng vẫn vậy anh ạ. Em thử nhồi thêm mấy trạng thái vào thì nó vẫn không cải thiện hơn chút nào.
                        int tmp = 0;
                        void External_ISR()org 0x0003 ilevel 0
                        {
                        EA_bit = 0;
                        if(++ tmp >= 5)tmp = 1; // quay l?i t? d?u : 1 2 3 1 2 3 1 2 3 ......

                        }

                        void main() {

                        P1 = 0xFF;
                        P3 = 0xFF;
                        tmp = 0;
                        IE = 0x81;
                        IT0_bit = 0;
                        while(1)
                        {
                        switch(tmp){
                        case 1 : P1 = 0b00000001; delay_ms(200); EA_bit = 1; break;
                        case 2 : P1 = 0b00000010; delay_ms(200); EA_bit = 1; break;
                        case 3 : P1 = 0b00000100; delay_ms(200); EA_bit = 1; break;
                        case 4 : P1 = 0b00001000; delay_ms(200); EA_bit = 1; break;
                        default : break;
                        }
                        }
                        }
                        Attached Files

                        Comment


                        • #13
                          Thế này được chứ ?

                          case 1 : P1 = 0b00000001; while(!P3.F2) delay_ms(200);EA_bit = 1; break;
                          case 2 : P1 = 0b00000010; while(!P3.F2) delay_ms(200);EA_bit = 1; break;
                          case 3 : P1 = 0b00000100; while(!P3.F2) delay_ms(200);EA_bit = 1; break;
                          case 4 : P1 = 0b00001000; while(!P3.F2) delay_ms(200);EA_bit = 1; break;
                          Module RF chuyên dụng điều khiển, truyền dữ liệu, thiết kế đề tài, dự án điện tử - chuyển giao công nghệ... ĐT: 0904964977 - email: dientuqueduong@yahoo.com

                          Comment


                          • #14
                            Quá OK rồi bác ạ, em đang tìm hiểu MikroC cho DsPIC, chắc sẽ lại làm phiền bác nhiều!
                            Thanks bác!

                            Comment

                            Về tác giả

                            Collapse

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

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

                            Collapse

                            • since0501
                              Trả lời cho Pin Li-FePO4 (pin sắt) rất dể hỏng! Các biện pháp ngăn ngừa.
                              bởi since0501
                              Mình đào mộ xíu, cho mình hỏi là pin của bác vẫn ok chứ? Mình vừa đóng khối pin 16 cell 40135 thì khi chạy điện áp nó sụt so với khi nghỉ như video mình dẫn link, vậy cho mình hỏi là dung lượng pin sẽ tính khi áp nghỉ hay áp đang hoạt động, và pin sụt áp như vậy là bình thường hay pin kém?
                              ht...
                              hôm nay, 17:56
                            • mèomướp
                              Trả lời cho Sửa bộ nguồn DC 60V 45A
                              bởi mèomướp
                              Dạ hông dám làm thì chắc chắn sẽ mãi ko thể làm được đâu ạ. Nguồn xung dân dụng vài kw giờ rất nhìu ạ, sạc ô tô điện, máy hàn, lò vi sóng, âm ly... tùy chất lượng mà độ phức tạp sẽ khác nhau ạ. Và cái giá phải trả về kinh tế...
                              Hôm qua, 13:11
                            • tuyennhan
                              Trả lời cho Sửa bộ nguồn DC 60V 45A
                              bởi tuyennhan
                              Sửa dạng này thì chuyên còn không dám chắc khộng cháy nổ với linh kiện bán ngoài chợ nói gì khộng chuyên .
                              Hôm qua, 09:25
                            • tuyennhan
                              Trả lời cho Cần tư vấn cải thiện chất âm thanh loa SoNy.
                              bởi tuyennhan
                              Đúng rồi chọn mua theo tai . ca thì phải toàn dải nhạc thì chỉ cao và thấp thé nên loa ca thì nghe nhạc không hay và ngược lại .
                              Muốn ca và nhạc đều hay thì phải dúng 2 giàn , còn nếu chỉ có 1 thì phải chỉnh sửa lại sao cho ca và nhạc đều được không quá dở ....
                              Hôm qua, 09:10
                            • Ng.Phuong.5
                              Vấn đề in lỗ khoan ra pdf ở Orcad 9.2
                              bởi Ng.Phuong.5
                              Vấn đề cũ: khi in mạch ra pdf và bấm chọn Keep Drill Holes Open, in ra thì pdf trắng đen các lỗ chân linh kiện như nhau. Mặc dù có linh kiện phần Drill là 1mm, có linh kiện thì là 3mm. Cho em hỏi cách sửa phần này ở Orcad 9.2 với ạ.
                              Mấy con...
                              09-01-2025, 19:44
                            • viettinh
                              Trả lời cho Cần tư vấn cải thiện chất âm thanh loa SoNy.
                              bởi viettinh
                              Bác nói đúng quá. Cơ mà muốn mua hàng chính hãng, hàng thương hiệu mà tai lại hợp hàng tầu mới khổ chứ.
                              Đang tính mua cái loa tầu nữa cột đằng sau loa này, Loa sony chỉ để hát nhép thôi, có dc k các bác ...
                              09-01-2025, 18:12
                            • nguyendinhvan
                              Trả lời cho Cần tư vấn cải thiện chất âm thanh loa SoNy.
                              bởi nguyendinhvan
                              Theo tôi thì khi hpj sản xuất ra cái loa đó, đã có nhiều chuyên gia kỹ thuật hiệu chỉnh, tính toán các phần tử kỹ lưỡng rồi.
                              Bây giờ tính toán hiệu chỉnh lại cần có đội ngũ tương đương với nhà sản xuất.
                              Cách đơn giản...
                              09-01-2025, 00:04
                            • mèomướp
                              Trả lời cho Sửa bộ nguồn DC 60V 45A
                              bởi mèomướp
                              Dạ cháu có ý tốt muốn động viên chú ấy ngâm cứu khoa học thôi ạ. Về phần kiểm tra dao động thì chú ấy chưa biết thì sẽ tìm hiểu được là cần những gì ạ, chắc chắn là khi hướng dẫn phần ấy các cô chú nào đó sẽ lưu ý cần loại sò công suất ra tránh cháy nổ rồi ạ....
                              08-01-2025, 19:02
                            • tuyennhan
                              Trả lời cho Sửa bộ nguồn DC 60V 45A
                              bởi tuyennhan
                              Chủ thớt hỏi có kiểm tra được dao động mà không cấp nguồn thì rõ trình ở mức nào mà mèo còn xúi ngâm cứu nữa ác vậy ....
                              08-01-2025, 15:43
                            • tuyennhan
                              Trả lời cho Cần tư vấn cải thiện chất âm thanh loa SoNy.
                              bởi tuyennhan
                              Loa bass đấu trực tiếp không qua phân tần để thành loa toàn dải xem có thoát tiếng khộng , nếu không thoát cần phải sửa lại mạch cs hay âm sắc nếu đủ trình còn nếu thoát ca hay nhưng chưa vừa ý vì bass kém chăc thì đấu lại như cũ và đấu thêm loa mid treble bên ngoài .
                              08-01-2025, 15:28
                            Đang tải...
                            X