Thông báo

Collapse
No announcement yet.

Xin gỡ rối dùm Ngắt trong Keil C

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

  • Xin gỡ rối dùm Ngắt trong Keil C

    Mình đang làm quen với C trong vi điều khiển( dùng Keil C). Mình có thử một đoạn code dùng timer2 trong 89C52, tạo ngắt 1ms. Cứ mỗi 1000ms thì cho nháy đèn led 1 lần. Debug bằng keil C hoặc proteus đều Ok cả, nhưng nạp vào mạch thì lại không chạy( mạch ok đã được test bàng "hello world").
    Mình paste code ở đây, bạn nào rảnh thì xem hộ. Lập trình ngắt có cần chú ý gì không?Xin chỉ giáo.
    #include<Reg52.h>

    sbit led_pin=P1^0;
    unsigned int counter=0;
    void Timer2(void)
    {
    T2CON = 0x04; // Load Timer 2 control register
    TH2 = 0xFC; // Load T2 high byte
    RCAP2H = 0xFC; // Load T2 reload capt. reg. high byte
    TL2 = 0x2B; // Load T2 low byte
    RCAP2L = 0x2B; // Load T2 reload capt. reg. low byte
    ET2 = 1;
    TR2 = 1;
    EA = 1; // Globally enable interrupts
    }
    void main(void)
    {
    Timer2();
    while(1);
    }
    void ISR_1000ms(void) interrupt 5
    {
    TF2 = 0;

    if (counter==1000)
    {
    counter=0;

    led_pin=~led_pin;

    }
    else
    counter++;

    }

  • #2
    Coi hoài thì thấy không sai, nhưng bạn thử ban đầu cho T2CON = 0x00; xem sao!
    !e

    Comment


    • #3
      Mình cũng không thấy sai. Bạn phải dùng oscillo soi chân P1.0 chứ dùng led thì nhỡ bạn quét nhanh quá nó ko hiện thì sao.

      Comment


      • #4
        Mình nghĩ rằng trình phục vụ ngắt quá lớn nên gây ra lỗi. Mình thử viết ngắn lại như sau và đã chạy ok. Tuy nhiên không hiểu trong Keil C có những chỉ lệnh tương tự như ORG trong ASEM hay không( để xác định vị trí đặt IRS).

        void main(void)
        {

        Timer2();
        Init_clock();
        while(1)
        {
        if (counter==20)
        {
        counter=0;
        led_pin=~led_pin;
        }
        }

        }
        void ISR_1000ms(void) interrupt 5
        {
        TF2 = 0;
        counter++;

        }

        Comment


        • #5
          Khi ngắt xảy ra, thì nó sẽ nhãy vào HÀM nào trong chương trình????

          Comment


          • #6
            Tôi có một ví dụ dùng ngắt timer của C51 để làm nhấp nháy led (đèn sáng 1s, tắt 1s), chương trình viết bằng Keil/C. Có source code + sơ đồ mạch điện, bạn dowload file cktimer.pdf tại link này:
            http://www.diendandientu.com/diendan...d?thread=10222
            0912666017

            Comment


            • #7
              Các bạn ơi cho tôi hỏi.Tại sao khi tôi đăng nhập ở diendandientu.com thì chương trình báo đã hoàn thành và kiểm tra lại mail để lấy mã kích hoạt, nhưng không bao giờ nhận được mã kích hoạt cả. Tôi đã tạo vài hộp thư để thử lại đều không được. Bạn nào có kinh nghiệm chỉ giùm tôi với. Xin cảm ơn.

              Comment


              • #8
                Nguyên văn bởi kitanai
                #include<Reg52.h>

                sbit led_pin=P1^0;
                unsigned int counter=0;
                void Timer2(void)
                {
                T2CON = 0x04; // Load Timer 2 control register
                TH2 = 0xFC; // Load T2 high byte
                RCAP2H = 0xFC; // Load T2 reload capt. reg. high byte
                TL2 = 0x2B; // Load T2 low byte
                RCAP2L = 0x2B; // Load T2 reload capt. reg. low byte
                ET2 = 1;
                TR2 = 1;
                EA = 1; // Globally enable interrupts
                }
                void main(void)
                {
                Timer2();
                while(1);
                }
                void ISR_1000ms(void) interrupt 5
                {
                TF2 = 0;

                if (counter==1000)
                {
                counter=0;

                led_pin=~led_pin;

                }
                else
                counter++;

                }
                Chào kitanai!

                Theo như khai báo thì chu kỳ chớp tắt khoảng gần 1S.
                Bạn thử khai báo lại biến counter thành kiểu long xem kết quả thế nào.
                C chuẩn là ngôn ngữ còn cấu trúc, theo cấu trúc thì các function phải đặt trước main() và hàm gọi phải viết sau hàm được gọi. Nếu muốn viết tự do thì cần khai báo prototype. Vì thế bạn nên đặt cả hàm ngắt lên trên hàm main().

                Chúc bạn thành công!
                Một bông hồng cho những ai đang còn mẹ,
                Đang còn mẹ để lòng vui sướng hơn ..

                Comment


                • #9
                  Cảm ơn các bạn đã góp ý. Cái mình băn khoăn ở đây là vì sao debuge bằng Keil và proteu đều ok nhưng nạp vào lại không chạy. Mình thử mày mò và tick vào phần option for target, chọn LX51 instead of BL51, thì chạy ngon. Mình cũng chưa tìm hiểu kỹ tại sao. Thanks mọi người.

                  Comment


                  • #10
                    Nguyên văn bởi kitanai Xem bài viết
                    Mình nghĩ rằng trình phục vụ ngắt quá lớn nên gây ra lỗi. Mình thử viết ngắn lại như sau và đã chạy ok. Tuy nhiên không hiểu trong Keil C có những chỉ lệnh tương tự như ORG trong ASEM hay không( để xác định vị trí đặt IRS).

                    void main(void)
                    {

                    Timer2();
                    Init_clock();
                    while(1)
                    {
                    if (counter==20)
                    {
                    counter=0;
                    led_pin=~led_pin;
                    }
                    }

                    }
                    void ISR_1000ms(void) interrupt 5
                    {
                    TF2 = 0;
                    counter++;

                    }
                    Trong C ko có hàm ORG mà khi dịch nó sẽ tự sắp xếp các đoạn code. Tuy nhiên bạn vẫn có thể đặt địa chỉ cho hàm main bằng cách add vào project file startup.a51 và sửa nó. Tôi thường đặt hàm main ở địa chỉ bắt đầu là 30H.

                    Comment


                    • #11
                      void ISR_1000ms(void) interrupt 5 // chi co interupt tu 0-4 thoi ban oi lam gi co interupt 0

                      ban thu thay doi theo ham ngat nay xem
                      void timer0(void) interrupt 1 using 0// dung ngat timer 0 su dung bank 0;

                      //Interrupt 0: Ngat ngoai 0
                      //Interrupt 1: Ngat do tran bo dinh thoi 0
                      //Interrupt 2: Ngat ngoai 1
                      //Interrupt 3: Ngat do tran bo dinh thoi 1
                      //Interrupt 4: Ngat ngat noi tiep
                      //using bank 0,1,2,3 mac dinh la 0

                      Comment


                      • #12
                        hinh nhu sau khi ngat pai nap lai gia tri thanh ghi

                        Comment


                        • #13
                          Help

                          em viết thử code cho mạch đếm sản phẩm dùng ngắt ngoài nhưng ko hiểu sao trình dịch cứ báo lỗi " syntax error near 'void' " em viết nhiều chương trình dùng ngắt đều báo thế cả . mong các pro chỉ giúp
                          #include <REGX51.H>
                          #include<stdio.h>
                          #include<math.h>
                          void delay(unsigned int t)
                          {
                          int i;
                          for(i=1;i<=t;i++);
                          }
                          unsigned char M[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x9 0};
                          int i,ng,tr,ch,dv,num;
                          void main(void)
                          {
                          num=0;
                          IE=0x84;
                          IT1=1;
                          while(1)
                          {

                          ng = num/1000;
                          tr = (num%1000)/100;
                          ch = ((num%1000)%100)/10;
                          dv = num%10;
                          for(i=0;i<=200;++i)
                          {
                          P3=0x80;
                          P2=M[dv];
                          delay(20);
                          P3=0x40;
                          P2=M[ch];
                          delay(20);
                          P3=0x20;
                          P2=M[tr];
                          delay(20);
                          P3=0x10;
                          P2=M[ng];
                          delay(20);
                          }
                          }
                          void ngatngoai_1(void) interrupt 2
                          {
                          if(num==9999) num=0;
                          ++num;
                          }
                          }
                          Dùng thử website bán hàng chuyên nghiệp hoàn toàn miễn phí :

                          Liên hệ ngay: 01649440 năm một năm

                          Comment


                          • #14
                            B xem lại dấu } đi đóng nhầm rùi. cho dấu } dưới cùng lên hàng trên void ngatngoai_1(void) interrupt 2 là ok. chúc vui

                            Comment


                            • #15
                              Nguyên văn bởi quang_le_pt Xem bài viết
                              B xem lại dấu } đi đóng nhầm rùi. cho dấu } dưới cùng lên hàng trên void ngatngoai_1(void) interrupt 2 là ok. chúc vui
                              Thanks bác nha em mới học cái này chưa đọc kĩ đầu tiên cứ tưởng ngắt phải nằm trong main void

                              Comment

                              Về tác giả

                              Collapse

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

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

                              Collapse

                              Đang tải...
                              X