Giải thích code cho dsPIC

Collapse
X
 
  • Giờ
  • Show
Clear All
new posts
  • nvtri
    Nhập môn đệ tử
    • Jun 2008
    • 9

    #1

    Giải thích code cho dsPIC

    Code:
    unsigned char InData[] = {"000000"};
    unsigned char OutData[] = {"Speed = 00000 rpm\r\n"};
    void SendSpeed()
    {
    unsigned int k;
    unsigned char c;
       
       k = SPEEDMULT/timer3avg;
       c = k/10000;
       if (c > 0)
          k = k - c*10000;
       OutData[OFFSET] = (c + 0x30);
       c = k/1000;
       if (c > 0)
          k = k - c*1000;
       OutData[OFFSET+1] = (c + 0x30);
       c = k/100;
       if (c > 0)
          k = k - c*100;
       OutData[OFFSET+2] = (c + 0x30);
       c = k/10;
       if (c > 0)
          k = k - c*10;
       OutData[OFFSET+3] = (c + 0x30);
       OutData[OFFSET+4] = (char)(k + 0x30);
       TXPtr = &OutData[0];
       SendMsg();
       Flags.CalSpeed = 0;
    }
    trong đó với SPEEDMULT là 4, timer3avg là giá trị đọc từ timer3
    Mình chưa hiểu rõ đoạn code trên gửi giá trị vận tốc động cơ như thế nào, mong anh Nam và mọi người giải thích giúp mình ý nghĩa đoạn code này.
    Last edited by namqn; 01-01-2009, 08:17 PM.
  • namqn
    Trưởng lão PIC bang
    • Feb 2006
    • 3020

    #2
    Giả sử k là tốc độ tính bằng rpm, đoạn code trên chỉ chuyển giá trị của k thành một chuỗi ký tự ASCII và đặt vào vị trí tương ứng ("00000") trong bộ đệm OutData[] để được truyền đi.

    Vì k là một số 16-bit, nên nó chỉ mang giá trị tối đa là 65535, tức là có tối đa 5 chữ số thập phân. Đoạn code trên chỉ lần lượt tách các chữ số hàng chục ngàn, hàng ngàn, hàng trăm, hàng chục, và hàng đơn vị để đưa vào bộ đệm OutData[].

    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

    • nvtri
      Nhập môn đệ tử
      • Jun 2008
      • 9

      #3
      Giải thích code cho dsPIC

      Cảm ơn anh Nam, em đã hiểu cách gửi dữ liệu của đoạn code trên rồi, nhưng em còn thắc mắc một số vấn đề sau:
      +)Thứ nhất: SPEEDMULT=60*(Fcy/256); // sẽ bằng 2343750 với Fcy=10 Mhz
      k=SPEEDMULT/timer3avg;
      Thì sao k có vận tốc là (vòng/phút), mong anh giải thích, cái này em xem trong code của microchip về điều khiển động cơ BLDC. (lúc nãy em post lộn SPEEDMULT=4).
      +)Thứ nhì: Số 0x30 là bắt đầu của vùng nhớ nào?

      Comment

      • love_ac
        Đệ tử 4 túi
        • Apr 2008
        • 78

        #4
        --về điều khiển BLDC thì mình chưa làm nên sẽ vẫn nhờ anh Nam giúp cho câu thứ nhất
        --Còn câu thứ hai của bạn thì :0x30 không phải là nói đến vùng nhớ,mà nó chỉ là sự hiệu chỉnh thành mã ASCII thôi.Bạn không hiểu mã ascii à.

        Comment

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

          #5
          Nguyên văn bởi nvtri View Post
          Cảm ơn anh Nam, em đã hiểu cách gửi dữ liệu của đoạn code trên rồi, nhưng em còn thắc mắc một số vấn đề sau:
          +)Thứ nhất: SPEEDMULT=60*(Fcy/256); // sẽ bằng 2343750 với Fcy=10 Mhz
          k=SPEEDMULT/timer3avg;
          Thì sao k có vận tốc là (vòng/phút), mong anh giải thích, cái này em xem trong code của microchip về điều khiển động cơ BLDC. (lúc nãy em post lộn SPEEDMULT=4).
          +)Thứ nhì: Số 0x30 là bắt đầu của vùng nhớ nào?
          Thứ nhất: Tôi cũng không rõ vì sao k tính bằng vòng/phút, vì bạn không cho biết người ta tính timer3avg ra sao. Do đó, tôi chỉ giả sử rằng k tính bằng vòng/phút, dựa vào cách tổ chức thông điệp trong bộ đệm OutData[] (có cụm từ "rpm").

          Thứ hai: 0x30 là mã ASCII của ký tự '0'. Nếu bạn tính ra giá trị của chữ số thập phân là x, thì x + 0x30 sẽ chuyển nó thành ký tự tương ứng với giá trị của x. Ví dụ, x = 5 thì x + 0x30 sẽ cho bạn ký tự '5', có thể hiển thị được trên các màn hình sử dụng mã ASCII.

          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

          • nvtri
            Nhập môn đệ tử
            • Jun 2008
            • 9

            #6
            Giải thích code cho dsPIC

            Cảm ơn anh Nam và mong anh tiếp tục đọc chủ đề của em
            Cách tính giá trị timer3avg như sau:
            Code:
             #define INDEX 1
             #define POLEPAIRS   5   // động cơ BLDC có 5 cặp cực
             unsigned int HallValue;
             unsigned int timer3value;
             unsigned int timer3avg;
             unsigned char polecount; // dùng để đếm số cặp cực
             
               if (HallValue == INDEX)  // has the same position been sensed?
                  if (polecount++ == POLEPAIRS)   //has one mech rev elasped?
                  {                        // yes then read timer 3
                  timer3value = TMR3;
                  TMR3 = 0;
                  timer3avg = ((timer3avg + timer3value) >> 1);
                  polecount = 1;
                  }
            Em khai báo chỉ số INDEX là 1 để chỉ vị trí đầu tiên của cảm biến Hall, lệnh if thứ hai là để xem động cơ quay được 1 vòng hay chưa (đếm đủ 5 cặp cực tương ứng cho 1 vòng). Sau đó đọc giá trị của Timer3. Tóm lại, đoạn code trên là đọc giá trị Timer3 sau mỗi lần động cơ quay được một vòng.
            Trong đó, với module Timer3 em khởi tạo như sau:
            Code:
            void InitTMR3(void)
            {
               T3CON = 0x0030;         // internal Tcy/256 clock
               TMR3 = 0;
               PR3 = 0xFFFF;
            }
            Tần số thực thi lệnh Fcy = 10 Mhz
            Cho em hỏi thêm: Với cấu hình thanh ghi T3CON = 0x0030 thì thanh ghi TMR3 tăng lên một đơn vị sẽ tốn 256 chu kì lệnh?
            Last edited by namqn; 02-01-2009, 05:41 PM.

            Comment

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

              #7
              Như vậy, Timer 3 sẽ đo thời gian của một vòng quay của trục động cơ. Gọi count_TMR3 là số đếm của Timer 3 tương ứng với một vòng quay. Tốc độ của động cơ được tính như sau:

              Tốc độ = 1/(count_TMR3*256*Tcy) (vòng/giây) = 60/(count_TMR3*256*Tcy) (vòng/phút)

              Với Tcy là thời gian của một chu kỳ thực thi lệnh (Tcy = 1/Fcy), và Timer 3 chỉ tăng một đơn vị sau mỗi 256 Tcy vì bạn thiết lập T3CON = 0x0030.

              Như vậy,

              Tốc độ = 60/(count_TMR3*256/Fcy) = (60*Fcy/256)/(count_TMR3) (vòng/phút)

              Với Fcy = 10 MHz = 10^7,

              Tốc độ = 2343750/(count_TMR3) (vòng/phút)

              Đây là công thức đã được dùng trong đoạn code mẫu của AN957.

              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

              • nvtri
                Nhập môn đệ tử
                • Jun 2008
                • 9

                #8
                Giải thích code cho dsPIC

                Cảm ơn anh Nam, em làm động cơ chạy rồi, gửi được tốc độ lên máy tính, bây giờ em đang cần gửi tốc độ từ máy tính xuống và động cơ sẽ quay đúng số vòng như vậy? có gì em se hỏi anh tiếp.

                Comment

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

                  #9
                  Nguyên văn bởi nvtri View Post
                  Cảm ơn anh Nam, em làm động cơ chạy rồi, gửi được tốc độ lên máy tính, bây giờ em đang cần gửi tốc độ từ máy tính xuống và động cơ sẽ quay đúng số vòng như vậy? có gì em se hỏi anh tiếp.
                  Dưới bài viết của các thành viên đều có nút "Cảm ơn" để bạn thể hiện lòng biết ơn với một bài viết có ích cho bạn. Diễn đàn cũng có quy định là nếu chỉ muốn cám ơn bài viết thì dùng nút này thay cho việc viết một bài cảm ơn không có nội dung.

                  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

                  • nvtri
                    Nhập môn đệ tử
                    • Jun 2008
                    • 9

                    #10
                    giải thích code cho dsPIC

                    Đây là đoạn code để PIC nhận dữ liệu từ máy tính (từ VB truyền xuống)
                    Code:
                    float Kps=0; 
                    float Kis=0; 
                    float Kds=0; 
                    unsigned char InData[]
                    void getvalue()
                    {
                       char hs_vel[4];   // vận tốc là số có 4 chữ số
                       int len_vel;
                       char hs_kp[8];    // hệ số Kp là số có 8 chữ số
                       int len_kp;
                       char hs_ki[8];    // 8 chữ số
                       int len_ki;
                       char hs_kd[8];  // 8 chữ số
                       int len_kd;
                       unsigned char InData[28];  // tổng cộng chuỗi có 28 chữ số
                       int i;
                         for (i=0;i<28;i++)
                          InData[i]=getc();
                          
                       for (len_vel=0;len_vel<4;len_vel++)
                       {   
                          hs_vel[len_vel]=InData[len_vel];
                          //putc(hs_vel[len_vel]);
                       }   
                       for (len_kp=0;len_kp<8;len_kp++)
                       {  
                         hs_kp[len_kp]=InData[len_kp+4];
                         //putc(hs_kp[len_kp]); 
                       }
                       for (len_ki=0;len_ki<8;len_ki++)
                       {   
                          hs_ki[len_ki]=InData[len_ki+12];
                          //putc(hs_ki[len_ki]);
                       }      
                       for (len_kd=0;len_kd<8;len_kd++)
                       {
                          hs_kd[len_kd]=InData[len_kd+20];
                          //putc(hs_kd[len_kd]);
                       }      
                       
                       DesiredSpeed = atol(hs_vel); //vận tốc yêu cầu
                       Kps = atof(hs_kp);
                       Kis =  atof(hs_ki);
                       Kds = atof(hs_kd);
                    }
                    Trong hàm main em gọi hàm getsvalue();
                    Nhưng khi biên dịch chương trình bị lỗi sau:
                    c:\program files\microchip\mplab c30\bin\bin\pic30-coff-ld.exe Error: A heap is required, but has not been specified
                    ClosedLoopSenBLDC.o(.text+0xbe): In function `main':
                    C:\Documents and Settings\NVTRI_HCMUT\Desktop\ClosedLoop\ClosedLoop SenBLDC.c:131: undefined reference to `getvaule'
                    Link step failed. // lỗi link step này là gi vậy
                    BUILD FAILED: Sat Jan 03 12:48:58 2009
                    Mong anh Nam và mọi người giúp đỡ.
                    Last edited by namqn; 03-01-2009, 01:14 AM.

                    Comment

                    • nvtri
                      Nhập môn đệ tử
                      • Jun 2008
                      • 9

                      #11
                      Giải thích code cho dsPIC

                      Trong đó module U2ART được khởi tạo như sau:
                      Code:
                      void InitUART(void)
                      { 
                       U2MODE = 0x8000;
                       U2STA = 0x0000;
                       U2BRG = ((FCY/16)/BAUD) - 1;   // set baud to 19200
                       IEC1bits.U2RXIE = 1;         // enable RX interrupt
                       RXPtr = &InData[0];      // con trỏ chỉ đến kí tự đầu tiên trong bộ đệm nhận
                       Flags.CheckRX = 0;         // Xóa cờ rx and tx 
                       Flags.SendTX = 0;
                       U2STAbits.UTXEN = 1;           // Initiate transmission
                      }
                      void _ISR _U2TXInterrupt(void)
                      {
                         IFS1bits.U2TXIF = 0;   // xóa cờ ngắt
                      }
                      
                      void _ISR _U2RXInterrupt(void)
                      {
                         IFS1bits.U2RXIF = 0;   //xóa cờ ngắt
                         *RXPtr = U2RXREG;
                         if (*RXPtr == CR)
                            {Flags.CheckRX = 1;RXPtr = &InData[0];}
                         else *RXPtr++;
                      }
                      Last edited by namqn; 03-01-2009, 01:12 AM.

                      Comment

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

                        #12
                        Nguyên văn bởi nvtri View Post
                        Đây là đoạn code để PIC nhận dữ liệu từ máy tính (từ VB truyền xuống)
                        ...
                        Trong hàm main em gọi hàm getsvalue();
                        Nhưng khi biên dịch chương trình bị lỗi sau:
                        c:\program files\microchip\mplab c30\bin\bin\pic30-coff-ld.exe Error: A heap is required, but has not been specified
                        ClosedLoopSenBLDC.o(.text+0xbe): In function `main':
                        C:\Documents and Settings\NVTRI_HCMUT\Desktop\ClosedLoop\ClosedLoop SenBLDC.c:131: undefined reference to `getvaule'
                        Link step failed. // lỗi link step này là gi vậy
                        BUILD FAILED: Sat Jan 03 12:48:58 2009
                        Mong anh Nam và mọi người giúp đỡ.
                        Về lỗi liên quan đến heap, bạn xem post #18 của luồng sau: http://www.picvietnam.com/forum/showthread.php?p=2676

                        Theo tôi, trong main() bạn có gọi đến một hàm tên là getvaule(), vốn là một lỗi đánh máy (vì bạn chỉ định nghĩa hàm getvalue()), cho nên mới nhận được thông báo lỗi về tham chiếu chưa được định nghĩa.

                        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

                        • denhutech
                          Nhập môn đệ tử
                          • Jan 2010
                          • 1

                          #13
                          ban nvtri hien minh dang lam do an tot nghep ve dong co BLDC ma chua goi toc do len duoc ban cho minh xin doan code cua ban dc ko.thank mail cua minh tiengchuong_tinh89@yahoo.com

                          Comment

                          • untilyou_92
                            Nhập môn đệ tử
                            • Oct 2012
                            • 6

                            #14
                            Nguyên văn bởi nvtri View Post
                            Trong đó module U2ART được khởi tạo như sau:
                            Code:
                            void InitUART(void)
                            { 
                             U2MODE = 0x8000;
                             U2STA = 0x0000;
                             U2BRG = ((FCY/16)/BAUD) - 1;   // set baud to 19200
                             IEC1bits.U2RXIE = 1;         // enable RX interrupt
                             RXPtr = &InData[0];      // con trỏ chỉ đến kí tự đầu tiên trong bộ đệm nhận
                             Flags.CheckRX = 0;         // Xóa cờ rx and tx 
                             Flags.SendTX = 0;
                             U2STAbits.UTXEN = 1;           // Initiate transmission
                            }
                            void _ISR _U2TXInterrupt(void)
                            {
                               IFS1bits.U2TXIF = 0;   // xóa cờ ngắt
                            }
                            
                            void _ISR _U2RXInterrupt(void)
                            {
                               IFS1bits.U2RXIF = 0;   //xóa cờ ngắt
                               *RXPtr = U2RXREG;
                               if (*RXPtr == CR)
                                  {Flags.CheckRX = 1;RXPtr = &InData[0];}
                               else *RXPtr++;
                            }
                            nvtri mình cũng đang làm đồ án về điều khiển động cơ BLCD giao tiếp PC bạn có thể gửi cho mình project của bạn đc k!! mail của mình nguyenvanthangk55@gmail.com thank bạn trước

                            Comment

                            Working...