CCS C cho PIC/dsPIC phiên bản 4.xxx

Collapse
This is a sticky topic.
X
X
 
  • Giờ
  • Show
Clear All
new posts
  • ngtdung.nguyen
    Nhập môn đệ tử
    • Jun 2008
    • 1

    #46
    Em dùng Wizard của CCS 4.065, tạo chương trình xuất xung PWM cho PIC6F877A như sau:
    (mục đích là tần số điều xung= 10kHz, 2 xung độ rộng 30% và 80%)

    #include "F:\TRANNING-PIC\PWM.H"

    void main()
    {
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
    setup_timer_1(T1_DISABLED);
    setup_timer_2(T2_DIV_BY_4,124,1); //tần số PWM = 10kHz
    setup_ccp1(CCP_PWM);
    setup_ccp2(CCP_PWM);
    set_tris_c(0x00);
    set_pwm1_duty(150); // độ rộng xung 30%
    set_pwm2_duty(400); // độ rộng xung 80%
    setup_comparator(NC_NC_NC_NC);
    setup_vref(FALSE);

    while (1);
    }

    Mô phỏng bằng Proteus 7.2 cho thấy xung ra bị sai, cả về tần số và độ rộng xung
    (xin lỗi các bác em chưa biết cách post hình lên)

    Khi cài lại duty cycle, thì mô phỏng cho thấy xung ra đúng:

    set_pwm1_duty(37);
    set_pwm2_duty(100);


    2 trường hợp này sai lệch nhau ở hệ số nhân 4 là hệ số chia tần đưa vào timer2.
    Em đọc Data sheet thấy trường hợp 1 do CCS tự tính giá trị value là hợp với miêu tả về PWM. Tuy nhiên mô phỏng thấy sai.

    Em có mạch chạy PIC tuy nhiên không có Oscilocope nên không biết thực tế ra sao.
    Em không biết đây là do CCS sai hay do Proteus mô phỏng sai.

    Mong các bác giải đáp giúp em với. Em xin cám ơn.

    Comment

    • tungtuantu
      Đệ tử 3 túi
      • Apr 2006
      • 54

      #47
      em rât mong bác nào có tàiliệu hướng dẫn dùng CCS cho DsPIC cả anh lẫn việt cũng được, post lên cho anh em với, bác nào chỉ bảo luôn dùng phiên bản nào đầy đủ của CCS để lập trình cho DSPIC với

      Comment

      • picpen
        Đệ tử 5 túi
        • Jun 2008
        • 112

        #48
        a ha. ccs ko sai và protues cũng chẳng có vấn đề gì đâu, mà vấn đề nằm ở hai thông số : period ( 124 ) và giá trị value(400) trong lệnh set_pwmx_duty(value)
        thứ nhất : 2 giá trị period và value phải nằm trong khoảng : 0..255
        thứ hai : khi bạn điều xung như trên thì giá trị : value luôn phải < period ( nếu value = period thì tần số bạn thu được sẽ =0 , nếu value > period thì xung ra là trùm xung ko như bạn tính toán )
        Bạn đọc kỹ lại về cấu tạo và hoạt động của bộ tham 2 cũng như khối PWM
        ***** chúc thành công ********
        ** xin hãy cho tôi là tượng đá
        ** Để muôn đời không nhớ thương ai ..!!

        Comment

        • dungnt7
          Nhập môn đệ tử
          • Aug 2007
          • 9

          #49
          Nguyên văn bởi picpen View Post
          a ha. ccs ko sai và protues cũng chẳng có vấn đề gì đâu, mà vấn đề nằm ở hai thông số : period ( 124 ) và giá trị value(400) trong lệnh set_pwmx_duty(value)
          thứ nhất : 2 giá trị period và value phải nằm trong khoảng : 0..255
          thứ hai : khi bạn điều xung như trên thì giá trị : value luôn phải < period ( nếu value = period thì tần số bạn thu được sẽ =0 , nếu value > period thì xung ra là trùm xung ko như bạn tính toán )
          Bạn đọc kỹ lại về cấu tạo và hoạt động của bộ tham 2 cũng như khối PWM
          ***** chúc thành công ********
          Theo mình biết thì giá trị value được biểu diễn bằng 10bit, giá trị lớn nhất của value là 1024.

          Value không phải lúc nào cũng nhỏ hơn period, theo datasheet thì (pwm_duty/pwm_period)=(value/(4*(tmr2+1))).

          Đoạn chương trình sau xuất xung PWM 50%, f=5Khz, ở chân CCP1
          void main()
          {
          setup_timer_1(T1_DISABLED);
          setup_timer_2(T2_DIV_BY_4,249,1);
          setup_ccp1(CCP_PWM);
          set_pwm1_duty(512);
          set_tris_c(0x00);
          }


          Vấn đề của bạn ngtdung.nguyen mình cũng chưa hiểu vì sao bị như vậy.
          Last edited by dungnt7; 26-07-2008, 10:46 PM.

          Comment

          • cong1810
            Đệ tử 4 túi
            • Sep 2007
            • 62

            #50
            Nguyên văn bởi ngtdung.nguyen View Post
            Em dùng Wizard của CCS 4.065, tạo chương trình xuất xung PWM cho PIC6F877A như sau:
            (mục đích là tần số điều xung= 10kHz, 2 xung độ rộng 30% và 80%)

            #include "F:\TRANNING-PIC\PWM.H"

            void main()
            {
            setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
            setup_timer_1(T1_DISABLED);
            setup_timer_2(T2_DIV_BY_4,124,1); //tần số PWM = 10kHz
            setup_ccp1(CCP_PWM);
            setup_ccp2(CCP_PWM);
            set_tris_c(0x00);
            set_pwm1_duty(150); // độ rộng xung 30%
            set_pwm2_duty(400); // độ rộng xung 80%
            setup_comparator(NC_NC_NC_NC);
            setup_vref(FALSE);

            while (1);
            }

            Mô phỏng bằng Proteus 7.2 cho thấy xung ra bị sai, cả về tần số và độ rộng xung
            (xin lỗi các bác em chưa biết cách post hình lên)

            Khi cài lại duty cycle, thì mô phỏng cho thấy xung ra đúng:

            set_pwm1_duty(37);
            set_pwm2_duty(100);


            2 trường hợp này sai lệch nhau ở hệ số nhân 4 là hệ số chia tần đưa vào timer2.
            Em đọc Data sheet thấy trường hợp 1 do CCS tự tính giá trị value là hợp với miêu tả về PWM. Tuy nhiên mô phỏng thấy sai.

            Em có mạch chạy PIC tuy nhiên không có Oscilocope nên không biết thực tế ra sao.
            Em không biết đây là do CCS sai hay do Proteus mô phỏng sai.

            Mong các bác giải đáp giúp em với. Em xin cám ơn.

            mình cũng mới tìm hiểu về PIC và PWM!
            vần đề của bạn là ở chỗ duty(150) và 400. đó là 150 là 1 số int còn 400 là số long int.cái này được đề cập trong VDu PWM của CCS c.nếu là duty là số int thì công thức tính: value=4*duty/clock*t2div.
            nếu là số long int thì value=duty/clock*t2div.
            thân!!

            Comment

            • cong1810
              Đệ tử 4 túi
              • Sep 2007
              • 62

              #51
              các bác cho em hỏi.em viết 1 đoạn code PWM nhỏ và mô phỏng.
              lúc để value là hằng số thì mô phỏng đúng.
              còn để value là biến số thì mô phỏng ko chạy gì hết.em mất cả buổi mà ko biết tại sao?
              các sư huynh chỉ giáo!!em dùng 1 phím nhấn để tăng duty!!

              Code:
              #include<16f877a.h>
              #fuses XT,NOPROTECT,NOLVP,NOWDT
              #use delay(clock=4000000)
              #byte portb=0x06
              int8 value=0,period=200,percent=0;
              #int_RB
              void inter_RB()
              {
              if(percent==100)
                 {
                 percent=100;
                 }
              else
                {
                percent=percent+5;
                } 
              }
              main()
              {
              set_tris_c(0x00);
              set_tris_b(0b00010000);
              portb=0x00;
              enable_interrupts(INT_RB);
              enable_interrupts(global);
              ext_int_edge(l_to_h);
              setup_CCP1(CCP_PWM);
              setup_timer_2(t2_div_by_1,199,1);
              
              while(1)
              {
               value=percent*period/100; 
                set_pwm1_duty(value);
              }
              }
              Last edited by namqn; 11-08-2008, 05:55 PM.

              Comment

              • vietkhanh
                Nhập môn đệ tử
                • Mar 2007
                • 2

                #52
                cho em hỏi tí các anh sao khi em viết chương trình nào mà có dùng thư viện LCD của CCS thì đều bị lỗi khi biên dịch ạ,có hình đính kèm.
                Attached Files

                Comment

                • cong1810
                  Đệ tử 4 túi
                  • Sep 2007
                  • 62

                  #53
                  vấn đề là ở file chính.còn file lcd.c hoàn toàn đúng.

                  Comment

                  • picpen
                    Đệ tử 5 túi
                    • Jun 2008
                    • 112

                    #54
                    Cong1810 ! Mình nghĩ biểu thức bạn dùng để tính giá trị value ko ổn ," value=percent*period/100; " , 3 biến value,percent,period bạn đều định nghĩa dạng INT8 ,vậy khi chương trình thực hiện biểu thức nó sẽ làm phép nhân trước " percent*period " ,giá trị của phép nhân này có thể lớn hơn 8 bit ( thường phải lưu vào biến 16 bit) ,nếu giá trị này lưu vào biến 8 bit nó có thể bị tràn và dẫn tới kết quả tính toán bị sai .
                    Mình thấy đoạn khai báo chương trình chính của bạn sai cú pháp : phải là , VOID main() ( thiếu VOID nha )
                    ** xin hãy cho tôi là tượng đá
                    ** Để muôn đời không nhớ thương ai ..!!

                    Comment

                    • namqn
                      Trưởng lão PIC bang
                      • Feb 2006
                      • 3020

                      #55
                      Với C (kiểu dữ liệu của CCS C), bạn có thể viết tổng quát như sau:
                      Code:
                      	value = (int16 (percent*period))/100;
                      Trong trường hợp cụ thể mà bạn dùng để thử xem nút nhấn có thay đổi được duty cycle hay không, period = 200, do đó có thể viết gọn lại là:
                      Code:
                      	value = percent*2;
                      sẽ không xảy ra tràn số đối với value.

                      Thân,
                      Biển học mênh mông, sức người có hạn.

                      Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau:
                      http://www.picvietnam.com/forum/showthread.php?t=1263

                      Comment

                      • cong1810
                        Đệ tử 4 túi
                        • Sep 2007
                        • 62

                        #56
                        Nguyên văn bởi picpen View Post
                        Cong1810 ! Mình nghĩ biểu thức bạn dùng để tính giá trị value ko ổn ," value=percent*period/100; " , 3 biến value,percent,period bạn đều định nghĩa dạng INT8 ,vậy khi chương trình thực hiện biểu thức nó sẽ làm phép nhân trước " percent*period " ,giá trị của phép nhân này có thể lớn hơn 8 bit ( thường phải lưu vào biến 16 bit) ,nếu giá trị này lưu vào biến 8 bit nó có thể bị tràn và dẫn tới kết quả tính toán bị sai .
                        Mình thấy đoạn khai báo chương trình chính của bạn sai cú pháp : phải là , VOID main() ( thiếu VOID nha )
                        ừ nhỉ.mình ko để ý đến việc này.
                        cái void main.mình thấy ko có void nó vẫn hoạt động bình thường mà!!
                        nhưng mà mình sửa như bạn và anh namqn nói.mô phỏng vẫn ko chạy.
                        nhưng khi đổi sang ngắt ngoài thì ok!!
                        vậy tại sao vậy nhỉ!!

                        Comment

                        • picpen
                          Đệ tử 5 túi
                          • Jun 2008
                          • 112

                          #57
                          Số thực với LCD &amp; Led7seg....

                          Khi mới học lập trình thì những bài toán giao tiếp với LCD và led 7 thanh là rất cơ bản và đơn giản.
                          Vậy mà đã học được 1 thời gian rùi nay mình lại bị mắc một bài toán : " Hiển thị giá trị số thực lên LCD và Led 7 thanh "
                          Nhờ các bá cao thủ trên diễn đàn chỉ giáo, ko biết làm thế nào để xác định giá trị trong một biến là số thực hay số nguyên ??? Rồi lại còn phải tách phần nguyên và phần thập phân nữa chứ ....... hóc búa quá .** Mong được mọi người chỉ giáo ...thank ****
                          ** xin hãy cho tôi là tượng đá
                          ** Để muôn đời không nhớ thương ai ..!!

                          Comment

                          • picpen
                            Đệ tử 5 túi
                            • Jun 2008
                            • 112

                            #58
                            trả lời cong810

                            Cong810 ! mình đã load bài của bạn về và chỉnh sửa 1 chút xíu, và giờ thì nó chạy ngon lành rùi, bạn bị mắc một lỗi rất nhỏ lên khó phát hiện ra khi chỉnh sửa.
                            Khi chương trình nhảy đến trình phục vụ ngắt Rb,nó sẽ thực hiện các câu lệnh trong đó,bạn dùng chân Rb4 để thực hiện phục vụ ngắt,nếu trong trình phục vụ ngắt bạn kiểm tra xem Rb4 có =1 ko, nếu =1 thì thực hiện việc thay đổi giá trị biến " percent " ,nếu ko thoát khỏi trình phục vụ ngắt ,như vậy chương trình sẽ chạy ngon lành
                            đây là chương trình mình đã sử và cho chạy mo fong được rồi

                            Code:
                            ...#include<16f877a.h>
                            #fuses XT,NOPROTECT,NOLVP,NOWDT
                            #use delay(clock=4000000)
                            #byte portb=0x06
                            int8 value=0,period=200,percent=0;
                            #int_RB
                            void inter_RB()
                            {
                            if( rb4 =1)       // phai kiem tra Rb4 nhe 
                               {   
                                  if(percent==100)percent=100;
                                     
                                  else percent=percent+5;
                               }    
                            }
                            main()
                            {
                            set_tris_c(0x00);
                            set_tris_b(0b00010000);
                            portb=0x00;
                            enable_interrupts(INT_RB);
                            enable_interrupts(global);
                            ext_int_edge(l_to_h);
                            setup_CCP1(CCP_PWM);
                            setup_timer_2(t2_div_by_1,199,1);
                            
                            while(1)
                            {
                             value=percent*period/100; 
                              set_pwm1_duty(value);
                            }
                            }
                            Last edited by picpen; 16-08-2008, 11:17 PM.
                            ** xin hãy cho tôi là tượng đá
                            ** Để muôn đời không nhớ thương ai ..!!

                            Comment

                            • picpen
                              Đệ tử 5 túi
                              • Jun 2008
                              • 112

                              #59
                              có ai biết thì giúp mình giải quyết vấn đề : Hiển thị giá trị số thực lên LCD và led 7 thanh với *********** thank ***********
                              ** xin hãy cho tôi là tượng đá
                              ** Để muôn đời không nhớ thương ai ..!!

                              Comment

                              • picpen
                                Đệ tử 5 túi
                                • Jun 2008
                                • 112

                                #60
                                Mòn mỏi đợi chờ ,ý kiến góp ý ,gợi ý giúp đỡ chỉ giáo của anh em trong gia đình pic mà ko có ai quan tâm giúp đỡ hic ... hic ... Chắc câu hỏi của mình chuối quá hay thiếu " I ỐT " ko biết nữa..hic ...hic
                                ** xin hãy cho tôi là tượng đá
                                ** Để muôn đời không nhớ thương ai ..!!

                                Comment

                                Working...