Thông báo

Collapse
No announcement yet.

input capture trong AVR

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

  • #31
    vài dòng góp ý về cái timer1:

    để đo độ rộng xung thì mình dùng chế độ input capture (ở đây là xung vuông).
    khi vào đầu chương trình thì mình set xung clock cho T1, cần chú ý đến tần số này, vì T1 chạy được 16 bit và độ rộng xung lớn nhất mà nó đo được là 2^16*Fck.
    giả sử bạn chọn xung clock là 1Mhz thì độ rộng xung tối đa mà nó đo được là 65 535us.
    cho nó chạy ở mode nomal 16 bit.

    khởi tạo cho phép ngắt ICP, tác động cạnh lên.
    khi có ngắt xảy ra: xóa TCNT1,cho T1 chạy, đổi cạnh tác động cho ICP. (cạnh xuống) thoát khỏi ngắt.

    đến ngắt tiếp theo xóa TCNT1,cho T1 chạy, đổi cạnh tác động cho ICP (cạnh lên), đọc ICR1 (đây là thời gian xung ở mức cao),thoát khỏi ngắt.

    đến ngắt tiếp theo: đọc ICR1 (đây là thời gian xung ở mức thấp) ...

    đây là cách để đo độ rộng của xung cần capture, thường được sử dụng để capture tín hiệu hồng ngoại của các remote.

    còn khi muốn đo tần số hay chu kì của xung thì mình sẽ sử dụng chế độ counter, nghĩa là cho T1 chạy bởi nguồn xung ngoài đưa vào chân T1, chứ ko phải chân ICP. dùng một timer khác để định thời gian đếm.
    giả sử dùng timer 0 và cho tràn trong 100ms trước khi cho T0 chạy thì mình xỏa TCNT1, và thiết lập các thông số cho nó chạy xung ngoải ở chân T1,
    khi tràn ngắt T0 thì mình đọc về TCNT1, đây là số xung đếm được trong 100ms, từ đó tính ra tần số hay chu kì..
    cần chú ý là tùy vào tấn số của xung cần đếm mà mình sẽ set thời gian tràn của T0 cho thích hợp. khi xung cần đếm có tần số lớn thì set thời gian tràn T0 nhỏ và ngược lại để bảo đảm T1 ko bị tràn và sai số đo là nhỏ.

    một số chú ý.
    chế độ capture chỉ nên sử dụng khi cần biết chính xác độ rộng xung. như là khi capture tín hiệu hồng ngoại, không nên sử dụng để đo tần số hay chu kì xung.
    khi muốn đo tần số hay chu kì thì sử dụng chế độ counter với nguồn xung từ T1.

    tần số xung lớn nhất mà AVR nhận được là Fosc/2. cần chú ý điều này để tránh bị lỗi trong quá trình thiết kế và viết phần mềm.

    Comment


    • #32
      Nguyên văn bởi dt_love Xem bài viết
      vài dòng góp ý về cái timer1:

      để đo độ rộng xung thì mình dùng chế độ input capture (ở đây là xung vuông).
      khi vào đầu chương trình thì mình set xung clock cho T1, cần chú ý đến tần số này, vì T1 chạy được 16 bit và độ rộng xung lớn nhất mà nó đo được là 2^16*Fck.
      giả sử bạn chọn xung clock là 1Mhz thì độ rộng xung tối đa mà nó đo được là 65 535us.
      cho nó chạy ở mode nomal 16 bit.

      khởi tạo cho phép ngắt ICP, tác động cạnh lên.
      khi có ngắt xảy ra: xóa TCNT1,cho T1 chạy, đổi cạnh tác động cho ICP. (cạnh xuống) thoát khỏi ngắt.

      đến ngắt tiếp theo xóa TCNT1,cho T1 chạy, đổi cạnh tác động cho ICP (cạnh lên), đọc ICR1 (đây là thời gian xung ở mức cao),thoát khỏi ngắt.

      đến ngắt tiếp theo: đọc ICR1 (đây là thời gian xung ở mức thấp) ...

      đây là cách để đo độ rộng của xung cần capture, thường được sử dụng để capture tín hiệu hồng ngoại của các remote.

      còn khi muốn đo tần số hay chu kì của xung thì mình sẽ sử dụng chế độ counter, nghĩa là cho T1 chạy bởi nguồn xung ngoài đưa vào chân T1, chứ ko phải chân ICP. dùng một timer khác để định thời gian đếm.
      giả sử dùng timer 0 và cho tràn trong 100ms trước khi cho T0 chạy thì mình xỏa TCNT1, và thiết lập các thông số cho nó chạy xung ngoải ở chân T1,
      khi tràn ngắt T0 thì mình đọc về TCNT1, đây là số xung đếm được trong 100ms, từ đó tính ra tần số hay chu kì..
      cần chú ý là tùy vào tấn số của xung cần đếm mà mình sẽ set thời gian tràn của T0 cho thích hợp. khi xung cần đếm có tần số lớn thì set thời gian tràn T0 nhỏ và ngược lại để bảo đảm T1 ko bị tràn và sai số đo là nhỏ.

      một số chú ý.
      chế độ capture chỉ nên sử dụng khi cần biết chính xác độ rộng xung. như là khi capture tín hiệu hồng ngoại, không nên sử dụng để đo tần số hay chu kì xung.
      khi muốn đo tần số hay chu kì thì sử dụng chế độ counter với nguồn xung từ T1.

      tần số xung lớn nhất mà AVR nhận được là Fosc/2. cần chú ý điều này để tránh bị lỗi trong quá trình thiết kế và viết phần mềm.
      mình đọc thì cũng thấy hiểu hiểu một chút, nhưng mà nó vẫn cứ mờ mờ thế nào ấy,
      để cho trực quan hơn, bác nào có đoạn code post lên cho anh em đọc dễ hiể hơn ko?
      rất cảm ơn
      ĐỪNG KHÓC CHO NHỮNG GÌ ĐÃ QUA, MÀ HÃY CƯỜI CHO NHỮNG ĐIỀU SẮP TỚI!

      Comment


      • #33
        Nguyên văn bởi dt_love Xem bài viết
        vài dòng góp ý về cái timer1:

        để đo độ rộng xung thì mình dùng chế độ input capture (ở đây là xung vuông).
        khi vào đầu chương trình thì mình set xung clock cho T1, cần chú ý đến tần số này, vì T1 chạy được 16 bit và độ rộng xung lớn nhất mà nó đo được là 2^16*Fck.
        giả sử bạn chọn xung clock là 1Mhz thì độ rộng xung tối đa mà nó đo được là 65 535us.
        cho nó chạy ở mode nomal 16 bit.

        khởi tạo cho phép ngắt ICP, tác động cạnh lên.
        khi có ngắt xảy ra: xóa TCNT1,cho T1 chạy, đổi cạnh tác động cho ICP. (cạnh xuống) thoát khỏi ngắt.

        đến ngắt tiếp theo xóa TCNT1,cho T1 chạy, đổi cạnh tác động cho ICP (cạnh lên), đọc ICR1 (đây là thời gian xung ở mức cao),thoát khỏi ngắt.

        đến ngắt tiếp theo: đọc ICR1 (đây là thời gian xung ở mức thấp) ...

        đây là cách để đo độ rộng của xung cần capture, thường được sử dụng để capture tín hiệu hồng ngoại của các remote.

        còn khi muốn đo tần số hay chu kì của xung thì mình sẽ sử dụng chế độ counter, nghĩa là cho T1 chạy bởi nguồn xung ngoài đưa vào chân T1, chứ ko phải chân ICP. dùng một timer khác để định thời gian đếm.
        giả sử dùng timer 0 và cho tràn trong 100ms trước khi cho T0 chạy thì mình xỏa TCNT1, và thiết lập các thông số cho nó chạy xung ngoải ở chân T1,
        khi tràn ngắt T0 thì mình đọc về TCNT1, đây là số xung đếm được trong 100ms, từ đó tính ra tần số hay chu kì..
        cần chú ý là tùy vào tấn số của xung cần đếm mà mình sẽ set thời gian tràn của T0 cho thích hợp. khi xung cần đếm có tần số lớn thì set thời gian tràn T0 nhỏ và ngược lại để bảo đảm T1 ko bị tràn và sai số đo là nhỏ.

        một số chú ý.
        chế độ capture chỉ nên sử dụng khi cần biết chính xác độ rộng xung. như là khi capture tín hiệu hồng ngoại, không nên sử dụng để đo tần số hay chu kì xung.
        khi muốn đo tần số hay chu kì thì sử dụng chế độ counter với nguồn xung từ T1.

        tần số xung lớn nhất mà AVR nhận được là Fosc/2. cần chú ý điều này để tránh bị lỗi trong quá trình thiết kế và viết phần mềm.
        Dùng chế độ inputcapture như trên vẫn có thể đo được các xung có độ rộng lớn hơn chứ nhỉ? Các chủ đề trước hình như có nói về cái này rồi, sử dụng thêm một biến đếm trong sự kiện tràn timer để lưu giữ giá trị thời gian...

        Comment


        • #34
          Nguyên văn bởi quocdat_dtvt Xem bài viết
          mình đọc thì cũng thấy hiểu hiểu một chút, nhưng mà nó vẫn cứ mờ mờ thế nào ấy,
          để cho trực quan hơn, bác nào có đoạn code post lên cho anh em đọc dễ hiể hơn ko?
          rất cảm ơn
          bạn muốn code mẫu về capture hay là counter? mình sẽ viết và post lên

          Comment


          • #35
            Nguyên văn bởi mrcuongcon Xem bài viết
            để đo độ rộng xung thì mình dùng chế độ input capture (ở đây là xung vuông).
            khi vào đầu chương trình thì mình set xung clock cho T1, cần chú ý đến tần số này, vì T1 chạy được 16 bit và độ rộng xung lớn nhất mà nó đo được là 2^16*Fck.
            giả sử bạn chọn xung clock là 1Mhz thì độ rộng xung tối đa mà nó đo được là 65 535us.
            cho nó chạy ở mode nomal 16 bit.
            Dùng chế độ inputcapture như trên vẫn có thể đo được các xung có độ rộng lớn hơn chứ nhỉ? Các chủ đề trước hình như có nói về cái này rồi, sử dụng thêm một biến đếm trong sự kiện tràn timer để lưu giữ giá trị thời gian...
            mong bạn đọc kĩ bài của mình rồi phát biểu ý kiến nhá. ở đây mình đã nói rõ... và bạn có thể đọc lại phần mình bôi nổi ở trên. và mình chỉ đang nói đến việc dùng phần cứng để capture, chưa dùng đến biến phần mềm để mở rộng.

            thân!

            Comment


            • #36
              /************************************************** ***
              This program was produced by the
              CodeWizardAVR V2.03.4 Standard
              Automatic Program Generator
              © Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.
              http://www.hpinfotech.com

              Project :
              Version :
              Date : 9/8/2009
              Author :
              Company :
              Comments:


              Chip type : ATmega8
              Program type : Application
              Clock frequency : 1.000000 MHz
              Memory model : Small
              External RAM size : 0
              Data Stack size : 256
              ************************************************** ***/

              #include <mega8.h>

              // Alphanumeric LCD Module functions
              #asm
              .equ __lcd_port=0x12 ;PORTD
              #endasm
              #include <lcd.h>
              #include <delay.h>
              #include <stdio.h>
              #define ICP PINB.0
              int ov_counter;
              int rising;
              int falling;
              int counts;
              char lcd_buffer[33];
              unsigned int data0;
              // Timer 1 overflow interrupt service routine
              interrupt [TIM1_OVF] void timer1_ovf_isr(void)
              {
              // Place your code here
              ov_counter++;
              }

              // Timer 1 input capture interrupt service routine
              interrupt [TIM1_CAPT] void timer1_capt_isr(void)
              {
              // Place your code here
              //save start time
              if (ICP) //if high level

              {
              rising=ICR1;

              //set to trigger on falling edge

              TCCR1B=TCCR1B&0xBF;

              //reset overflow counter

              ov_counter=0;

              }

              else

              {

              //save falling time

              falling=ICR1;

              //rising edge triggers next

              TCCR1B=TCCR1B|0x40;

              counts=falling-rising+ov_counter+52;

              /*you can convert coutns to seconds and send to LCD*/

              }
              }

              // Declare your global variables here

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

              // Input/Output Ports initialization
              // 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
              // 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: On
              // Input Capture Interrupt: On
              // 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: Off
              // INT1: Off
              MCUCR=0x00;

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

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

              // LCD module initialization
              lcd_init(16);

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

              while (1)
              {
              // Place your code here
              data0=counts;
              sprintf(lcd_buffer,"Gia tri la: %d",data0);
              lcd_gotoxy(0,0);
              lcd_puts(lcd_buffer);
              delay_ms(5);
              lcd_clear();

              };
              }
              các bác xem hộ mình các code này với. viết bằng codevision, mình viết theo mẫu trên mạng, nhung mình in ra cái biến counts ra LCD thì nó cứ bằng ===0
              thế mới điên chứ.

              TO: dt_love: thank bác , bác có lòng thì cứ cho em cả 2 cũng chả sao, mà nếu bận thì cứ cho em cái code counter frequency sử dụng timer và counter.
              em cứ nhìn code mới hiểu được , chứ đọc mãi nó cứ u u cạc cạc, chán
              thank mọi người lần nữa nhé,
              ĐỪNG KHÓC CHO NHỮNG GÌ ĐÃ QUA, MÀ HÃY CƯỜI CHO NHỮNG ĐIỀU SẮP TỚI!

              Comment


              • #37
                Nguyên văn bởi quocdat_dtvt Xem bài viết
                các bác xem hộ mình các code này với. viết bằng codevision, mình viết theo mẫu trên mạng, nhung mình in ra cái biến counts ra LCD thì nó cứ bằng ===0
                thế mới điên chứ.

                TO: dt_love: thank bác , bác có lòng thì cứ cho em cả 2 cũng chả sao, mà nếu bận thì cứ cho em cái code counter frequency sử dụng timer và counter.
                em cứ nhìn code mới hiểu được , chứ đọc mãi nó cứ u u cạc cạc, chán
                thank mọi người lần nữa nhé,
                chương trình này, counter 1 đang stop, nên dù giá trị ICR luôn là 0 nếu có ngắt capture xảy ra.
                như vậy: nếu như nó nhảy được vào ngắt input capture thì biến counter sẽ là 52 của dòng lệnh này.
                Code:
                counts=falling-rising+ov_counter+52;
                còn nếu nó ko nhảy vào ngắt được thì biến counter sẽ có giá trị 0. nếu như giá trị trên LCD của bạn là 0 thì bạn nên kiểm tra chỗ này, (lí do mà ngắt capture chưa xảy ra, có thể do phần cứng hoặc... chưa có tín hiệu cho chân ICP).

                sau khi fix xong chỗ này thì bạn tìm vị trí thích hợp để cho phép T1 chạy. lúc đó nó mới capture được tín hiệu vào.
                mà ko biết dòng lệnh ở trên bạn dùng để làm j, nếu là để capture tín hiệu thì giá trị capture sẽ ko chính xác đâu.

                thân!
                giờ mình đang bận nên tranh thủ post cho bạn fix lỗi thôi. có thời gian thì mình sẽ viết code cho bạn.

                Comment


                • #38
                  cảm ơn bác, dòng lệnh đó mình cộng thêm 52 vào nữa cho vui đó mà, để test xem lcd có làm việc kô vì mình sợ phần in ra lcd có vấn đề,

                  đề mình xem laị
                  thank đã quan tâm
                  ĐỪNG KHÓC CHO NHỮNG GÌ ĐÃ QUA, MÀ HÃY CƯỜI CHO NHỮNG ĐIỀU SẮP TỚI!

                  Comment


                  • #39
                    các bác xem jup E cái này cái nó toàn báo lỗi không định nghĩa đc ký hiệu ICR1 thoi
                    /************************************************** **********************
                    This program was produced by theCodeWizardAVR V1.24.8d
                    ProfessionalAutomatic Program Generator ©
                    Copyright 1998-2006 Pavel Haiduc, HP InfoTech s.r.l.
                    HP InfoTech, Development Tools for Microcontrollers, C Compilers, In-System Programmers
                    Project : Do an tot nghiep
                    Version :
                    Date : 5/21/2009
                    Author : Nguyen Thi Ha Thu va Do Viet Lon
                    Company : Dai Hoc Bach Khoa Ha Noi
                    Comments:

                    Chip type : ATmega16
                    Program type : Application
                    Clock frequency : 16.000000MHz
                    Memory model : Small
                    External SRAM size :0
                    Data Stack size : 256
                    ************************************************** **********************///
                    /*Khai bao thu vien su dung chip ATmega16*/
                    #include <mega16.h>
                    /************************************************** **********************
                    Khai bao cac bien su dung trong chuong trinhy: bien tuong duong voi goc mo alpha j:
                    chi so cua mangi: bien dem so chu kya: dung de luu gia tri thanh ghi TCNT1 khi goc mo lon
                    ************************************************** **********************/
                    unsigned int y=0x74,a,i,j=1000;
                    /************************************************** **********************
                    bang tra cac gia tri ung voi cac goc mo, thoi gian khoi dong la 20s
                    ************************************************** **********************/
                    flash unsigned char bang[]={
                    0x1A, 0x1A, 0x1A, 0x1A,0x1A, 0x1A, 0x1A, 0x1A,0x1A, 0x1A, 0x1A, 0x1A,0x1A,0x1A, 0x1A,
                    0x1B, 0x1B,0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B,0x1B, 0x1B,
                    0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,0x1C, 0x1C,
                    0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D,0x1D, 0x1D,
                    0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
                    0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
                    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
                    0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
                    0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
                    0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
                    0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
                    0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
                    0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
                    0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
                    0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
                    0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
                    0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B,
                    0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
                    0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
                    0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
                    0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F,
                    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
                    0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
                    0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
                    0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
                    0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
                    0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
                    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
                    0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
                    0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
                    0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
                    0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A,
                    0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B,
                    0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C,
                    0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D,
                    0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E,
                    0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
                    0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
                    0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
                    0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
                    0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43,
                    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
                    0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
                    0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46,
                    0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
                    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
                    0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,
                    0x4A, 0x4A, 0x4A, 0x4A, 0x4A, 0x4A, 0x4A, 0x4A, 0x4A,
                    0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
                    0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C,
                    0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D,
                    0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E,
                    0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F,
                    0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
                    0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
                    0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52,
                    0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53,
                    0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54,
                    0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
                    0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56,
                    0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57,
                    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
                    0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59,
                    0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
                    0x5B, 0x5B, 0x5B, 0x5B, 0x5B, 0x5B, 0x5B, 0x5B, 0x5B,
                    0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
                    0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D,
                    0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E,
                    0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F,
                    0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
                    0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
                    0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62,
                    0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
                    0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
                    0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65,
                    0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
                    0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67,
                    0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68,
                    0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
                    0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A,
                    0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,
                    0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C,
                    0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D,
                    0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E,
                    0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F,
                    0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70,
                    0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71,
                    0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72,
                    0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73,
                    0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74};
                    /************************************************** **********************
                    CHUONG TRINH PHUC VU NGAT INPUTCAPTURE (TIMER1)
                    ************************************************** **********************/
                    interrupt [TIM1_CAPT] void timer1_capt_isr(void)
                    {
                    i++;
                    if (j==0)
                    {
                    PORTD.1=0x01;
                    y=0x1A;
                    }
                    else
                    {
                    j=j-1;
                    y=bang[j];
                    }
                    }
                    /************************************************** **********************
                    CHUONG TRINH PHUC VU MGAT SO SANH (TIMER0)(xay ra khi TCNT0 = OCR0)
                    ************************************************** **********************/
                    interrupt [TIM0_COMP] void timer0_comp_isr(void)
                    {
                    PORTD.0^=1;
                    }
                    /************************************************** **********************
                    CHUONG TRINH CHINH
                    ************************************************** **********************/
                    void main(void)
                    {
                    /************************************************** **********************
                    DAT CHE DO HOAT DONG CHO CAC CONG VAO - RAPORTA:
                    Dat la cac dau vao (khong su dung)PORTB:
                    Dat la cac dau vao (khong su dung)PORTC:
                    Dat la cac dau ra (xuat xung dieu khien)PORTD: - PORTD.6:
                    dat lam dau vao (nhan tin hieu dong pha)- PORTD.0:
                    dat lam dau ra (phat tin hieu xung chum)- PORTD.1:
                    dat lam dau ra (phat tin hieu dieu khien ro le)
                    ************************************************** **********************/
                    PORTC=0x00;
                    DDRC=0xFF;
                    PORTD=0x00;
                    DDRD=0x03;
                    /************************************************** **********************
                    DAT CHE DO HOAT DONG CHO TIMER0
                    - che do hoat dong CTC top = OCR0
                    - xung nhip la xung nhip hoat dong cua chip
                    - prescaler = 1/1024- OCR0 = 0x02
                    ************************************************** **********************/
                    TCCR0=0x0D;
                    TCNT0=0x00;
                    OCR0=0x02;
                    /************************************************** *********************
                    DAT CHE DO HOAT DONG CHO TIMER1
                    - che do hoat dong normal top = 0xFFFF
                    - xung nhip la xung nhip hoat dong cua chip
                    - prescaler = 1/1024
                    - ngat input capture khi co suon len o chan ICP (PORTD.6)
                    ************************************************** **********************/
                    TCCR1A=0x00;
                    TCCR1B=0x45;
                    TCNT1H=0x00;
                    TCNT1L=0x00;
                    ICR1H=0x00;
                    ICR1L=0x00;
                    OCR1AH=0x00;
                    OCR1AL=0x00;
                    OCR1BH=0x00;
                    OCR1BL=0x00;
                    /************************************************** *********************
                    CHO PHEP XAY RA NGAT
                    ************************************************** **********************/
                    TIMSK=0x22;#asm("sei")
                    /************************************************** **********************
                    VONG LAP VO TANso sanh gia tri cua thanh ghi TCNT1 de phat xung ra PORTC
                    ************************************************** **********************/
                    while (1)
                    {
                    if (TCNT1==ICR1+y)
                    {
                    PORTB=0x09;
                    PORTC=0x09;
                    }
                    if (TCNT1==ICR1+y+0x34)
                    {
                    PORTB=0x21;
                    PORTC=0x21;
                    }
                    if (TCNT1==ICR1+y+0x68)
                    {
                    PORTB=0x24;
                    PORTC=0x24;
                    }
                    if (TCNT1==ICR1+y+0x9C)
                    {
                    PORTB=0x06;
                    a=TCNT1;
                    PORTC=0x06;
                    }
                    if (TCNT1==ICR1+y+D0)
                    {
                    PORTB=0x12;
                    PORTC=0x12;
                    }
                    if (TCNT1==ICR1+y+104)
                    {
                    PORTB=0x18;
                    PORTC=0x18;
                    }
                    if (i>=1)
                    {
                    if (TCNT1==a+0x34)
                    {
                    PORTB=0x12;
                    PORTC=0x12;
                    }
                    if (TCNT1==a+0x68)
                    {
                    PORTB=0x18;
                    PORTC=0x18;
                    }
                    if (TCNT1==ICR1+y)
                    {
                    PORTB=0x09;
                    PORTC=0x09;
                    }
                    if (TCNT1==ICR1+y+0x34)
                    {
                    PORTB=0x21;
                    PORTC=0x21;
                    }
                    if (TCNT1==ICR1+y+0x68)
                    {
                    PORTB=0x24;
                    PORTC=0x24;
                    }
                    if (TCNT1==ICR1+y+0x9C)
                    {
                    PORTB=0x06;
                    a=TCNT1;
                    PORTC=0x06;
                    }
                    if (TCNT1==ICR1+y+0xD0)
                    {
                    PORTB=0x12;
                    PORTC=0x12;
                    }
                    if (TCNT1==ICR1+y+0x104)
                    {
                    PORTB=0x18;
                    PORTC=0x18;
                    }
                    }
                    };
                    }
                    error: underfined symbol 'ICR1'
                    Vũ xuân Lợi
                    YM!:

                    Comment


                    • #40
                      Nguyên văn bởi nghaiha Xem bài viết
                      Có nhiều cách lắm bác ạ. Sau đây là 1 cách

                      unsigned int x; // khai báo x là số từ 0 đến 65535
                      x=(unsigned int)ICR1H <<8 + ICR1L; // chuyển ICR1H sang kiểu 16 bit, sau đó dịch sang trái 8 bit rồi cộng với ICR1L
                      //Cách này tương đương với: x=(unsigned int)ICR1H * 256 + ICR1L;
                      //Ta phải chuyển sang kiểu 16 bit (cái này gọi là type casting) nếu không kết quả của ICR1H * 256 sẽ vẫn là 1 số 8 bit

                      Theo cách làm của bác thì có 2 cái sai, 1 là phải nhân 256 chứ không phải là 100, 2 là thiếu type casting.
                      Hi bạn!
                      Mình hỏi đoạn này tí:
                      x= x=(unsigned int)ICR1H * 256 + ICR1L;
                      Ban đầu khi khởi tạo là thanh ghi ICR1H có giá trị là 0 đúng ko? mình *256 thì nó sẽ ra 0x0000 (16 bit) như vầy ah ???

                      Comment


                      • #41
                        Bác dt_love bảo chế độ ICP vào ngắt thì xóa TCNT1 đi xong cho T1 chạy sau đó đổi cạnh... thế thì bác dùng ngắt ngoài luôn chứ dùng ICP làm gì cho đau đầu ... đặc trưng của ICP là khi có ngắt xảy ra thì thanh ghi ICR1 sẽ bắt giá trị của thanh ghi đếm timer (TCNT1) ... vậy mà bác vào ngắt lại xóa đi giá trị của TCNT1 thì dùng luôn Ext interrupt có phải nhanh không chứ nhà sx họ cần gì phải chế ra ICP làm gì

                        Comment

                        Về tác giả

                        Collapse

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

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

                        Collapse

                        Đang tải...
                        X