Thông báo

Collapse
No announcement yet.

thiết lập timer/counter cho avr!

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

  • thiết lập timer/counter cho avr!

    các bác cho em hỏi, hệ thống em làm muốn có chức năng chạy trong vòng 20 tiếng, và tự động nghỉ 4 tiếng, rồi lại chạy tiếp như vậy! thì em phải thiết lập timer và couter như thế nào ạ? sơ đồ thuật toán để lập trình được điều này ra sao?
    cái thứ 2 là việc tính toán giá trị chia (prescaler ) cho xung nhịp Timer/Counter, nếu nguồn xung clock nuôi cho avr là 8MHz, thì có phải là 8 nhịp hết 1us không ạ? vậy khả năng lớn nhất mà timer/counter có thể đếm được là bao nhiêu? (cho dù là chọn prescaler=1024). em không biết là nó có thể đếm được 24 tiếng không nữa! mong các bác giúp em về cái này!

  • #2
    theo mình thì bạn có thể thiết lập timer với 1 khoảng thời gian lớn nhất có thể. Sau đó dùng ngắt timer, tăng các biến đếm lên, so sánh giá trị các biến đếm => thời gian cần thiết.
    Nguyễn Huy Biên - 01649 802 694
    gmail :

    Comment


    • #3
      các bác cho em hỏi cái, em dùng timer 1 để tạo PWM chế độ (fast PWm top on ICR1), muốn khi nhiệt độ cài đặt( biến "tang") nhỏ hơn nhiệt độ đo được thì phát xung chậm đi, nhưng em làm mãi nó chỉ tăng liên tục mà không giảm.Các bác xem hộ em cái code này với, xem có gì không ổn.
      PHP Code:
      /*****************************************************
      This program was produced by the
      CodeWizardAVR V2.04.9a Evaluation
      Automatic Program Generator
      © Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
      http://www.hpinfotech.com

      Project : 
      Version : 
      Date    : 3/22/2013
      Author  : Freeware, for evaluation and non-commercial use only
      Company : 
      Comments: 


      Chip type               : ATmega16
      Program type            : Application
      AVR Core Clock frequency: 12.000000 MHz
      Memory model            : Small
      External RAM size       : 0
      Data Stack size         : 256
      *****************************************************/
      #include <mega16.h>
      #include <stdlib.h> 
      #include <delay.h>
      //==============================khai bao bien================================= 
       
      unsigned char  lcdBuff[10];
       
      float gt_ADC
       
      int giatri[10]; 
       
      int biendem=1;
       
      unsigned char mang[10]; 
       
      int tang=45;
       
      #define C1 PINB.3
      #define C2 PINB.2
      #define H2 PINB.1
      #define H1 PINB.0
       //================================bat dau thoi===============================

      // Alphanumeric LCD Module functions
      #include <alcd.h>

      unsigned int adc_data;
      #define ADC_VREF_TYPE 0xC0

      // ADC interrupt service routine
      interrupt [ADC_INTvoid adc_isr(void)
      {
      // Read the AD conversion result
      adc_data=ADCW;
      }

      // Read the AD conversion result
      // with noise canceling
      unsigned int read_adc(unsigned char adc_input)
      {
      ADMUX=adc_input | (ADC_VREF_TYPE 0xff);
      // Delay needed for the stabilization of the ADC input voltage
      delay_us(10);
      #asm
          
      in   r30,mcucr
          cbr  r30
      ,__sm_mask
          sbr  r30
      ,__se_bit __sm_adc_noise_red
          out  mcucr
      ,r30
          sleep
          cbr  r30
      ,__se_bit
          out  mcucr
      ,r30
      #endasm
      return adc_data;
      }

      //=====================================================================
      char stt(void)
      {

      PORTB=0x03;
      DDRB=0x0C;
      if((!
      H1)|(!H2) )
      {
      if(!
      H1)
      {
      PORTB=0b11111110;
       
      DDRB =0b00000001;
       if(!
      C1){while(!C1){;}return 1;}
       if(!
      C2) {while(!C2){;}return 2;}
       }
       if(!
      H2)
       { 
      PORTB=0b11111101;
       
      DDRB =0b00000010
         if(!
      C1){while(!C1){;}return 3;}
       if(!
      C2) {while(!C2){;}return 4;} 
      }
      }else
      return 
      5;   }
      //====================================================================
       
      void quetphim()
       { 
      char x=stt();
       if (
      x==1)
       
      biendem++;
       if(
      x==3)
       
      tang++;
       if(
      x==4)
       
      tang--;
       }
       
      //================================================================
      void sumadc (void)
      {
      unsigned char x,y;
      for(
      x=0;x<=1;x++)
      for(
      y=0y<=29y++)
      giatri[x]=read_adc(x)+giatri[x];
      }
      //====================================================================
      void hienthi (void)
            {  
      unsigned char x,y;
            
      sumadc();
            for( 
      x=0;x<=1;x++)
               { 
      lcd_gotoxy(x,x);
             
      gt_ADC=((float)(giatri[x]/120));
            
      ftoa(gt_ADC,2,lcdBuff);
            
      lcd_puts(lcdBuff);
            
      delay_ms(10);
            
      giatri[x]=0;
            for( 
      y=0;y<=7;y++)
            
      lcdBuff[y]=0
            }
            } 
      //========================================================
      void hienthisoint x)
      {
      int a,b;
      a=0;
      while(
      x>0)
      mang[a]=x%10;
      x=x/10;
      a++;
      }
      while((
      x==0)&(a<=3))
      mang[a]=0;
      a++;}
      a--;
      for(
      b=ab>=0b--)
       
      lcd_putchar(mang[b]+48); 
       }

      //================================================
      void hienthi_mode(void)
      {
      if ((
      biendem%2)==0)
      {
      lcd_gotoxy(0,0);
      lcd_putsf("Nhiet cai dat");
      lcd_gotoxy(1,1);
      hienthiso(tang);
      }
      else
      {
      lcd_clear();
      lcd_gotoxy(6,0);
       
      hienthiso(stt());
       
      lcd_gotoxy(6,1);
       
      hienthiso(OCR1A);
       
      hienthi();
       }
      }
      //====================================================
       /*void xungpwm(int x)
       {  
      //ICR1H=0x4e; 3774
      //ICR1L=0x20;
      OCR1A=OCR1A-x;//1388=5000
      OCR1B=OCR1B-x; //2710=10000*/
         //====================================================
        
      void kiemsoat (void)
      {
        
      int y;
      if(
      tang>(giatri[0]/120))// giatri chia 120 vì lay mau 30 lan và 1 do C tuong duong voi 4 don vi dau vao ADC
      {y=OCR1A;
      OCR1A=y+10;
      //OCR1B=OCR1B+10;


      if((
      giatri[0]/120)>tang )
      {
      OCR1A=OCR1A+10;
      //OCR1B=OCR1B-10;
      } ;

      if(
      tang==(giatri[0]/120))
      {
      y=OCR1A;
      OCR1A=y+0;
      //OCR1B=OCR1B+0;

       
      delay_ms(500);

      }
        
      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=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 
      PORTC=0x00;
      DDRC=0xFF;

      // Port D 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 
      PORTD=0x00;
      DDRD=0xFF;

      // Timer/Counter 0 initialization
      // Clock source: System Clock
      // Clock value: Timer 0 Stopped
      // Mode: Normal top=0xFF
      // OC0 output: Disconnected
      TCCR0=0x00;
      TCNT0=0x00;
      OCR0=0x00;

      // Timer/Counter 1 initialization
      // Clock source: System Clock
      // Clock value: 187.500 kHz
      // Mode: Fast PWM top=ICR1
      // OC1A output: Inverted
      // OC1B output: Inverted
      // 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=0xF2;
      TCCR1B=0x1B;
      TCNT1H=0x00;
      TCNT1L=0x00;
      ICR1H=0x0e;
      ICR1L=0xbe;
      OCR1A=1000;
      //OCR1AL=0x00;
      OCR1B=1000;
      //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;

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

      // ADC initialization
      // ADC Clock frequency: 375.000 kHz
      // ADC Voltage Reference: AREF pin
      // ADC Auto Trigger Source: ADC Stopped
      ADMUX=ADC_VREF_TYPE 0xff;
      ADCSRA=0x8D;

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

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


      while (1)
            {  
      quetphim();
            
      hienthi_mode();
            
      kiemsoat();
            

            }

      thank các bác trước!!!!!!!!!!!!

      Comment


      • #4
        Nguyên văn bởi gaconhamhoc Xem bài viết
        các bác cho em hỏi cái, em dùng timer 1 để tạo PWM chế độ (fast PWm top on ICR1), muốn khi nhiệt độ cài đặt( biến "tang") nhỏ hơn nhiệt độ đo được thì phát xung chậm đi, nhưng em làm mãi nó chỉ tăng liên tục mà không giảm.Các bác xem hộ em cái code này với, xem có gì không ổn.
        Đọc code nhức đầu lắm, chỉ cần bạn sai 1 dấu phẩy hoặc sai 1 lỗi logic nhỏ thì lắm vấn đề nảy sinh, vì thế mình xác định là sẽ ko đọc code đâu nên mình sẽ hướng dẫn bạn kinh nghiệm lập trình rồi bạn tự kiểm lại.
        _ Đầu tiên bạn viết 1 code cho PWM tăng tốc độ và 1 code cho PWM giảm tốc từ từ, sau đó mang lên Proteus hoặc test motor trực tiếp để chắc chắn 2 cái code này phải chạy ok, nhớ kiểm lại nhiều lần để chắc rằng tụi nó ko bị chồng chập logic vào nhau.
        _ sau đó lập trình cho cái biến nhiệt độ can thiệp vào 2 cái code PWM, còn đương nhiên biến bạn thiết lập thì bạn phải quản lý được, nếu có lỗi thì đương nhiên là do việc xử lý biến gây ra rồi vì phần PWM đã ok.
        _ nên làm từ từ cẩn thận, tránh việc nghĩ cái gì trong đầu là tay code cái đó, làm hồi loạn mù luôn đó (ghĩ ra cái gì thì ghi ra giấy trước). code nào OK thì save riêng ra để còn có vốn trong trường hợp code quá dài mà ko biết lỗi do đâu -> phá sản.
        _muốn hỏi về code thì trước tiên bạn phải xác định hoặc phỏng đoán chỗ code nào có vấn đề rồi hỏi chính xác khúc code đó sẽ nhanh và hay hơn, vì thường code bạn lập trình thì bạn hiểu chớ ai hiểu nổi, chưa kể là bạn viết theo kiểu chương trình con thì chả muốn scroll ngược lên trên để xem bạn viết cái gì bởi vì sau khi xem xong họ sẽ quên mất chương trình chính bạn viết cái gì rồi lại phải scroll ngược xuống để xem, thế có hài hước và mất thời gian ko chớ.
        Làm sao mà bạn dám nói là không làm được khi bạn chưa từng thử một lần nào.
        Ngay cả khi bạn đã làm 1 lần và thất bại bạn cũng không có quyền nói là không làm được vì bạn chưa làm lần thứ 2,3...

        Comment


        • #5
          bác nào đã từng làm về phần hẹn giờ cho vi điều khiển hoạt động mà viết bằng ngôn ngữ C cho avr không ạ? có thể post đoạn code lên cho em tham khảo với được không ạ? vì em không biết bắt đầu từ đâu! em xin cảm ơn!

          Comment


          • #6
            Nguyên văn bởi ninh_bk_1991 Xem bài viết
            bác nào đã từng làm về phần hẹn giờ cho vi điều khiển hoạt động mà viết bằng ngôn ngữ C cho avr không ạ? có thể post đoạn code lên cho em tham khảo với được không ạ? vì em không biết bắt đầu từ đâu! em xin cảm ơn!
            coi như vì đàn em thân yêu vậy, mình sẽ cố viết cho bạn đoạn code C cho avr cứ khoảng 2-3 phút bật tắt con led 1 lần = timer trên mô phỏng proteus rồi cố giải thích thật kỹ rồi bạn tự tăng vòng lặp lên để có 20 tiếng như bạn muốn, bạn chờ tí nha.
            Làm sao mà bạn dám nói là không làm được khi bạn chưa từng thử một lần nào.
            Ngay cả khi bạn đã làm 1 lần và thất bại bạn cũng không có quyền nói là không làm được vì bạn chưa làm lần thứ 2,3...

            Comment


            • #7
              Ok của bạn ninh bk xong rồi đây:
              code nè:

              /************************************************** ***
              This program was produced by the
              CodeWizardAVR V2.05.6 Evaluation
              Automatic Program Generator
              © Copyright 1998-2012 Pavel Haiduc, HP InfoTech s.r.l.
              http://www.hpinfotech.com

              Project :
              Version :
              Date : 24-03-2013
              Author : Freeware, for evaluation and
              non-commercial use only
              Company :
              Comments:


              Chip type : ATmega32A
              Program type : Application
              AVR Core Clock frequency: 16.000000 MHz
              Memory model : Small
              External RAM size : 0
              Data Stack size : 512
              ************************************************** ***/

              #include <mega32a.h>
              #include <delay.h>



              // Declare your global variables here
              unsigned long int ngat;


              //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxx
              //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxx
              // Timer 0 overflow interrupt service routine
              interrupt [TIM0_OVF] void timer0_ovf_isr(void)
              {
              // Place your code here

              ngat++;
              TCNT0=0x00;

              if (ngat>10200)
              {
              ngat=0;
              };

              }


              //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxx
              //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxx

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

              // Input/Output Ports initialization
              // Port A initialization
              // Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
              // State7=1 State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=1
              PORTA=0xFF;
              DDRA=0xFF;

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

              // Port C initialization
              // Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
              // State7=1 State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=1
              PORTC=0xFF;
              DDRC=0xFF;

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

              // Timer/Counter 0 initialization
              // Clock source: System Clock
              // Clock value: 15.625 kHz
              // Mode: Normal top=0xFF
              // OC0 output: Disconnected
              TCCR0=0x05;
              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=0x01;

              // 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")

              while (1)
              {
              // Place your code here

              if (ngat>=10000)
              {
              PORTA.0=0;
              delay_ms(10000);
              };

              PORTA.0=1;

              }

              }

              hình mô phỏng chạy ok nè:
              chưa bật led
              Click image for larger version

Name:	avr01.png
Views:	1
Size:	36.0 KB
ID:	1375952

              bật led sau 2,7 phút = timmer (muốn sau 2 năm bật led cũng được )
              Click image for larger version

Name:	avr02.png
Views:	1
Size:	36.7 KB
ID:	1375953

              Phần code mình đánh dấu màu đỏ là quan trọng và mình sẽ giải thích
              Last edited by hoahauvn2; 24-03-2013, 05:58.
              Làm sao mà bạn dám nói là không làm được khi bạn chưa từng thử một lần nào.
              Ngay cả khi bạn đã làm 1 lần và thất bại bạn cũng không có quyền nói là không làm được vì bạn chưa làm lần thứ 2,3...

              Comment


              • #8
                Mình bắt đầu giải thích từ từ đây:

                Muốn xài timer thì phải thiết lập timer, mình thiết lập dùng timer0:
                // Timer/Counter 0 initialization
                // Clock source: System Clock
                // Clock value: 15.625 kHz
                // Mode: Normal top=0xFF
                // OC0 output: Disconnected
                TCCR0=0x05;
                TCNT0=0x00;
                OCR0=0x00;


                Nó là cái code thiết lập timer theo khai báo của mình trên codevisionAVR, có 1 số điểm cần lưu ý sau đây:
                _Codevision có cái hay là nó tự thiết lập thời gain đếm của timer dựa trên các tần số chuẩn (ở đây mình chọn là 15.625Khz) mà ko bắt người dùng tính toán trên thạch anh (vì nó tự tính sẵn).
                _mình khai báo dùng thạch anh 16Mhz nên tần số đếm của timer có thể lên đến 16Mhz, nếu tham lam và thiếu hiểu biết cứ quất timer 16Mhz rồi bạn sẽ thấy hậu quả (MCU lo đếm và ngắt timer là hết giờ ko đào ra time xử lý chương trình chính, cụ thể là mcu sẽ thực hiện hàm delay 1s trong 1h ), mình dùng timer có tần số thấp nhất là 16.625Khz cho phù hợp với yêu cầu mcu nghỉ tầm 20h của bạn.
                _ cái normal top=0xff có nghĩa là đây là timer 8bit và khi nó đếm đến 255 thì tràn timer, lúc đó timer sẽ nhảy vào thực hiện chương trình ngắt.
                _Chắc chắn là bạn sẽ thắc mắc vậy từ lúc bắt đầu đến lúc tràn MCU sẽ làm mất bao lâu?? tần số timer là 15.625Khz -> chu kì 1 lần đếm lên là 6.5x10 mũ -5 giây -> khi tràn là timer đã đếm 255 lần -> hết 255x6.4x10 mũ -5 = 0.01632 giây
                _Có lẽ bạn sẽ thắc mắc vậy cái biến nào ẩn trong timer sẽ được đếm lên từ 0-255 đây?? xin thưa nó đây: TCNT0=0x00; khi timer tràn thằng này sẽ có giá trị là 255, vì thế trong ngắt timer bạn phải reset lại thằng này =0, nếu ko thì nó sẽ 255 hoài lúc đó chả làm ăn được gì cả.

                Tiếp theo ta thấy timer tốn có 0.01632 giây là tràn mất tiêu rồi vậy làm sao có được 20 tiếng đây, ko lo trong hàm ngắt timer ta sẽ làm việc này:
                // Timer 0 overflow interrupt service routine
                interrupt [TIM0_OVF] void timer0_ovf_isr(void)
                {
                // Place your code here

                ngat++;
                TCNT0=0x00;

                if (ngat>10200)
                {
                ngat=0;
                };

                }


                lúc đầu khi vừa mới thiết lập cho chip xong để vào lập trình, bạn sẽ thấy hàm ngắt timer sẽ được đưa lên trước khu khai báo biến (mặc định của codevision), bạn bắt buộc phải cắt đoạn hàm ngắt này cho xuống ngay bên dưới khu khai báo biến, nếu trong code của bạn có chương trình con thì các hàm phục vụ ngắt phải là chương trình con cuối cùng. Nghe hơi khó hiểu nhỉ, giải thích rất đơn giản, giả sử trong hàm ngắt timer có sử dụng 1 biến thì bắt buộc biến đó phải được khai báo trước hàm ngắt, nếu ko trình biên dịch sẽ đọc theo thứ tự từ trên xuống dưới và ko hiểu cái biến đó ở đâu ra và báo lỗi.
                _Cái biến đặc biệt đó ở đây là biến ngat theo như các bạn thấy trên code. Nhìn vào cái code các bạn dễ dàng thấy được là khi tràn timer ngắt xảy ra thì trong hàm ngắt mình cho tăng cái biến ngắt lên 1 đơn vị, đồng thời xóa biến chạy timer về 0 (vì lúc này nó =255). Lúc này thì ngon rồi, sau 0.01632 giây là biến ngat tang lên chỉ có 1 đơn vị, mình khai báo biến ngat dạng unsigned long int tức là nó có khả năng chạy từ 0 đến 4294967295, một con số kinh khủng 4 tỷ 2 trăm 9 mươi 4 triệu, chỉ cần sử dụng 4 tỷ 2 thôi là mcu có thể delay đến 19040 tiếng =2.2 năm (chờ chết già)
                _Các bạn có thấy hàm if trong hàm ngắt ko?? hàm if này có ý nghĩa là mình cho ngat len den 10200 thôi là reset lại 0, vì 10200 mình tính delay được cỡ 3 phút để test là ok (ai có dư thời gian và thừa dũng cảm cứ thử test trong 20 tiếng xem chứ mình thì ko có ), cho bạn biết mình lập trình cho bạn lúc 3 giờ sáng ngồi chờ led sáng có 2.7 phút mà ngỡ 2.7 tiếng vì buồn ngủ chết được, hãi .

                Mệt thật cố lên gần xong giờ thì mọi thứ ổn rồi chỉ còn vào chương trình chính thôi:
                if (ngat>=10000)
                {
                PORTA.0=0;
                delay_ms(10000);
                };

                PORTA.0=1;

                }


                Chương trình chính khá đơn giản, mình cho đọc biến ngat nếu nó >=1000 (lúc này chờ được khoảng 2.7 phút sao lâu vãi) thì cho bật led ở portA.0 lên trong 10 giây rồi tắt đi, sau đó lặp lại quá trình chờ mòn mỏi xem led sáng.

                Vậy là xong rồi đó, nếu muốn tăng thời gian chờ lên thì bạn thay đổi 2 thông số của biến ngat trong chượng trình chính và hàm ngắt cao lên theo cách tính trên là ok. Lưu ý 1 điểm quan trọng là ngat trong hàm ngắt bao giờ cũng phải cao hơn vài chục đến vài trăm đơn vị so với ngat trong chương trình chính để tạo 1 khảng trừ hao cho chương trình chính có thời gian bắt được thông số biến ngat tại lúc chuyển đổi.
                Mình lấy 1 ví dụ trong trường hợp tổ trát thế này, giả sử trong hàm ngắt bạn cho biến ngắt đếm đến 10000 rồi trả về 0 ngay lập tức, chương trình chính thì khi biến ngắt >=10000 thì bật led, lúc này thì ngay khi biến ngat đạt 10000, hên thì đó là lúc chương trình chính bắt được giá trị này thì bật led, xui thì hàm ngắt bắt trước rồi reset về 0 thì chương trình chính đói mốc mỏ. Lúc đó thì đừng hỏi tại sao code viết đúng mà chả chạy (chạy mới là lạ đó).
                Xoooooong thấy có ích thì nhấn nút cảm ơn nhá, còn mình thì kiệt sức rồi, ôi cha mẹ ơi còn ngủ được 2 tiếng là phải chạy lên trường học rồi.
                Làm sao mà bạn dám nói là không làm được khi bạn chưa từng thử một lần nào.
                Ngay cả khi bạn đã làm 1 lần và thất bại bạn cũng không có quyền nói là không làm được vì bạn chưa làm lần thứ 2,3...

                Comment


                • #9
                  Nguyên văn bởi hoahauvn2 Xem bài viết
                  Mình bắt đầu giải thích từ từ đây:

                  Muốn xài timer thì phải thiết lập timer, mình thiết lập dùng timer0:
                  // Timer/Counter 0 initialization
                  // Clock source: System Clock
                  // Clock value: 15.625 kHz
                  // Mode: Normal top=0xFF
                  // OC0 output: Disconnected
                  TCCR0=0x05;
                  TCNT0=0x00;
                  OCR0=0x00;


                  Nó là cái code thiết lập timer theo khai báo của mình trên codevisionAVR, có 1 số điểm cần lưu ý sau đây:
                  _Codevision có cái hay là nó tự thiết lập thời gain đếm của timer dựa trên các tần số chuẩn (ở đây mình chọn là 15.625Khz) mà ko bắt người dùng tính toán trên thạch anh (vì nó tự tính sẵn).
                  _mình khai báo dùng thạch anh 16Mhz nên tần số đếm của timer có thể lên đến 16Mhz, nếu tham lam và thiếu hiểu biết cứ quất timer 16Mhz rồi bạn sẽ thấy hậu quả (MCU lo đếm và ngắt timer là hết giờ ko đào ra time xử lý chương trình chính, cụ thể là mcu sẽ thực hiện hàm delay 1s trong 1h ), mình dùng timer có tần số thấp nhất là 16.625Khz cho phù hợp với yêu cầu mcu nghỉ tầm 20h của bạn.
                  _ cái normal top=0xff có nghĩa là đây là timer 8bit và khi nó đếm đến 255 thì tràn timer, lúc đó timer sẽ nhảy vào thực hiện chương trình ngắt.
                  _Chắc chắn là bạn sẽ thắc mắc vậy từ lúc bắt đầu đến lúc tràn MCU sẽ làm mất bao lâu?? tần số timer là 15.625Khz -> chu kì 1 lần đếm lên là 6.5x10 mũ -5 giây -> khi tràn là timer đã đếm 255 lần -> hết 255x6.4x10 mũ -5 = 0.01632 giây
                  _Có lẽ bạn sẽ thắc mắc vậy cái biến nào ẩn trong timer sẽ được đếm lên từ 0-255 đây?? xin thưa nó đây: TCNT0=0x00; khi timer tràn thằng này sẽ có giá trị là 255, vì thế trong ngắt timer bạn phải reset lại thằng này =0, nếu ko thì nó sẽ 255 hoài lúc đó chả làm ăn được gì cả.

                  Tiếp theo ta thấy timer tốn có 0.01632 giây là tràn mất tiêu rồi vậy làm sao có được 20 tiếng đây, ko lo trong hàm ngắt timer ta sẽ làm việc này:
                  // Timer 0 overflow interrupt service routine
                  interrupt [TIM0_OVF] void timer0_ovf_isr(void)
                  {
                  // Place your code here

                  ngat++;
                  TCNT0=0x00;

                  if (ngat>10200)
                  {
                  ngat=0;
                  };

                  }


                  lúc đầu khi vừa mới thiết lập cho chip xong để vào lập trình, bạn sẽ thấy hàm ngắt timer sẽ được đưa lên trước khu khai báo biến (mặc định của codevision), bạn bắt buộc phải cắt đoạn hàm ngắt này cho xuống ngay bên dưới khu khai báo biến, nếu trong code của bạn có chương trình con thì các hàm phục vụ ngắt phải là chương trình con cuối cùng. Nghe hơi khó hiểu nhỉ, giải thích rất đơn giản, giả sử trong hàm ngắt timer có sử dụng 1 biến thì bắt buộc biến đó phải được khai báo trước hàm ngắt, nếu ko trình biên dịch sẽ đọc theo thứ tự từ trên xuống dưới và ko hiểu cái biến đó ở đâu ra và báo lỗi.
                  _Cái biến đặc biệt đó ở đây là biến ngat theo như các bạn thấy trên code. Nhìn vào cái code các bạn dễ dàng thấy được là khi tràn timer ngắt xảy ra thì trong hàm ngắt mình cho tăng cái biến ngắt lên 1 đơn vị, đồng thời xóa biến chạy timer về 0 (vì lúc này nó =255). Lúc này thì ngon rồi, sau 0.01632 giây là biến ngat tang lên chỉ có 1 đơn vị, mình khai báo biến ngat dạng unsigned long int tức là nó có khả năng chạy từ 0 đến 4294967295, một con số kinh khủng 4 tỷ 2 trăm 9 mươi 4 triệu, chỉ cần sử dụng 4 tỷ 2 thôi là mcu có thể delay đến 19040 tiếng =2.2 năm (chờ chết già)
                  _Các bạn có thấy hàm if trong hàm ngắt ko?? hàm if này có ý nghĩa là mình cho ngat len den 10200 thôi là reset lại 0, vì 10200 mình tính delay được cỡ 3 phút để test là ok (ai có dư thời gian và thừa dũng cảm cứ thử test trong 20 tiếng xem chứ mình thì ko có ), cho bạn biết mình lập trình cho bạn lúc 3 giờ sáng ngồi chờ led sáng có 2.7 phút mà ngỡ 2.7 tiếng vì buồn ngủ chết được, hãi .

                  Mệt thật cố lên gần xong giờ thì mọi thứ ổn rồi chỉ còn vào chương trình chính thôi:
                  if (ngat>=10000)
                  {
                  PORTA.0=0;
                  delay_ms(10000);
                  };

                  PORTA.0=1;

                  }


                  Chương trình chính khá đơn giản, mình cho đọc biến ngat nếu nó >=1000 (lúc này chờ được khoảng 2.7 phút sao lâu vãi) thì cho bật led ở portA.0 lên trong 10 giây rồi tắt đi, sau đó lặp lại quá trình chờ mòn mỏi xem led sáng.

                  Vậy là xong rồi đó, nếu muốn tăng thời gian chờ lên thì bạn thay đổi 2 thông số của biến ngat trong chượng trình chính và hàm ngắt cao lên theo cách tính trên là ok. Lưu ý 1 điểm quan trọng là ngat trong hàm ngắt bao giờ cũng phải cao hơn vài chục đến vài trăm đơn vị so với ngat trong chương trình chính để tạo 1 khảng trừ hao cho chương trình chính có thời gian bắt được thông số biến ngat tại lúc chuyển đổi.
                  Mình lấy 1 ví dụ trong trường hợp tổ trát thế này, giả sử trong hàm ngắt bạn cho biến ngắt đếm đến 10000 rồi trả về 0 ngay lập tức, chương trình chính thì khi biến ngắt >=10000 thì bật led, lúc này thì ngay khi biến ngat đạt 10000, hên thì đó là lúc chương trình chính bắt được giá trị này thì bật led, xui thì hàm ngắt bắt trước rồi reset về 0 thì chương trình chính đói mốc mỏ. Lúc đó thì đừng hỏi tại sao code viết đúng mà chả chạy (chạy mới là lạ đó).
                  Xoooooong thấy có ích thì nhấn nút cảm ơn nhá, còn mình thì kiệt sức rồi, ôi cha mẹ ơi còn ngủ được 2 tiếng là phải chạy lên trường học rồi.
                  oa oa! em chưa đọc, nhưng thấy bác viết thế này, có lẽ em hôm nào em mời bác đi caffee mới được! hihi! em sẽ từ từ nghiền ngẫm! cảm ơn bác "e nờ" lần nhé! hihi

                  Comment


                  • #10
                    dúng ic ds1307 đi bạn tha hồ mà hẹn giờ

                    Comment


                    • #11
                      Dùng ds1307 là ok nhất, thời gian hẹn càng dài thì độ chính xác càng thấp khi dùng timer, dùng 1307 đi, cái này avr có hàm hỗ trợ hết, viết code cũng mau thôi, giá 1307 có 10k.
                      hãy cố gắng dù vướn phải thất bại!!!!!!!!

                      Comment


                      • #12
                        Nguyên văn bởi hoahauvn2 Xem bài viết
                        Mình bắt đầu giải thích từ từ đây:

                        Muốn xài timer thì phải thiết lập timer, mình thiết lập dùng timer0:
                        // Timer/Counter 0 initialization
                        // Clock source: System Clock
                        // Clock value: 15.625 kHz
                        // Mode: Normal top=0xFF
                        // OC0 output: Disconnected
                        TCCR0=0x05;
                        TCNT0=0x00;
                        OCR0=0x00;


                        Nó là cái code thiết lập timer theo khai báo của mình trên codevisionAVR, có 1 số điểm cần lưu ý sau đây:
                        _Codevision có cái hay là nó tự thiết lập thời gain đếm của timer dựa trên các tần số chuẩn (ở đây mình chọn là 15.625Khz) mà ko bắt người dùng tính toán trên thạch anh (vì nó tự tính sẵn).
                        _mình khai báo dùng thạch anh 16Mhz nên tần số đếm của timer có thể lên đến 16Mhz, nếu tham lam và thiếu hiểu biết cứ quất timer 16Mhz rồi bạn sẽ thấy hậu quả (MCU lo đếm và ngắt timer là hết giờ ko đào ra time xử lý chương trình chính, cụ thể là mcu sẽ thực hiện hàm delay 1s trong 1h ), mình dùng timer có tần số thấp nhất là 16.625Khz cho phù hợp với yêu cầu mcu nghỉ tầm 20h của bạn.
                        _ cái normal top=0xff có nghĩa là đây là timer 8bit và khi nó đếm đến 255 thì tràn timer, lúc đó timer sẽ nhảy vào thực hiện chương trình ngắt.
                        _Chắc chắn là bạn sẽ thắc mắc vậy từ lúc bắt đầu đến lúc tràn MCU sẽ làm mất bao lâu?? tần số timer là 15.625Khz -> chu kì 1 lần đếm lên là 6.5x10 mũ -5 giây -> khi tràn là timer đã đếm 255 lần -> hết 255x6.4x10 mũ -5 = 0.01632 giây
                        _Có lẽ bạn sẽ thắc mắc vậy cái biến nào ẩn trong timer sẽ được đếm lên từ 0-255 đây?? xin thưa nó đây: TCNT0=0x00; khi timer tràn thằng này sẽ có giá trị là 255, vì thế trong ngắt timer bạn phải reset lại thằng này =0, nếu ko thì nó sẽ 255 hoài lúc đó chả làm ăn được gì cả.

                        Tiếp theo ta thấy timer tốn có 0.01632 giây là tràn mất tiêu rồi vậy làm sao có được 20 tiếng đây, ko lo trong hàm ngắt timer ta sẽ làm việc này:
                        // Timer 0 overflow interrupt service routine
                        interrupt [TIM0_OVF] void timer0_ovf_isr(void)
                        {
                        // Place your code here

                        ngat++;
                        TCNT0=0x00;

                        if (ngat>10200)
                        {
                        ngat=0;
                        };

                        }


                        lúc đầu khi vừa mới thiết lập cho chip xong để vào lập trình, bạn sẽ thấy hàm ngắt timer sẽ được đưa lên trước khu khai báo biến (mặc định của codevision), bạn bắt buộc phải cắt đoạn hàm ngắt này cho xuống ngay bên dưới khu khai báo biến, nếu trong code của bạn có chương trình con thì các hàm phục vụ ngắt phải là chương trình con cuối cùng. Nghe hơi khó hiểu nhỉ, giải thích rất đơn giản, giả sử trong hàm ngắt timer có sử dụng 1 biến thì bắt buộc biến đó phải được khai báo trước hàm ngắt, nếu ko trình biên dịch sẽ đọc theo thứ tự từ trên xuống dưới và ko hiểu cái biến đó ở đâu ra và báo lỗi.
                        _Cái biến đặc biệt đó ở đây là biến ngat theo như các bạn thấy trên code. Nhìn vào cái code các bạn dễ dàng thấy được là khi tràn timer ngắt xảy ra thì trong hàm ngắt mình cho tăng cái biến ngắt lên 1 đơn vị, đồng thời xóa biến chạy timer về 0 (vì lúc này nó =255). Lúc này thì ngon rồi, sau 0.01632 giây là biến ngat tang lên chỉ có 1 đơn vị, mình khai báo biến ngat dạng unsigned long int tức là nó có khả năng chạy từ 0 đến 4294967295, một con số kinh khủng 4 tỷ 2 trăm 9 mươi 4 triệu, chỉ cần sử dụng 4 tỷ 2 thôi là mcu có thể delay đến 19040 tiếng =2.2 năm (chờ chết già)
                        _Các bạn có thấy hàm if trong hàm ngắt ko?? hàm if này có ý nghĩa là mình cho ngat len den 10200 thôi là reset lại 0, vì 10200 mình tính delay được cỡ 3 phút để test là ok (ai có dư thời gian và thừa dũng cảm cứ thử test trong 20 tiếng xem chứ mình thì ko có ), cho bạn biết mình lập trình cho bạn lúc 3 giờ sáng ngồi chờ led sáng có 2.7 phút mà ngỡ 2.7 tiếng vì buồn ngủ chết được, hãi .

                        Mệt thật cố lên gần xong giờ thì mọi thứ ổn rồi chỉ còn vào chương trình chính thôi:
                        if (ngat>=10000)
                        {
                        PORTA.0=0;
                        delay_ms(10000);
                        };

                        PORTA.0=1;

                        }


                        Chương trình chính khá đơn giản, mình cho đọc biến ngat nếu nó >=1000 (lúc này chờ được khoảng 2.7 phút sao lâu vãi) thì cho bật led ở portA.0 lên trong 10 giây rồi tắt đi, sau đó lặp lại quá trình chờ mòn mỏi xem led sáng.

                        Vậy là xong rồi đó, nếu muốn tăng thời gian chờ lên thì bạn thay đổi 2 thông số của biến ngat trong chượng trình chính và hàm ngắt cao lên theo cách tính trên là ok. Lưu ý 1 điểm quan trọng là ngat trong hàm ngắt bao giờ cũng phải cao hơn vài chục đến vài trăm đơn vị so với ngat trong chương trình chính để tạo 1 khảng trừ hao cho chương trình chính có thời gian bắt được thông số biến ngat tại lúc chuyển đổi.
                        Mình lấy 1 ví dụ trong trường hợp tổ trát thế này, giả sử trong hàm ngắt bạn cho biến ngắt đếm đến 10000 rồi trả về 0 ngay lập tức, chương trình chính thì khi biến ngắt >=10000 thì bật led, lúc này thì ngay khi biến ngat đạt 10000, hên thì đó là lúc chương trình chính bắt được giá trị này thì bật led, xui thì hàm ngắt bắt trước rồi reset về 0 thì chương trình chính đói mốc mỏ. Lúc đó thì đừng hỏi tại sao code viết đúng mà chả chạy (chạy mới là lạ đó).
                        Xoooooong thấy có ích thì nhấn nút cảm ơn nhá, còn mình thì kiệt sức rồi, ôi cha mẹ ơi còn ngủ được 2 tiếng là phải chạy lên trường học rồi.
                        bác ơi! cho em hỏi về cái này cái! ví dụ mạch ứng dụng của em có nguồn dao động clk=8MHz, thì có phải là 8 nhịp là 1us(micro giây) không ạ?
                        vậy thì em khai báo T/C0 như của bác là:
                        Clock value: 15.625 kHz
                        TCCR0=0x05; // CS02=1, CS01=0, CS00=1: chon Prescaler = 1024
                        thì làm sao để tính được giá trị ngắt là bao nhiêu, khi em muốn bóng đèn của em sáng trong 5 giây! em xin cám ơn bác!^^!

                        Comment


                        • #13
                          Nguyên văn bởi ninh_bk_1991 Xem bài viết
                          các bác cho em hỏi, hệ thống em làm muốn có chức năng chạy trong vòng 20 tiếng, và tự động nghỉ 4 tiếng, rồi lại chạy tiếp như vậy! thì em phải thiết lập timer và couter như thế nào ạ? sơ đồ thuật toán để lập trình được điều này ra sao?
                          cái thứ 2 là việc tính toán giá trị chia (prescaler ) cho xung nhịp Timer/Counter, nếu nguồn xung clock nuôi cho avr là 8MHz, thì có phải là 8 nhịp hết 1us không ạ? vậy khả năng lớn nhất mà timer/counter có thể đếm được là bao nhiêu? (cho dù là chọn prescaler=1024). em không biết là nó có thể đếm được 24 tiếng không nữa! mong các bác giúp em về cái này!
                          nên kết hợp sử dụng với ic ds1307 sẽ dễ đặt thời gian hơn.

                          Comment


                          • #14
                            ngắt xong cho dừng hệ thống

                            Nguyên văn bởi hoahauvn2 Xem bài viết
                            Ok của bạn ninh bk xong rồi đây:
                            code nè:

                            /************************************************** ***
                            This program was produced by the
                            CodeWizardAVR V2.05.6 Evaluation
                            Automatic Program Generator
                            © Copyright 1998-2012 Pavel Haiduc, HP InfoTech s.r.l.
                            HP InfoTech - CodeVisionAVR C Compiler

                            Project :
                            Version :
                            Date : 24-03-2013
                            Author : Freeware, for evaluation and
                            non-commercial use only
                            Company :
                            Comments:


                            Chip type : ATmega32A
                            Program type : Application
                            AVR Core Clock frequency: 16.000000 MHz
                            Memory model : Small
                            External RAM size : 0
                            Data Stack size : 512
                            ************************************************** ***/

                            #include <mega32a.h>
                            #include <delay.h>



                            // Declare your global variables here
                            unsigned long int ngat;


                            //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxx
                            //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxx
                            // Timer 0 overflow interrupt service routine
                            interrupt [TIM0_OVF] void timer0_ovf_isr(void)
                            {
                            // Place your code here

                            ngat++;
                            TCNT0=0x00;

                            if (ngat>10200)
                            {
                            ngat=0;
                            };

                            }


                            //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxx
                            //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxx

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

                            // Input/Output Ports initialization
                            // Port A initialization
                            // Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
                            // State7=1 State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=1
                            PORTA=0xFF;
                            DDRA=0xFF;

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

                            // Port C initialization
                            // Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
                            // State7=1 State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=1
                            PORTC=0xFF;
                            DDRC=0xFF;

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

                            // Timer/Counter 0 initialization
                            // Clock source: System Clock
                            // Clock value: 15.625 kHz
                            // Mode: Normal top=0xFF
                            // OC0 output: Disconnected
                            TCCR0=0x05;
                            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=0x01;

                            // 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")

                            while (1)
                            {
                            // Place your code here

                            if (ngat>=10000)
                            {
                            PORTA.0=0;
                            delay_ms(10000);
                            };

                            PORTA.0=1;

                            }

                            }

                            hình mô phỏng chạy ok nè:
                            chưa bật led
                            [ATTACH=CONFIG]62714[/ATTACH]

                            bật led sau 2,7 phút = timmer (muốn sau 2 năm bật led cũng được )
                            [ATTACH=CONFIG]62715[/ATTACH]

                            Phần code mình đánh dấu màu đỏ là quan trọng và mình sẽ giải thích
                            bác giúp e chuơng trình này với,mấy ngày hôm nay mà chưa biết giải quyết cho đúng yêu cầu,em làm nó chạy rồi nhưng vướng mấy chỗ quan trọng nên chưa đạt yêu cầu.yêu cầu là:ấn nút(chỉ có 1 nút) thì bật hệ thống đun,đun đến khi cảm biến nó bật thì ngừng đun và cho motor quay trong 2 phút,quay xong thì dừng toàn bộ hệ thống????

                            Comment


                            • #15
                              Nguyên văn bởi vietran2708 Xem bài viết
                              bác giúp e chuơng trình này với,mấy ngày hôm nay mà chưa biết giải quyết cho đúng yêu cầu,em làm nó chạy rồi nhưng vướng mấy chỗ quan trọng nên chưa đạt yêu cầu.yêu cầu là:ấn nút(chỉ có 1 nút) thì bật hệ thống đun,đun đến khi cảm biến nó bật thì ngừng đun và cho motor quay trong 2 phút,quay xong thì dừng toàn bộ hệ thống????
                              Cũng tương đối đơn giản, dùng 1 Port làm input nhận tín hiệu từ nút nhấn, vi điều khiển phát hiện nút được nhấn thì cho 1 port khác làm output bật hệ thống đun, sau đó cho nhảy vô cái vòng lặp while kiểm tra cái cảm biến cho đến khi phát hiện bật cảm biến thì cho chương trình thoát ra tắt hệ thống đun và cho motor quay trong 2 phút xong rồi cho off toàn bộ chờ tín hiệu nút nhấn để khởi động quá trình lại từ đầu. Vậy thôi, đâu có cần xài timmer ở đây đâu.
                              Lý thuyết suông thì như vậy, mình tránh bàn sâu vảo thực tế vì còn dính dáng nhiều đến động lực, nhiễu, khả năng thiết kế mạch....V..V..
                              Còn bạn nói vướng thì giải trình vướng chỗ nào mọi người giúp cho, đừng quăng cái code dài ngoằng và lộn xộn lên đây nha, chả ai muốn đọc đâu.
                              Last edited by hoahauvn2; 11-08-2014, 11:41.
                              Làm sao mà bạn dám nói là không làm được khi bạn chưa từng thử một lần nào.
                              Ngay cả khi bạn đã làm 1 lần và thất bại bạn cũng không có quyền nói là không làm được vì bạn chưa làm lần thứ 2,3...

                              Comment

                              Về tác giả

                              Collapse

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

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

                              Collapse

                              Đang tải...
                              X