Thông báo

Collapse
No announcement yet.

Thắc mắc về INTERRUPT trong AVR

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

  • Thắc mắc về INTERRUPT trong AVR

    em mới học ngắt trong AVR ... từ sáng nay, em làm cái mạch về đếm tiến lùi nhưng đến phần viết code thì ko bít viết kiểu j để thực hiện lệnh ngắt, uhm, thắc mắc của em là:
    theo như em hiểu thì trong vòng while(1) thì chương trình sẽ thực hiện 1 vòng lặp vô hạn, nhưng khi có ngắt xảy ra thì chương trình sẽ chạy đến ngắt->thực hiện lệnh rùi sau đó chạy đến chương trình chính (không biết em hiểu thế có j sai không), do đó em viết code (code vision) như sau :

    #include <mega8.h>
    #include <delay.h>


    // External Interrupt 0 service routine
    interrupt [EXT_INT0] void ext_int0_isr(void)
    {
    // Place your code here
    PORTB=2 ;
    }

    // External Interrupt 1 service routine
    interrupt [EXT_INT1] void ext_int1_isr(void)
    {
    PORTB=3;

    }

    // Declare your global variables here

    void main(void)
    {
    // Declare your local variables here

    // Input/Output Ports initialization
    // Port B initialization
    // Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
    // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
    PORTB=0x00;
    DDRB=0xFF;

    // Port C initialization
    // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTC=0x00;
    DDRC=0x00;

    // Port D initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTD=0x00;
    DDRD=0x00;

    // Timer/Counter 0 initialization
    // Clock source: System Clock
    // Clock value: Timer 0 Stopped
    TCCR0=0x00;
    TCNT0=0x00;

    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: Timer 1 Stopped
    // Mode: Normal top=FFFFh
    // OC1A output: Discon.
    // OC1B output: Discon.
    // Noise Canceler: Off
    // Input Capture on Falling Edge
    // Timer 1 Overflow Interrupt: Off
    // Input Capture Interrupt: Off
    // Compare A Match Interrupt: Off
    // Compare B Match Interrupt: Off
    TCCR1A=0x00;
    TCCR1B=0x00;
    TCNT1H=0x00;
    TCNT1L=0x00;
    ICR1H=0x00;
    ICR1L=0x00;
    OCR1AH=0x00;
    OCR1AL=0x00;
    OCR1BH=0x00;
    OCR1BL=0x00;

    // Timer/Counter 2 initialization
    // Clock source: System Clock
    // Clock value: Timer 2 Stopped
    // Mode: Normal top=FFh
    // OC2 output: Disconnected
    ASSR=0x00;
    TCCR2=0x00;
    TCNT2=0x00;
    OCR2=0x00;

    // External Interrupt(s) initialization
    // INT0: On
    // INT0 Mode: Falling Edge
    // INT1: On
    // INT1 Mode: Falling Edge
    GICR|=0xC0;
    MCUCR=0x0A;
    GIFR=0xC0;

    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=0x00;

    // Analog Comparator initialization
    // Analog Comparator: Off
    // Analog Comparator Input Capture by Timer/Counter 1: Off
    ACSR=0x80;
    SFIOR=0x00;

    // Global enable interrupts
    #asm("sei")

    while (1)
    {
    PORTB++;
    if (PORTB>9) PORTB=0;
    delay_ms (70) ;
    };
    }
    em định cho con led 7 đoạn sáng từ 0 tới 9 (delay là 70ms)
    khi ấn button 0 thì led 7 sáng ở 2 (delay là 70ms)
    khi ấn button 1 thì led 7 sáng ở 3 (delay là 70ms)
    (em chỉ thử nghiệm với nhiệm vụ của mạch như thế thui )
    kết quả là led chạy ngon từ 0 tới 9 nhưng khi ấn button thì ko có gì xảy ra cả
    các cao thủ xem hộ em xem em cái code của em có j sai
    em cảm ơn rất rất rất rất nhiều
    Attached Files

  • #2
    - Nút này khi nhấn có nối đất không? có gắn điện trở ngoài kéo lên Vcc không? vì chương trình yêu cầu ngắt cạnh xuống mà chân các chân INT0;1 lại không có điện trở treo bên trong.
    Sửa hàng code này có thể fix được lỗi: PORTD = 00|(1<<2)|(1<<3)
    Đẹp từng kilomét

    Comment


    • #3
      thanks anh kilodeth nhé, em sửa xong rùi,

      nhưng có 2 câu lệnh này trong Interrupt em không hiểu rõ lắm , các cao thủ giải thích giùm em với:

      MCUCR=0x0A; // Câu này thì em hiểu rùi

      GICR|=0xC0; //?
      GIFR=0xC0; //?


      em cảm ơn rất nhiều

      Comment


      • #4
        GICR chứa hai bit cho phép ngắt ngoài INT1, và INT0 (bit 7,6) đồng thời hai bit IVSEL và IVCE bit 1,0. Mục đích chương trình là set hai bit INT1 và INT0, bỏ qua IVSEL và IVCE - hơi lằng nhằng vì dính tới bootloader các thứ, bạn đọc datasheet sẽ rõ, vậy nên dùng
        GICR|=0xC0
        thay vì
        GICR=0xC0
        là hợp lý

        GIFR chứa hai cờ ngắt INTF1,0 bit 7,6. AVR cho phép xóa cờ ngắt bằng cách set bit 1 lên cờ ngắt, vậy lệnh
        GIFR=0xC0
        dùng để xóa cờ ngắt tránh việc chạy ISR không mong muốn.
        Đẹp từng kilomét

        Comment


        • #5
          @Nobita87:
          Ặc, thuật toán quét led của bạn đơn giản thế???
          Thế này mà chạy được ư???
          Deg->Binary
          0-> 00000000
          1-> 00000001
          2-> 00000010
          ...............
          9-> 00001001

          vậy mà bạn muốn nó sáng số 0 thì đưa cho PORTB giá trị 0, muốn sáng giá trị 1 lại đưa cho PORTB giá trị 1(mối thanh của led 7 đoạn ứng với 1 bit) vậy bạn nối phần cứng kiểu gì để nó hiển thị được vậy??? Làm sao để chương trình của bạn chạy được từ 0->9??? Chỉ cho mình với, kiểu này mình chưa thấy bao giờ..........

          Comment


          • #6
            @Kilodeth:
            GICR chứa hai bit cho phép ngắt ngoài INT1, và INT0 (bit 7,6) đồng thời hai bit IVSEL và IVCE bit 1,0. Mục đích chương trình là set hai bit INT1 và INT0, bỏ qua IVSEL và IVCE - hơi lằng nhằng vì dính tới bootloader các thứ, bạn đọc datasheet sẽ rõ, vậy nên dùng
            Trích:
            GICR|=0xC0
            thay vì
            Trích:
            GICR=0xC0
            là hợp lý

            GIFR chứa hai cờ ngắt INTF1,0 bit 7,6. AVR cho phép xóa cờ ngắt bằng cách set bit 1 lên cờ ngắt, vậy lệnh
            Trích:
            GIFR=0xC0
            dùng để xóa cờ ngắt tránh việc chạy ISR không mong muốn.
            Việc gì mà phải phức tạp nó lên thế??? CodeVision đã fig hết cho rồi, chỉ việc chọn loại ngắt, chọn sườn hoặc mức gây ra ngắt, tuỳ theo phần cứng nối phím bấm vào chân ngắt mà fig theo kiểu pull up or để tristate là được, những phần kia không cần bận tâm. Tôi đã làm rồi, ngắt ngon lành cành đào
            Chúc vui

            Comment


            • #7
              Nguyên văn bởi sun_rise Xem bài viết
              @Nobita87:
              Ặc, thuật toán quét led của bạn đơn giản thế???
              Thế này mà chạy được ư???
              Deg->Binary
              0-> 00000000
              1-> 00000001
              2-> 00000010
              ...............
              9-> 00001001

              vậy mà bạn muốn nó sáng số 0 thì đưa cho PORTB giá trị 0, muốn sáng giá trị 1 lại đưa cho PORTB giá trị 1(mối thanh của led 7 đoạn ứng với 1 bit) vậy bạn nối phần cứng kiểu gì để nó hiển thị được vậy??? Làm sao để chương trình của bạn chạy được từ 0->9??? Chỉ cho mình với, kiểu này mình chưa thấy bao giờ..........
              Cái này chắc là bác ấy thừa giải mã 7447!

              Comment


              • #8
                Việc gì mà phải phức tạp nó lên thế??? CodeVision đã fig hết cho rồi, chỉ việc chọn loại ngắt, chọn sườn hoặc mức gây ra ngắt, tuỳ theo phần cứng nối phím bấm vào chân ngắt mà fig theo kiểu pull up or để tristate là được, những phần kia không cần bận tâm. Tôi đã làm rồi, ngắt ngon lành cành đào
                1. Bạn có quyền bảo vệ quan điểm của mình, nhưng cũng nên hỏi xem PNlab họ làm mạch nạp với bao nhiêu phần trăm code là mã tự sinh. Chức năng này thật tuyệt cho newbie, và họ vẫn luôn là newbie nếu không bận tâm, không bao giờ biết đặt câu hỏi tại sao CV tạo ra thế này mà không thế khác.

                2. Tôi không rỗi hơi đi làm chuyện lẩn thẩn, chỉ khi gặp vấn đề hay mà mình có thể giải quyết được ngay (hoặc tra tài liệu có thể hiểu được) thì tôi không ngại chia sẻ quan điểm. Bằng không thì có quyền giữ im lặng
                Đẹp từng kilomét

                Comment


                • #9
                  Nguyên văn bởi sun_rise Xem bài viết
                  @Nobita87:
                  Ặc, thuật toán quét led của bạn đơn giản thế???
                  Thế này mà chạy được ư???
                  Deg->Binary
                  0-> 00000000
                  1-> 00000001
                  2-> 00000010
                  ...............
                  9-> 00001001

                  vậy mà bạn muốn nó sáng số 0 thì đưa cho PORTB giá trị 0, muốn sáng giá trị 1 lại đưa cho PORTB giá trị 1(mối thanh của led 7 đoạn ứng với 1 bit) vậy bạn nối phần cứng kiểu gì để nó hiển thị được vậy??? Làm sao để chương trình của bạn chạy được từ 0->9??? Chỉ cho mình với, kiểu này mình chưa thấy bao giờ..........
                  sun_rise ơi, thật sự là bạn chưa thấy bao h ư, đáng nhẽ bạn nên xem qua file đính kèm trước khi đưa ra nhận xét vội vàng như thế chứ, theo tư duy thông thường thì mọi người sẽ nghĩ ngay là tớ dùng giải mã từ bcd sang 7 đoạn, thế nên mới từ 0 (atmega)-->0 (led 7 đoạn)
                  đoạn trên tớ chỉ bị 1 lỗi là PORTD=0x00 thui, thực ra là PORTD=0xFF.
                  Last edited by nobita87; 18-09-2008, 22:44.

                  Comment


                  • #10
                    Nguyên văn bởi Kilodeth Xem bài viết
                    1. Bạn có quyền bảo vệ quan điểm của mình, nhưng cũng nên hỏi xem PNlab họ làm mạch nạp với bao nhiêu phần trăm code là mã tự sinh. Chức năng này thật tuyệt cho newbie, và họ vẫn luôn là newbie nếu không bận tâm, không bao giờ biết đặt câu hỏi tại sao CV tạo ra thế này mà không thế khác.
                    thanks anh kilodeth nhé, một quan điểm rất đúng

                    Comment

                    Về tác giả

                    Collapse

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

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

                    Collapse

                    Đang tải...
                    X