Welcome & Happy Holidays!
Trang 1 của 4 123 ... CuốiCuối
Kết quả 1 đến 10 của 34

Chủ đề: bài 6 timer/counter 0

  1. #1
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    bài 6 timer/counter 0

    Do 2 hôm nay mình đang bị ho khù khụ nên làm video không hợp lý lắm mình xin phép trình bày bằng hình ảnh mong bà con thông cảm.

    - Timer là bộ định thời tức là xác định 1 khoảng thời gian nào đó, ứng dụng để đo độ rộng xung, hoặc là làm đồng hồ đếm thời gian, quét led 7seg, trong lập trình nâng cao ứng dụng rộng rãi hơn nhiều
    - counter là bộ đếm sự kiện ứng dụng để đếm sản phẩm trên 1 băng truyền, đếm xung của encorder....

    Atmega16 có 3 bộ timer/couter trong đó.
    - timer0 8 bit có hỗ trợ 1 kênh pwm giá trị tối đa là 255.
    - timer 16 bit có hỗ trợ 2 kênh pwm giá trị tối đa là 65535
    - timer2 8 bit hỗ trợ 1 kênh pwm giá trị tối đa là 255

    Phần này ta sẽ tìm hiểu về timer/counter 0 (sau này viết tắt là T/C0).
    T/C0 có thể đếm xung hệ thống ( lấy từ dao động nội hoặc ngoại) sau khi qua bộ chia tần, hoặc là xung bên ngoài lấy từ T0(PB0). Việc chọn bộ chia và tín hiệu để kích cụ thể bạn có thể xem bên dưới bằng cách cấu hình 3 bit cs00,cs01,cs02 của thanh ghi TCCR0.
    Các thanh ghi điều khiển T/C0 là
    - TCNT0 : là thanh ghi 8 bit chưa giá trị vận hành của T/C0. Thanh ghi này cho phép đọc và ghi đều được.
    - thanh ghi TCCR0 chính là thanh ghi điều khiển của T/C0 thanh ghi này


    [IMG]http://*************/attachments/13473/[/IMG]

    Sử dụng ở chế độ Timer và counter thì chỉ cần quan tâm đến 3 bit cuối CS00, CS01,CS02 các bit còn lại dùng ở chế độ pwm.



    [IMG]http://*************/attachments/13474/[/IMG]

    - TIMSK: thanh ghi mặt nạ ngắt T/C. trong đó khi set TOIE0=1 cho phép ngắt tràn T/0


    [IMG]http://*************/attachments/13477/[/IMG]

    - TIFR thanh ghi cờ nhớ cho tất cả bộ T/C


    [IMG]http://*************/attachments/13478/[/IMG]

    T/C0 hoạt động như sau: khi nhận được 1 xung thì TCNT0 tăng thêm 1 đơn vị. Cho đến khi TCNT0 đạt đến 255, nếu có thêm 1 tín hiệu kích nữa thì TCNT0 sẽ trở về 0 đồng thời bật bit TOV0(bit0 của TIFR) được set lên 1. Nếu cho phép ngắt tràn thì sẽ có 1 ngắt tràn xẩy ra, căn cứ vào tín hiệu kích ngắt và ngắt tràn ta có thể tạo ra 1 bộ định thời hoặc 1 bộ đếm sự kiện.

  2. #2
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Đầu tiên thử làm việc với chế độ counter


    [IMG]http://*************/attachments/13482/[/IMG]

    + thiết lập TCCR0 ở chế độ đếm sự kiện
    + đọc TCNT0 hiển thị lên lcd16x2


    [IMG]http://*************/attachments/13479/[/IMG]

    sau khi chọn chip và thạch anh bạn chọn timer 0 và chọn tín hiệu kích là falling edge (sườn xuống) hoặc là rising edge (sườn lên).
    và thiết lập lcd


    [IMG]http://*************/attachments/13480/[/IMG]

    giờ ta bắt đầu code như sau


    Mã:
    /*****************************************************
    This program was produced by the
    CodeWizardAVR V2.05.0 Professional
    Automatic Program Generator
    © Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
    http://www.hpinfotech.com
    
    Project :
    Version :
    Date    : 10/14/2013
    Author  : NeVaDa
    Company :
    Comments:
    
    
    Chip type              : ATmega16
    Program type            : Application
    AVR Core Clock frequency: 8.000000 MHz
    Memory model            : Small
    External RAM size      : 0
    Data Stack size        : 256
    *****************************************************/
    
    #include <mega16.h>
    #include <delay.h>
    
    
    // Alphanumeric LCD Module functions
    #include <alcd.h>
    
    // Declare your global variables here
    
    void main(void)
    {
    // 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=0x00;
    
    // 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=P
    PORTB=0x01;      // treo pullup
    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=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: T0 pin Falling Edge
    // Mode: Normal top=0xFF
    // OC0 output: Disconnected
    TCCR0=0x06;  // cs2=1,cs1=1,cs0=0
    TCNT0=0x00;
    OCR0=0x00;
    
    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: Timer1 Stopped
    // Mode: Normal top=0xFFFF
    // OC1A output: Discon.
    // OC1B output: Discon.
    // Noise Canceler: Off
    // Input Capture on Falling Edge
    // Timer1 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: Timer2 Stopped
    // Mode: Normal top=0xFF
    // OC2 output: Disconnected
    ASSR=0x00;
    TCCR2=0x00;
    TCNT2=0x00;
    OCR2=0x00;
    
    // External Interrupt(s) initialization
    // INT0: Off
    // INT1: Off
    // INT2: Off
    MCUCR=0x00;
    MCUCSR=0x00;
    
    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=0x00;
    
    // USART initialization
    // USART disabled
    UCSRB=0x00;
    
    // Analog Comparator initialization
    // Analog Comparator: Off
    // Analog Comparator Input Capture by Timer/Counter 1: Off
    ACSR=0x80;
    SFIOR=0x00;
    
    // ADC initialization
    // ADC disabled
    ADCSRA=0x00;
    
    // SPI initialization
    // SPI disabled
    SPCR=0x00;
    
    // TWI initialization
    // TWI disabled
    TWCR=0x00;
    
    // Alphanumeric LCD initialization
    // Connections specified in the
    // Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
    // RS - PORTC Bit 0
    // RD - PORTC Bit 1
    // EN - PORTC Bit 2
    // D4 - PORTC Bit 4
    // D5 - PORTC Bit 5
    // D6 - PORTC Bit 6
    // D7 - PORTC Bit 7
    // Characters/line: 16
    lcd_init(16);
    
    while (1)
          {  lcd_gotoxy(0,0);
          lcd_putsf("counter:");
          lcd_putchar(TCNT0/100+48);// hien thi hang tram tcnt0
          lcd_putchar((TCNT0%100)/10+48);  // hien thi hang chuc tcnt0
          lcd_putchar(TCNT0%10+48);    // hien thi hang don vi tcnt0
          // Place your code here
    
          }
    }
    sơ đồ mạch


    [IMG]http://*************/attachments/13486/[/IMG]

    đối với avr studio bạn sau khi add thư viện textlcd.h như bài trước mình code như sau


    Mã:
    #define F_CPU 8000000
    #include <util/delay.h>
    #include <avr/io.h>
    #include "textlcd.h"
    
    
    int main(void)
    {
    DDRC=0xFF;
    PORTB=0x01;// treo pull up portb.1
    TCCR0=0x06;// cs02=1,cs01=1;cs00=0 chon xung kich suon xuong tren T0
    lcd_init();
    while(1)
    {
    lcd_gotoxy(0,0);
    lcd_putsf("counter:",8);
    lcd_putc(TCNT0/100+48);// hien thi len lcd
    lcd_putc((TCNT0%100/10)+48);
    lcd_putc((TCNT0%10)+48);
    }
    }
    toàn bộ code và file mô phỏng download ở file đính kèm

  3. #3
    Ngày tham gia
    Feb 2016
    Bài viết
    0
    tiếp theo đến timer
    ví dụ đơn giản led nối với PORTD.0 cứ 1s thay đổi trạng thái 1 lần sử dụng timer.



    [IMG]http://*************/attachments/13491/[/IMG]

    - để giải quyết bài toàn này ta có thể dùng delay nhưng nhược điểm delay là trong khi delay cpu hoàn toàn không làm việc còn timer thì cpu vẫn làm việc khi timer đếm cụ thể bạn có thể xem hình dưới.


    [IMG]http://*************/attachments/13492/[/IMG]


    Giả sử mình dùng thạch anh 8MHZ. chu kỳ là 1/8MHZ= 0,125us
    vậy 1s cần có 1s/0,125us=8 triệu xung
    TCNT0 là thanh ghi 8 bit giá trị max là 255 cộng thêm 1 chu kỳ tràn từ 255 về 0 là 256. 8 triệu lớn hơn 256 rất nhiều vì vậy ta chọn bộ chia cao nhất 1024 lúc này ta cần 8000000/1024=7812.5 lấy tròn là 7813 xung
    Nếu mà khởi tạo TCNT0=4 thì cần có 7813/(256-4)=31 31 lần tràn
    bây giờ chúng ta code như sau
    - đầu tiên với codevison avr



    [IMG]http://*************/attachments/13494/[/IMG]

    ô clock soure chọn giao động lấy từ hệ thống
    clock value chọn 7.813khz là tần số sau khi đã qua bộ chia
    tích chọn overflow interrupt chọn ngắt tràn
    tại ô timer value gõ 04 tức là giá trị khởi tạo là của tcnt0 là 4
    Và chọn đầu ra cho portD.0

    - các bước thực hiện như sau
    + thiết lập thanh ghi TCCR0 ở bộ chia phù hợp
    + gán giá trị TCNT0 ở giá trị khởi tạo
    + set TIMSK=0x01 cho phép ngắt tràn timer 0
    + set biến i của SREG cho phép ngắt toàn cục


    Mã:
    /*****************************************************
    This program was produced by the
    CodeWizardAVR V2.05.0 Professional
    Automatic Program Generator
    © Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
    http://www.hpinfotech.com
    
    Project :
    Version :
    Date    : 10/14/2013
    Author  : NeVaDa
    Company :
    Comments:
    
    
    Chip type              : ATmega16
    Program type            : Application
    AVR Core Clock frequency: 8.000000 MHz
    Memory model            : Small
    External RAM size      : 0
    Data Stack size        : 256
    *****************************************************/
    
    #include <mega16.h>
    int i;
    // Timer 0 overflow interrupt service routine
    interrupt [TIM0_OVF] void timer0_ovf_isr(void)
    {
    // Reinitialize Timer 0 value
    TCNT0=0x04;
    i++; // moi lan ngat tran thi i tang len 1
    if(i==31){PORTD.0^=1;i=0;}    // khi dem den 31 thi dao trang thai PORTD,0 gán i=0 de bat dau lai
    // Place your code here
    
    }
    
    // Declare your global variables here
    
    void main(void)
    {
    // 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=0x00;
    
    // 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=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=0x01;    // dat dau ra
    
    // Timer/Counter 0 initialization
    // Clock source: System Clock
    // Clock value: 7.813 kHz
    // Mode: Normal top=0xFF
    // OC0 output: Disconnected
    TCCR0=0x05;
    TCNT0=0x04;
    OCR0=0x00;
    
    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: Timer1 Stopped
    // Mode: Normal top=0xFFFF
    // OC1A output: Discon.
    // OC1B output: Discon.
    // Noise Canceler: Off
    // Input Capture on Falling Edge
    // Timer1 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: Timer2 Stopped
    // Mode: Normal top=0xFF
    // OC2 output: Disconnected
    ASSR=0x00;
    TCCR2=0x00;
    TCNT2=0x00;
    OCR2=0x00;
    
    // External Interrupt(s) initialization
    // INT0: Off
    // INT1: Off
    // INT2: Off
    MCUCR=0x00;
    MCUCSR=0x00;
    
    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=0x01;        // cho phep ngat tran timer 0
    
    // USART initialization
    // USART disabled
    UCSRB=0x00;
    
    // Analog Comparator initialization
    // Analog Comparator: Off
    // Analog Comparator Input Capture by Timer/Counter 1: Off
    ACSR=0x80;
    SFIOR=0x00;
    
    // ADC initialization
    // ADC disabled
    ADCSRA=0x00;
    
    // SPI initialization
    // SPI disabled
    SPCR=0x00;
    
    // TWI initialization
    // TWI disabled
    TWCR=0x00;
    
    // Global enable interrupts
    #asm("sei")    // cho phep ngat toan cuc
    
    while (1)
          {
          // Place your code here
    
          }
    }
    Đối với avr studio ta code như sau


    Mã:
    #define F_CPU 8000000
    #include <util/delay.h>
    #include <avr/io.h>
    #include <avr/interrupt.h>
    int i;// bien dem so ngat tran
    int main(void)
    {
    DDRD=0x01; //D0 là dau ra
    TCCR0= (1<<CS02)|(1<<CS00);// chon bo chia 1024
    TCNT0=4;// khoi tao tcnt0=4
    TIMSK=0x01;// cho phep ngat tran timer 0
    sei(); // seti=1 cho phep ngat toan cuc
    while(1)
    {
    
    }
    }
    // trinh phuc vu ngat timer 0
    ISR(TIMER0_OVF_vect)
    {
    TCNT0=0x04;// gán tro lai 0x04 cho TCNT0
    i++;// moi lan tran i tang len 1
    if(i==31){PORTD^=1;i=0;}// dao trang thai D0 gán i=0
    
    }
    mạch mô phỏng và project có thể down ở file đính kèm
    bài tập luyên tập
    - bạn dùng timer để tạo 1 đồng hồ đếm thời gian của 1 trận đá bóng hiển thị trên LCD
    - như bài 4 mình dùng delay quét led 7seg bây giờ bạn dùng timer quét và so sánh sự khác biệt

  4. #4
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Bác nói cho em rõ hơn phần sei(); với cái i++ ở cuối được không ạ?
    Nếu không có i++ thì sảy ra trường hợp gì ạ? Thanks!

  5. #5
    Ngày tham gia
    Apr 2016
    Bài viết
    0
    sei(); là cho phép tất cả các ngắt hoạt động nếu như không có dòng này thì không có ngắt nào cho phép cả.
    i++; là mỗi lần ngắt tăng nên 1 khi đếm đến 31 thì tự động gán lại bằng 0. Nếu mà không i++ thì mỗi lần ngắt xảy ra D0 đổi trạng thái 1 lần thời gian đổi trạng thái là 1/31 giây.

  6. #6
    Ngày tham gia
    Jan 2016
    Bài viết
    0
    Cho em hỏi là tại sao là 31, với giá trị khác được không?

  7. #7
    Ngày tham gia
    Sep 2015
    Đang ở
    Hà Nội
    Bài viết
    0
    Trích dẫn Gửi bởi anndt_55
    Cho em hỏi là tại sao là 31, với giá trị khác được không?
    Giả sử mình dùng thạch anh 8MHZ. chu kỳ là 1/8MHZ= 0,125us
    vậy 1s cần có 1s/0,125us=8 triệu xung
    TCNT0 là thanh ghi 8 bit giá trị max là 255 cộng thêm 1 chu kỳ tràn từ 255 về 0 là 256. 8 triệu lớn hơn 256 rất nhiều vì vậy ta chọn bộ chia cao nhất 1024 lúc này ta cần 8000000/1024=7812.5 lấy tròn là 7813 xung
    Nếu mà khởi tạo TCNT0=4 thì cần có 7813/(256-4)=31 31 lần tràn

  8. #8
    Ngày tham gia
    Jan 2016
    Bài viết
    0
    OK. Thanks bác.

  9. #9
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    À anh Lành ơi, cho em hỏi cách chọn TCNT0 có phải là lấy thời gian đặt trước chia cho giá trị chia tần rùi lấy 256 trừ đi giá trị vừa rùi đúng không ạ?

  10. #10
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Đâu phải thế đâu chú, chú lấy tần số thạch anh chia cho bộ chia thì ra tần số xung, lấy nghịch đảo cái tần số xung này ra chu kỳ đếm tức là cứ sau thời gian đúng bằng chu kỳ này thì TCNT0 tăng nên 1 khi đến 255 đếm thêm 1 xung nữa thì bị reset về 0 nếu như có cho phép ngắt thì xẩy ra ngắt.
    Khi nhẩy về 0 thì chú có thể gán thẳng luôn TCNT0 bằng giá trị chú đặt thôi.
    tức là (256-giá trị đặt TCNT0)*(1/tần số thạch anh)*bộ chia= thời gian xẩy ra ngắt.

 

 
Trang 1 của 4 123 ... CuốiCuối

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •  
Múi giờ GMT +7. Bây giờ là 12:59 AM. Diễn đàn sử dụng vBulletin® Phiên bản 4.2.5.
Bản quyền của 2022 vBulletin Solutions, Inc. Tất cả quyền được bảo lưu.
Ban quản trị không chịu trách nhiệm về nội dung do thành viên đăng.