Thông báo

Collapse
No announcement yet.

Ngắt ngoài ! Nhờ các cao thủ giúp đỡ

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

  • Ngắt ngoài ! Nhờ các cao thủ giúp đỡ

    Tôi có một vấn đề với ngắt ngoài, nhờ các bác cao thủ ở đây giúp đỡ.
    Tôi viết một chương trình bằng Keil C để kiểm tra ngắt ngoài. Debug trên Keil thì có vẻ ổn, nhưng khi chạy mạch thật thì có vấn đề. Vấn đề ở đây là mạch đã tạo ra ngắt, chương trình ngắt đã chạy nhưng khi chạy hết chương trình ngắt thì không trở về chương trình chính nữa.
    Trong chương trình chính có vòng lặp while (1), trong đó cho hien thị ra LCD các số từ 1 đến 9. Ngắt được tạo ra từ các nút bấm. Khi một trong các nút bấm được ấn (mức tín hiẹu 0) thì sẽ tạo ra một xung để tạo ra ngắt. Mạch ngắt tôi post ở dưới các bác xem qua nhé. Khi chương trình ngắt chạy thì kiểm tra xem nút nào được ấn rồi hiển thị ra LCD tên nút.
    Các bác giải thích dùm xem tôi đã viết chương trình sai ở chỗ nào mà chương trình của tôi khi chạy vào chương trình ngắt rồi, nhận nút bấm rồi, hiển thị ra LCD rồi. Nhưng nó nhất quyết không chịu về chương trình chính ( không tiếp tục hiển thị các số từ 1 đến 9 nữa). Nhưng nếu có một ngắt tiếp tục xảy ra thì chương trình ngắt lại tiếp tục chạy (lại kiểm tra nút bấm). Debug trên Keil thì tôi vẫn thấy nó quay trở lại chương trình chính và tiếp tục hiển thị các số. Các bác cao thủ hãy ra tay giúp đỡ tôi nhé. Thanks !

  • #2
    Đây là code chương trình và file mạch. Các bác giúp đỡ nhé !
    Last edited by quangnv_bk; 22-10-2005, 01:37.

    Comment


    • #3
      CHưa phát hiện thấy chỗ sai của bác, bác thử gắn 1 con tụ 104 vào chan INT xem sao. Ah, bác chuyển thành schematic -->gif(kích thước <600*700) và post lên diến đàn xem sao. Vì máy tui và máy 1 số người ko cài Orcad
      -------------------

      Comment


      • #4
        Cảm ơn CHIBANG đã trả lời. Tôi không nghĩ là có vấn đề ở mạch đâu vì mạch đã tạo ra ngắt, chương trình ngắt đã chạy, nhưng có điều VĐK không quay trở về chương trình chính (mà thực ra bây giờ thì tôi cũng không hiểu nó đang ở đâu nữa). Tôi nghĩ là do chương trình thôi. Có thể là tôi chưa thực sự hiểu về ngắt.
        Hiện tượng trong thực tế mạch của tôi chạy như thế này. Khi bắt đầu chương trình, các số từ 1 đến 9 lần lượt hiện lên theo vòng lặp (tôi dùng LCD để hiển thị). Khi một phím được bấm sẽ tạo ra một xung trên chân ngắt INT0 (kích cạnh âm). Chương trình ngắt chạy và kiểm tra phím đã được bấm. Chương trình chạy hoàn toàn đúng cho đến đây. Theo tôi hiểu thì sau khi chạy xong chương trình ngắt này thì VĐK sẽ quay trở lại chương trình chính và thực hiện tiếp chương trình. Thế nhưng trên thực tế thì tôi không thấy LCD tiếp tục hiển thị các số nữa, nhưng khi tiếp tục bấm nút thì chương trình ngắt tiếp tục chạy. Đây là điều tôi không hiểu. Hay là tôi đã hiểu sai về ngắt. Rất mong các bác chỉ giáo

        Comment


        • #5
          Tôi không phải là người biết nhiều nhưng tôi nghĩ có lẽ bạn bị sai ở cấu trúc vòng lặp while (1).
          có lẽ khi bạn kiểm tra nó rơi vào vòng vô tận và không thoát về chương trình chính.
          --- Bạn có thể làm lại cách này xem có hiệu quả hơn không :
          while(1)
          { while ( không phím nào ấn )
          kiểm tra ();
          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


          • #6
            để tôi bắt mạch tiếp cho , có khi nào không reset LCD " về mo " nó bị tràn bộ nhớ nên không hiển thị được há ??? Thử cho nó " hiện tên nút lên một khoảng thời gian rồi sau đó clear hết đi để hiện tên mới xem có khá khẩm hơn không ?.
            -- Theo đúng bạn hiểu : ngắt tạo ra để bắt thằng CPU vào và làm việc của nó xong rồi lại tiếp tục làm việc (main).
            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


            • #7
              Theo tôi, nguyên nhân có thể là như sau :
              -Chương trình của bạn sử dụng ngắt theo mức, nghĩa là khi có mức âm ở chân ngắt Ext0 thì sẽ sinh ra ngắt. Phương pháp này có một điểm bất lợi là nếu chân này vẫn =0 thì ngắt xảy ra liên tục ( khi chạy simulator thì không phát hiện được vấn đề này).Đến khi bạn ấn và nhả phím, đã có khá nhiều ngắt cùng sinh ra và chương trình sẽ liên tục gọi thủ tục ngắt , dẫn đến hiện tượng rất lâu sau mới quay về chương trình main.
              Để khắc phục hiện tượng này, thay vì cấu hình ngắt theo mức, ta chuyển sang chế độ ngắt theo sườn , khi đó lúc ấn phím chỉ có một ngắt sinh ra.
              Chỉ cần thêm vào đoạn thủ tục Init như sau :
              void Init()
              {
              .......
              IT0=1; // set Ext0 falling edge
              ......
              }

              Comment


              • #8
                Ừ, quá đúng.
                Lâu rồi ko làm 89 nên ko phát hiện ra, vì thông thường em hay đặt ngắt theo sườn nên mặc nhiên công nhận tất cả trường hợp đều thế. He he...
                Trường hợp bạn quangnv_bk nói trên thì ko những ở lâu ko quay lại ngắt mà còn tệ hơn là treo do tràn ngăn xếp
                -------------------

                Comment


                • #9
                  Nguyên văn bởi trungkt
                  Theo tôi, nguyên nhân có thể là như sau :
                  -Chương trình của bạn sử dụng ngắt theo mức, nghĩa là khi có mức âm ở chân ngắt Ext0 thì sẽ sinh ra ngắt. Phương pháp này có một điểm bất lợi là nếu chân này vẫn =0 thì ngắt xảy ra liên tục ( khi chạy simulator thì không phát hiện được vấn đề này).Đến khi bạn ấn và nhả phím, đã có khá nhiều ngắt cùng sinh ra và chương trình sẽ liên tục gọi thủ tục ngắt , dẫn đến hiện tượng rất lâu sau mới quay về chương trình main.
                  Để khắc phục hiện tượng này, thay vì cấu hình ngắt theo mức, ta chuyển sang chế độ ngắt theo sườn , khi đó lúc ấn phím chỉ có một ngắt sinh ra.
                  Chỉ cần thêm vào đoạn thủ tục Init như sau :
                  void Init()
                  {
                  .......
                  IT0=1; // set Ext0 falling edge
                  ......
                  }


                  Hix. Vấn đề chính là ở đây. Cảm ơn bác nhé. Đây là sơ suất của tôi. Cảm ơn bác quế dương và CHIBANG nữa nhé!

                  Comment


                  • #10
                    Thằng KEil có vẻ không được chỉnh chu cho lắm về cái khoản khai báo này, chạy thử thì vẫn rầm rầm và dịch thì không có lỗi nữa chứ nhưng đến khi vào mạch cụ thể thì lại bị " dở hơi" liền . Tôi có làm một cái đồng hồ đếm lùi ( timer để làm cái hẹn giờ ) cụ thể làm như sau :
                    Khai báo : unsigned char sec , min_donvi, min_chuc , hour ;

                    -------------------- Chương trình loằng ngoằng ở đây ---------
                    + chương trình con sử lí ở đây :
                    if (hour==0 && min_chuc==0 && min_donvi ==0)
                    {P2_2 =0 ; }
                    else
                    {
                    if(sec>59)
                    {sec=0;
                    min_donvi--;
                    if(min_donvi <0)
                    {min_dv=9;
                    min_chuc--;
                    if (min_chuc <0)
                    { min_chuc=5;
                    hour --;
                    if(hour<0)
                    {hour=0;
                    }}}}
                    } // end else

                    --- Chạy chương trình dịch keil ngon lành , cú pháp giải thuật không bị lỗi
                    thế mà vào mạch cụ thể lại không chạy theo ý mình mặc dù không sai phần cứng.

                    lòng vòng mãi một hồi lâu . Cuối cùng phát hiện ra " các bác có biết là cái gì không ??? "
                    là cái khai báo ở trên kia kìa : Tôi hay quen tay gõ unsigned char để tiết kiệm bộ nhớ , ai dè chính cái unsigned trên kia cho phép từ 0 trở lên mà trong khi đó trong giải thuật lại có yếu tố " nhỏ hơn 0 " thế mà thằng keil vẫn chạy. Có thể nó quá kém chỗ này há.
                    sửa lại khai báo : char sec , min_donvi, min_chuc , hour ;
                    chạy vù vù ngay. Có thế chứ.
                    +++ cũng khai báo unsigned char sec , min_donvi, min_chuc , hour ;
                    mà lập trình trong RIDE
                    nếu nó nhận thấy có chỗ nào mà " nhỏ hơn 0 " là nó cảnh báo ngay-- thằng này nghe chừng mạnh về " ngữ pháp hơn "

                    ////// Các cụ đã dạy học đi đôi với hành , thôi đành căng mắt ra mà nhòm vậy.
                    KEIL hỡi ! không biết bao giờ nó mới cải tiến được cái này. Bác nào có bản RIDE professional cho tôi với.
                    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


                    • #11
                      Thế mà lần trước thằng bạn em bảo với em dùng Ride hay lắm nhưng vì em lỡ thích Keil nên chẳng thèm nghe lời nó. Có khi em phải cài thử để dùng xem thế nào. Bác nào có bản professional thì chia sẻ cho anh em với nhỉ

                      Comment


                      • #12
                        hoi ve hoat dong cua cac ngat
                        ________________________________________
                        #include<reg52.h>
                        //ham delay
                        //khai bao vi tri ham
                        unsigned char i,j=0x01;
                        void delay();
                        void timer0();
                        void delay(unsigned char ms)
                        {
                        while(ms--)
                        {
                        //IE = 0x81;
                        //cho phep ngat va ngat ngoai 0

                        EA = 1; //ngat canh xuong
                        EX0=1;
                        IP =0x01;
                        IT0 = 1;
                        TMOD = 0x01;
                        TH0 = 0xFC;
                        TL0 = 0x18;
                        TR0=1;
                        while(!TF0);
                        TR0 = 0;
                        TF0 = 0;
                        }
                        }
                        //ham ngat
                        void timer_0(void)interrupt 0 using 0
                        {
                        for(i=0;i<=8;i++)
                        {
                        P0 = j<<i;
                        delay(100);
                        }

                        }
                        //ham main
                        void main (void)
                        {
                        while(1)
                        {
                        P2 = 0xff;
                        delay(255);
                        P2 = 0x00;
                        delay(255);

                        }

                        }
                        Cho em hoi co phai sau khi thuc hien xong chuong trinh ngat thi tiep tuc lai tro ve chuong trinh chinh hay ko,va tiep tuc doi ngat tiep theo.Doan code tren la dang thuc hien P2 nhap nhay,khi co ngat ngoai_0 xay ra thi P0 dich led tu phai sang trai,roi tiep tuc tro ve chuong trinh chinh la P2 nhap nhay.Nhung em gap van de la sau khi thuc hien xong ngat thi chuogn trinh lai dung luon va ko quay ve chuong trinh chinh Mong cac anh giup do
                        |

                        Comment


                        • #13
                          Ngắt ngoài nè....

                          Có thể bạn bị trường hợp Bounce phím nhấn đó.Lúc đó tín hiệu ngắt là 1 chuỗi xung nên nó yêu cầu ngắt liên tục ===> treo máy.
                          Cách khắc phục: thêm 1 cổng NOT dạng SmithTrigger ở trước chân INT,ngõ vào cổng NOT này gắn thêm 1 bộ nạp xả RC giống như cho chân Reset.
                          Hy vọng là OK.
                          Có bạn sẽ nói có thể Debounce bằng phần mềm,nhưng đó là cho trường hợp quét phím.Còn ngắt thì pó hand.Chỉ có cách này thui.
                          Nếu cần trao đổi thêm thi pm cho mình theo địa chỉ YM nguyenhoaivietauf@yahoo.com
                          Nhân tiện cho mình quảng cáo chút,mình có làm KIT mô phỏng 89C51 nạp và chạy online.Anh em nao hứng thú thì pm,mình có thể chỉ cách làm luôn.

                          Comment

                          Về tác giả

                          Collapse

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

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

                          Collapse

                          Đang tải...
                          X