Thông báo

Collapse
No announcement yet.

tạo delay bằng timer0 pic16f887

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

  • tạo delay bằng timer0 pic16f887

    bác nào có thể hướng dẫn em cách tạo delay bằng timer0 với ạ
    em có code thử 1 đoạn code như sau
    Code:
    #include <htc.h>
    __CONFIG(FOSC_XT&WDTE_OFF&PWRTE_ON&MCLRE_OFF&CP_OFF&CPD_OFF&BOREN_OFF&IESO_OFF&FCMEN_OFF&LVP_OFF&DEBUG_OFF);
    __CONFIG(BOR4V_BOR40V&WRT_OFF);
    #ifndef _XTAL_FREQ
    	#define _XTAL_FREQ 4000000
    #endif
    unsigned char count1,count2;
    void main() {
    	TRISB=0;
    	ANSEL=ANSELH=0;
    	T0CS=0;
    	PSA=0;
    	RB0=1;
    	count1=count2=0;
    	while(1) {
    		TMR0=0;
    		T0IF=0;
    		while(!T0IF);
    		T0IF=0;
    		++count1;
    		if(count1==4) {
    			count1=0;
    			RB0=!RB0;
    		}
    	}
    }
    vậy xung tạo ra tại chân RB0 có T là bao nhiêu

  • #2
    Nguyên văn bởi kidteam Xem bài viết
    bác nào có thể hướng dẫn em cách tạo delay bằng timer0 với ạ
    em có code thử 1 đoạn code như sau
    Code:
    #include <htc.h>
    __CONFIG(FOSC_XT&WDTE_OFF&PWRTE_ON&MCLRE_OFF&CP_OFF&CPD_OFF&BOREN_OFF&IESO_OFF&FCMEN_OFF&LVP_OFF&DEBUG_OFF);
    __CONFIG(BOR4V_BOR40V&WRT_OFF);
    #ifndef _XTAL_FREQ
    	#define _XTAL_FREQ 4000000
    #endif
    unsigned char count1,count2;
    void main() {
    	TRISB=0;
    	ANSEL=ANSELH=0;
    	T0CS=0;
    	PSA=0;
    	RB0=1;
    	count1=count2=0;
    	while(1) {
    		TMR0=0;
    		T0IF=0;
    		while(!T0IF);
    		T0IF=0;
    		++count1;
    		if(count1==4) {
    			count1=0;
    			RB0=!RB0;
    		}
    	}
    }
    vậy xung tạo ra tại chân RB0 có T là bao nhiêu
    Ngắt thiếu vài cái:
    GIE=1; // Bật ngắt toàn cục
    T0IE = 1; // Bật ngắt timer 0
    PS = 0; // Prescaller là 1/2

    Về cơ bản, nếu prescaller là 1/2, thì cứ 2 Tcy đếm 1 cái (Tcy = 4/Fosc), trường hợp này là 2us đếm 1 cái. Timer 0 8 bit thì tràn trong 512us. count 4 lần thì là 2048us đảo B0 1 lần.
    Computer Science major - Vietnamese-German University
    Sponsored by

    Comment


    • #3
      Nguyên văn bởi kidteam pro
      cái đó là ngắt rồi chú ơi. mình muốn tạo trễ mà
      Sao mấy bác này thik tạo clone thế nhỉ, pó tay thật. Mấy cái kia thì enable ngắt thoy, tạo delay ko cần cũng đc, nếu ko set PS (Prescaller) thì khi ghi vào thanh ghi Timer 0 thì PS sẽ bị clear thành 000 nên prescaller lúc này là 1/2, cách tính thời gian delay như trên. Nếu muốn prescaller là 1/1 thì set PSA là 1 (PS gán cho WDT), nếu muốn set prescaller khác thì chèn nó vào ngay sau khi ghi TMR0. (Mỗi lần ghi TMR0 là clear PS lại).
      Computer Science major - Vietnamese-German University
      Sponsored by

      Comment


      • #4
        Nguyên văn bởi kidteam pro
        là sao mình không hiểu lắm. làm sao để mình cho chip đi vào WDT nhỉ.
        chỉ cần khởi tạo WDT. tính toán thời gian để WDT không xảy ra là được.

        Comment


        • #5
          ai giúp em sửa đoạn code này với ạ, duty 0.4
          lỗi:nó không chạy ra xung gì#include <htc.h>
          __CONFIG(XT & WDTDIS & PWRTEN & MCLREN & UNPROTECT & SWBOREN &
          IESODIS & FCMDIS & LVPDIS & DEBUGDIS); //1st config. Word
          __CONFIG(BORV21); //2st config. Word
          #define _XTAL_FREQ 4000000

          unsigned char count1,count2;
          void _unit() {
          TRISB=0;
          ANSEL=ANSELH=0;
          T0CS=0;
          PSA=0;
          PS2=0;
          PS1=0;
          PS0=0;
          GIE=1;
          T0IF=0;
          T0IE=1;
          TMR0=0;
          RB0=1;
          count1=count2=0;
          while(1) ;
          }

          void interrupt_isr()
          {
          if(T0IE&&T0IF)
          {

          count1++;
          count2++;





          }
          T0IF=0;
          TMR0=0;
          }
          void _thuatoan()
          {
          for(count1=0;count1<7;count1++)
          {
          if(count1=2)
          RB0=!RB0;

          }
          }


          void main()
          {
          _unit();
          interrupt_isr();
          _thuatoan();
          }

          Comment


          • #6
            Nguyên văn bởi langtu_711 Xem bài viết
            ai giúp em sửa đoạn code này với ạ, duty 0.4
            lỗi:nó không chạy ra xung gì#include <htc.h>
            __CONFIG(XT & WDTDIS & PWRTEN & MCLREN & UNPROTECT & SWBOREN &
            IESODIS & FCMDIS & LVPDIS & DEBUGDIS); //1st config. Word
            __CONFIG(BORV21); //2st config. Word
            #define _XTAL_FREQ 4000000

            unsigned char count1,count2;
            void _unit() {
            TRISB=0;
            ANSEL=ANSELH=0;
            T0CS=0;
            PSA=0;
            PS2=0;
            PS1=0;
            PS0=0;
            GIE=1;
            T0IF=0;
            T0IE=1;
            TMR0=0;
            RB0=1;
            count1=count2=0;
            while(1) ;
            }

            void interrupt_isr()
            {
            if(T0IE&&T0IF)
            {

            count1++;
            count2++;





            }
            T0IF=0;
            TMR0=0;
            }
            void _thuatoan()
            {
            for(count1=0;count1<7;count1++)
            {
            if(count1=2)
            RB0=!RB0;

            }
            }


            void main()
            {
            _unit();
            interrupt_isr();
            _thuatoan();
            }
            Để xài ngắt, thì bạn cần khai báo interrupt trước tên hàm, như thế compiler mới biết hàm đó là hàm ngắt, ví dụ như:
            void interrupt my_isr(void) { }
            Ngoài ra, bạn cần add thêm cái vòng lặp vô hạn nữa, nếu ko PIC sẽ bị rết liên tục.
            Đọc cái code của bạn, chẳng hiểu bạn đang định làm gì nữa. Trong if nhớ là biểu thức so sánh, tức count1 == 2 chứ ko phải count1 = 2.
            Computer Science major - Vietnamese-German University
            Sponsored by

            Comment


            • #7
              e cảm ơn !! a có thể sử luôn cho em được không ạ!

              Comment


              • #8
                e định tạo xung vuông với duty là 40% đấy ạ

                Comment


                • #9
                  Nguyên văn bởi langtu_711 Xem bài viết
                  e định tạo xung vuông với duty là 40% đấy ạ
                  Sơ sơ là nó như thế này (xài C18, ko xài hitech, có gì sai thì sửa lại):

                  Code:
                  #include <htc.h>
                  __CONFIG(FOSC_XT&WDTE_OFF&PWRTE_ON&MCLRE_OFF&CP_OFF&CPD_OFF&BOREN_OFF&IESO_OFF&FCMEN_OFF&LVP_OFF&DEBUG_OFF);
                  __CONFIG(BOR4V_BOR40V&WRT_OFF);
                  #ifndef _XTAL_FREQ
                  	#define _XTAL_FREQ 4000000
                  #endif
                  
                  char count = 0;
                  
                  // Hàm khởi tạo
                  void Initialize(void) {
                  	TRISB0 = 0; // B0 là output
                  	ANSEL = ANSELH = 0; // Enable digital buffer
                  	LATB0 = 0; // B0 mức thấp
                  	T0CS = 0; // T0 sử dụng xung nội
                  	PSA = 0; // Sử dụng Prescaler
                  	PS0 = PS1 = PS2 = 0; // Prescaller là 1:2
                  	T0IF = 0; // Xóa cờ ngắt T0
                  	T0IE = 1; // Ngắt T0 On
                  	GIE = 1; // Enable ngắt toàn cục
                  }
                  
                  // Hàm ngắt
                  void interrupt my_isr(void) {
                  	if (T0IE && T0IF) {
                  		if (count == 0) LATB0 = 1; // Chia thành 5 khoảng thời gian bằng nhau trong 1 chu kỳ
                  		if (count == 2) LATB0 = 0; // Tại cuối khoảng thứ 2, đảo ngõ ra xuống 0, tạo ra 1 xung 2/5 = 40%
                  		count++; // Tăng biến đếm
                  		if (count >= 5) count = 0; // Reset lại biến đếm sau 1 chu kỳ
                  		T0IF = 0; // Xóa cờ ngắt
                  	}
                  }
                  
                  // Chường trình chính
                  void main() {
                  	Initialize(); // Khởi tạo
                  	while(1) {
                  	}
                  }
                  1 chu kỳ xung ở đây là bằng (4/4000000)*256*2*5 = 2,56 ms. Trong đó 4/4000000 là chu kỳ máy, 256 là số lần đếm trong T0, 2 là Prescaler, còn 5 là max của biến đếm count.
                  Computer Science major - Vietnamese-German University
                  Sponsored by

                  Comment


                  • #10
                    cám ơn a!!!

                    Comment


                    • #11
                      #include "16f887.h"
                      #fuses NOWDT,HS,NOPUT,NOPROTECT,BROWNOUT,LVP,NOCPD,NOWRT
                      #use delay(Clock = 8000000)
                      #device *=8 ADC=8
                      int8 temp = 0;
                      int8 adc;
                      #int_TIMER1
                      void TIMER1_isr(void)
                      {
                      temp++;
                      if(temp == 4) //400us = 40% muc cao.
                      output_high(PIN_D0);
                      else if(temp == 6)
                      {
                      output_low(PIN_D0); //600us = 60% muc thap.
                      temp = 0;
                      }
                      set_timer1(65335);
                      }
                      void adc_read(void)
                      {
                      set_ADC(ADC_internal);
                      set_ADC_port(AN0);
                      set_ADC_channel(0);
                      delay_us(10);
                      while(true)
                      {
                      adc=read_adc();
                      output_B(adc);
                      #if adc>128
                      { output_low(PIN_D1);}

                      }
                      }
                      void main()
                      {
                      //Khoi tao T1 va ngat.
                      setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); //T1 dem xung noi, ti le chia 1
                      enable_interrupts(INT_TIMER1);
                      enable_interrupts(GLOBAL);
                      set_timer1(65335); //Thach anh 8 MHz => CK may = 4/8 = 0,5us
                      //100us ngat 1 lan = 200xung = 65535 - 65335
                      //Thiet lap cac pin xuat nhap
                      set_tris_d(0x00);
                      adc_read();//PORTD xuat du lieu.
                      //----------------------------
                      while(1);
                      }




                      a sửa em đoạn code này với, không hiểu sao cứ báo lỗi ở lệnh #divice *8adc=8

                      Comment


                      • #12
                        Nguyên văn bởi langtu_711 Xem bài viết
                        #include "16f887.h"
                        #fuses NOWDT,HS,NOPUT,NOPROTECT,BROWNOUT,LVP,NOCPD,NOWRT
                        #use delay(Clock = 8000000)
                        #device *=8 ADC=8
                        int8 temp = 0;
                        int8 adc;
                        #int_TIMER1
                        void TIMER1_isr(void)
                        {
                        temp++;
                        if(temp == 4) //400us = 40% muc cao.
                        output_high(PIN_D0);
                        else if(temp == 6)
                        {
                        output_low(PIN_D0); //600us = 60% muc thap.
                        temp = 0;
                        }
                        set_timer1(65335);
                        }
                        void adc_read(void)
                        {
                        set_ADC(ADC_internal);
                        set_ADC_port(AN0);
                        set_ADC_channel(0);
                        delay_us(10);
                        while(true)
                        {
                        adc=read_adc();
                        output_B(adc);
                        #if adc>128
                        { output_low(PIN_D1);}

                        }
                        }
                        void main()
                        {
                        //Khoi tao T1 va ngat.
                        setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); //T1 dem xung noi, ti le chia 1
                        enable_interrupts(INT_TIMER1);
                        enable_interrupts(GLOBAL);
                        set_timer1(65335); //Thach anh 8 MHz => CK may = 4/8 = 0,5us
                        //100us ngat 1 lan = 200xung = 65535 - 65335
                        //Thiet lap cac pin xuat nhap
                        set_tris_d(0x00);
                        adc_read();//PORTD xuat du lieu.
                        //----------------------------
                        while(1);
                        }




                        a sửa em đoạn code này với, không hiểu sao cứ báo lỗi ở lệnh #divice *8adc=8
                        Mấy cái lỗi config này mình ko bik đâu, mà mình thấy cũng xóa lun dòng đó đi.
                        Computer Science major - Vietnamese-German University
                        Sponsored by

                        Comment


                        • #13
                          xóa #divice*=8adc=8 thì adc dùng sao được ạ

                          Comment

                          Về tác giả

                          Collapse

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

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

                          Collapse

                          Đang tải...
                          X