Thông báo

Collapse
No announcement yet.

kiểm tra hộ cách tạo PWM bằng timer1?

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

  • kiểm tra hộ cách tạo PWM bằng timer1?

    Chào mọi người. Mình có 1 câu hỏi cần nhờ các bạn giúp đỡ:
    Mặc dù trong con 16f887 đã có 2 bộ CCPx nhưng mình muốn dùng Timer1 để tạo ra để tạo xung PWM –nhưng vẫn chưa được!
    Yêu cầu:dùng dùng bộ chuyển đổi ADC để xác định mức cao cho xung PWM-dùng Timer1
    Ghi chú:- T_h,T_l là thời gian mức cao và mức thấp của xung PWM
    - thạch anh=12MHz.
    - ADC dùng kênh 1. điện áp tham chiếu 0V và 5V
    - Dùng ngắt timer1 để thay đổi độ rộng xung.
    - Tần số PWM=1khz => T_s=1000us.
    Giải quyết:
    - Do ta dùng bộ adc để tạo T_h cho PWM nên T_h=(giá_trị_đọc_về/1024)*1000
    - tính giá trị mức cao để nạp cho thanh ghi của timer1 mỗi khi có ngắt:
    value_T1=T_h/(1/3)=3*T_h
    Register_T1_h=65534-value_T1.
    - tính giá trị mức thấp để nạp cho thanh ghi của timer1 mỗi khi có ngắt:
    T_l=1000-T_h
    Register_T1_l=65534-(T_l/(1/3))=65534-3*T_l.
    - mình làm như vậy mà sao khi điều chỉnh biến trở mà tần số vẫn không hể thay đổi (chu kì của xung PWM cố định ở 32,29ms chứ kg phải là 1ms)
    Mình có kèm theo file mô phỏng (proteus).
    Mong mọi người giúp đỡ. Chân thành cảm ơn.
    Code:
    #include<16f887.h>
    #device *=16 ADC=10
    #FUSES  NOWDT,HS,NOPUT,NODEBUG,NOPROTECT,NOBROWNOUT,NOLVP,NOCPD,NOWRT
    #include<math.h>
    #use delay(clock=12000000)
    #define  pwm2  59    //pin_c3 ngo ra PWM dung voi T1
    float th1,tl1,value_adc1;
    
    //--------------------------------
    #INT_TIMER1          
    void timer1_isr()         
    {
       if (input_state(pwm2))               
       {
          OUTPUT_BIT(pwm2,0);     
          SET_TIMER1(65534-tl1);
       }
        else
        {
          OUTPUT_BIT(pwm2,1);
          SET_TIMER1(65534-th1);
        }  
    }
    //=================================
    void main()
    {
       unsigned int16 duty_pwm;
       float value_adc0;
    //----------------------------------
       ENABLE_interrupts(INT_TIMER1);   
       ENABLE_interrupts(global);             
       SETUP_TIMER_1(T1_INTERNAL|T1_DIV_BY_1);     
       setup_ccp1(CCP_PWM);                   
       setup_timer_2(T2_DIV_BY_16, 187, 1);   
       setup_adc(ADC_CLOCK_INTERNAL);        
       setup_adc_ports(sAN0|sAN1|VSS_VDD);           
       OUTPUT_BIT(PIN_C3,1);               
       
       SET_ADC_CHANNEL(1);                    
       delay_us(50);                           
       value_adc1=read_adc();                 
       th1=(value_adc1/1024)*1000;        
       tl1=(3*(1000-th1));                
       th1=(th1*3);                  
       SET_TIMER1(65534-th1);        
       while(1)
       {
          SET_ADC_CHANNEL(0);                    
          delay_us(50);                           
          value_adc0=read_adc();                  
          SET_ADC_CHANNEL(1);                    
          delay_us(50);                          
          value_adc1=read_adc();                 
          value_adc0=(value_adc0/1024)*0.001;        
          duty_pwm=ceil((value_adc0*12000000)/16);   
          set_pwm1_duty(duty_pwm);                 
          
          th1=(value_adc1/1024)*1000;         
          tl1=(3*(1000-th1));                 
          th1=(th1*3);                  
       }
    }

  • #2
    huhu, các anh chị làm ơn giúp em với

    Comment


    • #3
      cau hoi de qua hay sao ma kg ai them giup em vay

      Comment


      • #4
        PWM trong vi điều khiển PIC

        sao bạn không dùng timer2 cho tiện, timer2 có thanh ghi chuyên dụng cho tính toán chu kì xung và độ rộng xung.

        :

        Comment


        • #5
          như trên mình có nói là đã có bộ CCPx rồi, nhưng mình muốn thử sức dùng timer1 xem sao!

          Comment


          • #6
            cái này mới nghe. Mình nghĩ dùng timer1 thì chác là PWM thủ công thôi. Chúc bạn thành công

            :

            Comment


            • #7
              Trước mình có nghe một số cao thủ nói là dùng timer để tạo xung thì ko thể đc tần số cao (giới hạn ở mức nào đó). Do còn có phần thời gian header gì đó (khởi tạo, xóa cờ....)
              Trên thực tế tui cũng đã thử nghiệm và cũng thấy là như vậy . cách khắc phục là sử dụng chip mạnh và thạch anh tần số cao thôi

              Comment


              • #8
                Nguyên văn bởi nhanh0112 Xem bài viết
                Trước mình có nghe một số cao thủ nói là dùng timer để tạo xung thì ko thể đc tần số cao (giới hạn ở mức nào đó). Do còn có phần thời gian header gì đó (khởi tạo, xóa cờ....)
                Trên thực tế tui cũng đã thử nghiệm và cũng thấy là như vậy . cách khắc phục là sử dụng chip mạnh và thạch anh tần số cao thôi
                cảm ơn bạn đã quan tâm đến câu hỏi của mình. nhưng mình nghĩ tạo xung có 1Khz thì tần số này cũng đâu có cao lắm đâu! à nếu được bạn có thể nói cụ thể cách làm này được kg?
                mình cảm ơn.

                Comment


                • #9
                  Nguyên văn bởi thanhnguyen0 Xem bài viết
                  cảm ơn bạn đã quan tâm đến câu hỏi của mình. nhưng mình nghĩ tạo xung có 1Khz thì tần số này cũng đâu có cao lắm đâu! à nếu được bạn có thể nói cụ thể cách làm này được kg?
                  mình cảm ơn.
                  theo tui bạn set cho timer tạo ra ngắt nhanh nhất có thể (chắc T ko thể nhỏ hơn 20us, cái này tui chưa thử kỹ lắm nhưng có lần làm đc 60us). Sau đó lấy 1khz/T=> Tổng số lần phải cộng dồn (đây chính là độ phân giải của PWM)
                  Ví dụ: Giả sử 1 lần ngắt là 20us với f=1kHz(T=1000us) vậy tổng số lần sẽ là:1000/20=50 lần
                  Code:
                  #int_timer0 //overflow every 20us
                  void code()
                     {
                     xung++;
                     if(xung>50)xung=0;
                     if(xung<=pwm)
                           output_high(PIN_A1);
                     else
                           output_low(PIN_A1);
                      }
                  bạn chọn giá trị của pwm từ 0-50 sẽ ra đc giá trị PWM tương ứng. Bạn làm cách này xem (tui cũng đã từng làm thử đc rồi). Rảnh tui sẽ xem thử cách của bạn xem sao (chắc độ phân giải sẽ đc cao hơn)

                  Comment


                  • #10
                    Nguyên văn bởi nhanh0112 Xem bài viết
                    theo tui bạn set cho timer tạo ra ngắt nhanh nhất có thể (chắc T ko thể nhỏ hơn 20us, cái này tui chưa thử kỹ lắm nhưng có lần làm đc 60us). Sau đó lấy 1khz/T=> Tổng số lần phải cộng dồn (đây chính là độ phân giải của PWM)
                    ........
                    cảm ơn bạn nhiều lắm.

                    để mình về làm thử lại xem sao. có gì thì cùng trao đổi thêm nhé.

                    chúc bạn vui

                    Comment


                    • #11
                      dùng timer thì hơi phí , tốt nhất là dùng 2 bộ ccp chuyên dùng để tao PWM sẽ tiện lợi hơn
                      Đối thủ mà ta khó chiến thắng nhất chính là bản thân !!!

                      Comment


                      • #12
                        NhÂn ĐÂy cho mÌnh hỎi luÔn nẾu bĂm xung thỦ cÔng nÀy liỆu ĐiỀu khiỂn ĐỘng cƠ cho robocon cÓ dc khÔng cÁc bÁc nhỈ?

                        Comment

                        Về tác giả

                        Collapse

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

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

                        Collapse

                        Đang tải...
                        X