Thông báo

Collapse
No announcement yet.

Ngắt timer0 sao ngộ quá

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

  • Ngắt timer0 sao ngộ quá

    Chào các cao thủ AVR, em chỉ là chicken về AVR hà, em cần mấy huynh cho biết thêm vấn đề của em, đơn giản nhưng hơi bị kì
    Em làm cái ngắt timer0 chỉ cho xuất led PORTC nhưng nếu để PORTE ở chế độ input thì ngắt ko thực thi(led ko cháy) nhưng khi set PORTE out thì led ở PORTC cháy theo ý đồ trong hàm ngát. Em dùng ATmega64, thach anh 16Mhz, CodeVision AVR
    code:
    #include <mega64.h>
    #include <delay.h>
    int count,i;

    // Timer 0 overflow interrupt service routine
    interrupt [TIM0_OVF] void timer0_ovf_isr(void)
    {
    // Place your code here
    //TCNT0=0x00;
    //TIFR = 0x00;
    count++;

    if(count==500)
    {
    i++;
    if (i == 3 )
    {
    PORTC = 0xaa ;
    delay_ms(500);
    PORTC = 0x55;
    i = 0;
    }
    else
    {
    PORTC=0xf0;
    delay_ms(500);
    PORTC=0x0f;
    }
    count = 0;

    }

    }

    // Declare your global variables here

    void main(void)
    {
    count = 0;
    i = 0;
    // Declare your local variables here

    // Input/Output Ports initialization
    // Port A 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
    PORTA=0x00;
    DDRA=0xff;

    // Port B 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
    PORTB=0x00;
    DDRB=0x00;

    // Port C 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
    PORTC=0xff;
    DDRC=0xff;

    // 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;

    // Port E 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
    PORTE=0x00;
    DDRE=0xff;

    // Port F 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
    PORTF=0x00;
    DDRF=0x00;

    // Port G initialization
    // Func4=In Func3=In Func2=In Func1=In Func0=In
    // State4=T State3=T State2=T State1=T State0=T
    PORTG=0x00;
    DDRG=0x00;

    // Timer/Counter 0 initialization
    // Clock source: System Clock
    // Clock value: 125.000 kHz
    // Mode: Normal top=FFh
    // OC0 output: Disconnected
    ASSR=0x00;
    TCCR0=0x05;
    TCNT0=0x00;
    OCR0=0x00;

    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: Timer 1 Stopped
    // Mode: Normal top=FFFFh
    // OC1A output: Discon.
    // OC1B output: Discon.
    // OC1C 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
    // Compare C Match Interrupt: Off
    TCCR1A=0x00;
    TCCR1B=0x00;
    TCNT1H=0x00;
    TCNT1L=0x00;
    ICR1H=0x00;
    ICR1L=0x00;
    OCR1AH=0x00;
    OCR1AL=0x00;
    OCR1BH=0x00;
    OCR1BL=0x00;
    OCR1CH=0x00;
    OCR1CL=0x00;

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

    // Timer/Counter 3 initialization
    // Clock source: System Clock
    // Clock value: Timer 3 Stopped
    // Mode: Normal top=FFFFh
    // Noise Canceler: Off
    // Input Capture on Falling Edge
    // OC3A output: Discon.
    // OC3B output: Discon.
    // OC3C output: Discon.
    // Timer 3 Overflow Interrupt: Off
    // Input Capture Interrupt: Off
    // Compare A Match Interrupt: Off
    // Compare B Match Interrupt: Off
    // Compare C Match Interrupt: Off
    TCCR3A=0x00;
    TCCR3B=0x00;
    TCNT3H=0x00;
    TCNT3L=0x00;
    ICR3H=0x00;
    ICR3L=0x00;
    OCR3AH=0x00;
    OCR3AL=0x00;
    OCR3BH=0x00;
    OCR3BL=0x00;
    OCR3CH=0x00;
    OCR3CL=0x00;

    // External Interrupt(s) initialization
    // INT0: Off
    // INT1: Off
    // INT2: Off
    // INT3: Off
    // INT4: Off
    // INT5: Off
    // INT6: Off
    // INT7: Off
    EICRA=0x00;
    EICRB=0x00;
    EIMSK=0x00;

    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=0x01;
    ETIMSK=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)
    {
    // Place your code here

    };
    }
    Thông cảm post code hơi dài. Mong các bác hồi đáp nhanh
    Tự động hóa hôm nay cho một thế hệ robot mai sau

  • #2
    Tớ chưa đọc kỹ nhưng biết đâu bạn mắc led sai cực
    Với lại dùng hàm delay trong hàm ngắt là ko được tốt lắm ^^

    Comment


    • #3
      Bác phải reset lại thanh ghi TCNT0=0x00
      Và như bác NMI
      Với lại dùng hàm delay trong hàm ngắt là ko được tốt lắm
      trong ngắt chỉ nên sử dụng một số ít dòng lệnh thôi. Còn nếu muốn tăng thời gian thì bác tăng tỉ lệ thời gian trong timer
      Bác nên sử dụng mô phỏng để xem nguyên nhân lỗi ở đâu để đễ xử lý.
      ----------------------
      Bể học là mênh mông!

      Comment


      • #4
        Mong thêm ý kiến

        Cảm ơn các bác đã reply, mạch của em ko có mắc sai cực gì hết, chuyện ngắt với xuất PORTE thì có liên quan gì đâu?Có ai có thêm cao kiến gì ko?
        Nếu sử dụng hàm delay trong ngắt sẽ ảnh hưởng thế nào đến chương trình chính?Có fai làm chương trình chạy chậm hơn ko hay bị đụng phải việc ngắt trong ngắt?Có hướng khắc phục ko các bác? Mong các bác cho ý kiến giùm
        Tự động hóa hôm nay cho một thế hệ robot mai sau

        Comment


        • #5
          Em thử cho bác rồi đây.
          Bác so sanh xem sao!
          Attached Files
          ----------------------
          Bể học là mênh mông!

          Comment


          • #6
            Em có file Proteus để bác xem!
            ----------------------
            Bể học là mênh mông!

            Comment


            • #7
              Tiếc quá, Proteus của mình ko đọc được, bác có kết quả gì nói cho mình biết với, hay chup một image post lên cho mình xem với
              Tự động hóa hôm nay cho một thế hệ robot mai sau

              Comment


              • #8
                Em thử thì chương trình chạy bình thường!
                Đây là một số hình chạy trong proteus,.
                Attached Files
                ----------------------
                Bể học là mênh mông!

                Comment


                • #9
                  Cảm ơn vì sự nhiệt tình của bạn, chắc tại mạch của mình có vấn đề. Bác trả lời giúp việc dùng hàm delay trong ngắt có vấn đề gì?Có hướng giải quyết ko?
                  Thanks
                  Tự động hóa hôm nay cho một thế hệ robot mai sau

                  Comment


                  • #10
                    Mình đã tìm được nguyên nhân của việc liên quan tới PORTE và ngắt rùi. Tại con VDK bị xìtin vì mình làm cho nó nóng quá trời, đem mạch thay con khác chạy đúng ý đồ. Cứ tưởng VDK có nội tình gì khó lí giải lắm....hic.
                    Tự động hóa hôm nay cho một thế hệ robot mai sau

                    Comment


                    • #11
                      Nguyên văn bởi nhaduy99 Xem bài viết
                      Cảm ơn vì sự nhiệt tình của bạn, chắc tại mạch của mình có vấn đề. Bác trả lời giúp việc dùng hàm delay trong ngắt có vấn đề gì?Có hướng giải quyết ko?
                      Thanks
                      Với CVAVR, mình thấy nó o ảnh hưởng gì. Giả sử đang gọi hàm delay mà xảy ra ngắt, hệ thống sẽ lưu tất cả các thghi đang dùng (có cả thghi dùng để trì hoãn); nếu tiếp tục gọi hàm delay lần nữa thì nó sẽ nạp giá trị mới cho các thghi này, ch.trình vẫn chạy b.thường, hết delay() thì trở về ngắt, hết ngắt sẽ lấy lại giá trị thghi rồi lại trở về delay()
                      Với Keil C dùng cho 8051, hình như có khác, ta phải khai báo hàm delay() này là reentrant thì phải!?
                      !e

                      Comment


                      • #12
                        việc dùng hàm delay trong ngắt có vấn đề gì?Có hướng giải quyết ko?
                        Về chương trình thi không có vấn đề gì! Nhưng sẽ tốn tài nguyên của uC.

                        Xảy ra ngắt thì thanh ghi Timer/Counter tràn, và khi ta thực hiện các lệnh trong hàm ngắt thì thanh ghi Timer/Counter tiếp tục đếm, nếu trong ngắt ta sử dụng hàm delay đủ lớn để thanh ghi Timer/Counter tràn tiếp và khi thoát khỏi ngắt sẽ lại tiếp tục thực hiện ngay vòng ngắt tiếp theo, như vậy chương trình sẽ luôn nhảy vảo ngắt -> không thể thực hiện công việc khác.

                        Ta có thể sử dụng tỉ lệ chia clock trong timer để thay thế cho hàm delay.
                        ----------------------
                        Bể học là mênh mông!

                        Comment


                        • #13
                          Bác hai_abc nói đến việc áp dụng "tỉ lệ chia clock trong timer" để tránh dùng hàm delay. Vậy bác có thể nói cụ thể hơn được không?Hay là cho ví dụ bằng code cũng được.Em còn mơ hồ lắm
                          thanks
                          Tự động hóa hôm nay cho một thế hệ robot mai sau

                          Comment


                          • #14
                            Xin phép tiếp lời hai_abc:
                            Timer có đầu vào là các xung đếm có tần số khác nhau. User có thể lựa chọn được 1 trong số các tần số đó bằng cách ghi giá trị thích hợp vào thanh ghi điều khiển TCCR khi khởi tạo cấu hình cho timer. Bạn có thể tham khảo thêm phần mô tả chi tiết thanh ghi TCCR. Khi xung đếm vào tần số khác nhau thì thời gian tràn tương ứng của timer cũng khác nhau. Bạn chọn tần số bao nhiêu là tùy thuộc vào ứng dụng của bạn. "Tỉ lệ chia clock trong timer" mà hai_abc nói là chắc là ý này.

                            Thân mến,
                            blakcmoon.

                            Comment


                            • #15
                              Vd: Khai báo Timer 0

                              // Timer/Counter 0 initialization
                              // Clock source: System Clock
                              // Clock value: 10.800 kHz
                              // Mode: Normal top=FFh
                              // OC0 output: Disconnected
                              ASSR=0x00;
                              TCCR0=0x07;
                              TCNT0=0x94; //10ms ngat 1 lan - TA 11.0592M
                              OCR0=0x00;

                              Xảy ra ngắt Timer 0 sau mỗi 10ms

                              unsigned int Count;

                              // Timer 0 overflow interrupt service routine
                              interrupt [TIM0_OVF] void timer0_ovf_isr(void)
                              {
                              // Reinitialize Timer 0 value
                              TCNT0=0x94;
                              // Place your code here
                              Count++;
                              }

                              Ta sử dụng biến Count để có thể thay được hàm Delay: Count = 50 ->Time = 500ms -> các dòng lệnh khác sẽ thực hiện theo biến Count và bên ngoài hàm ngắt
                              ----------------------
                              Bể học là mênh mông!

                              Comment

                              Về tác giả

                              Collapse

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

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

                              Collapse

                              Đang tải...
                              X