7 Replies Latest reply on Nov 28, 2018 10:06 PM by BoTa_264741

    need design 8bit division on psoc4

      dear FAE, i have a question for design a 8bit division on psoc4, my design is use a counter to count event from the psoc4's pin, and later use DMA to transmit the data to a DAC, but between the counter and DAC, i want to use 0xFF/data, and the quotients transmit to DAC, but i can't find the model which can use on this design, so if you have a good method, the can send it to my email which is keeny.zhao@163.com, i'm in China, thank you for you help.

        • 1. Re: need design 8bit division on psoc4
          MoTa_728816

          Hi,

           

          This is a community so usually answers/replies are supposed to be shared by everyone in the community.

          And if you need to make the information confidential, please submit your technical support request at

          http://www.cypress.com/support

          View MyCases

           

          Now following is a public reply from me.

           

          Reading your question, I assume that the data is also 8bit.

          In case the data is bigger than 0xFF, quotient will be 0, anyway.

           

          First if you are using PSoC Creator, you should be able to use

            quotients = 0xFF/data ; // method1

          except when data == 0,

          in this case you must decide what value to assign or what to do.

          In my example, I treated it just like as data == 1.

           

          Meantime, usually for a MCU, division is rather expensive in terms of CPU cycles,

          if the performance is critical, since it's a handling of a 8bit value,

          I would use a table look-up. (method2)

           

          So I wrote a test program like below

          Note: if you go with method1, you don't need quotient's array.

          ====================================

          #include "project.h"

          #include <stdio.h>

           

          char str[128] ; /* print buffer */

           

          uint8_t quotient[256] = {

          0xFF, 0xFF, 0x7F, 0x55, 0x3F, 0x33, 0x2A, 0x24,

          0x1F, 0x1C, 0x19, 0x17, 0x15, 0x13, 0x12, 0x11,

          0x0F, 0x0F, 0x0E, 0x0D, 0x0C, 0x0C, 0x0B, 0x0B,

          0x0A, 0x0A, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,

          0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,

          0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05,

          0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04,

          0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,

          0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,

          0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,

          0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02,

          0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,

          0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,

          0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,

          0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,

          0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,

          0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,

          0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,

          0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,

          0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,

          0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,

          0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,

          0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,

          0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,

          0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,

          0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,

          0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,

          0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,

          0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,

          0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,

          0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,

          0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01

          } ;

           

          uint8_t method1(uint8_t data)

          {

              uint8_t result = 0 ;

            

              // First what should we do when data == 0?

              // This time I treat it same as data == 1

              if (data == 0) {

                  result = 0xFF ;

              } else {

                  result = 0xFF / data ;

              }

              return( result ) ;

          }

           

          uint8_t method2(uint8_t data)

          {

              return(quotient[data]) ;

          }

           

          void test_method1(void) {

              uint16_t data = 0 ;

              uint8_t quotient ;

            

              for (data = 0 ; data < 0x100 ; data++) {

                  quotient = method1(data) ;

                  sprintf(str, "0x%02X ", quotient) ;

                  UART_UartPutString(str) ;

                  if (((data + 1) % 0x10) == 0) {

                      UART_UartPutString("\n") ;

                  }

              }

              UART_UartPutString("\n") ;

          }

           

          void test_method2(void) {

              uint16_t data = 0 ;

              uint8_t quotient ;

            

              for (data = 0 ; data < 0x100 ; data++) {

                  quotient = method2(data) ;

                  sprintf(str, "0x%02X ", quotient) ;

                  UART_UartPutString(str) ;

                  if (((data + 1) % 0x10) == 0) {

                      UART_UartPutString("\n") ;

                  }

              }

              UART_UartPutString("\n") ;

          }

           

          int main(void)

          {

              CyGlobalIntEnable; /* Enable global interrupts. */

           

              UART_Start() ;

              sprintf(str, "8bit division test (%s %s)\n", __DATE__, __TIME__) ;

              UART_UartPutString(str) ;

           

              UART_UartPutString("Testing Method1\n") ;

              test_method1() ;

            

              UART_UartPutString("Testing Method2\n") ;

              test_method2() ;

            

              for(;;)

              {

                  /* Place your application code here. */

              }

          }

          ====================================

           

          The result TeraTerm log

          div_test_181125.JPG

           

          Attached is my sample for CY8CKIT-044.

           

          moto

          • 2. Re: need design 8bit division on psoc4

            Hi

               i am very happy to receive you mail, in you design, you use MCU to deal with, but in my design, i want use hardware to design, for this it is real time for my design, so need a hardware divider, thx.

             

             

            Best regards

            Kenny

            086-13885725077

            • 3. Re: need design 8bit division on psoc4
              MoTa_728816

              Dear Kenny-san,

               

              That was my point, too.

               

              So my method2 is, IMHO, as fast as hardware divider,

              since it's a table look up.

               

              moto

              • 4. Re: need design 8bit division on psoc4

                Hi, Motoo

                    Ok, i understand you mean, for my design, i will use analog hardware divider to design outside the Psoc, and this not need MCU to deal with, thank you.

                 

                 

                 

                Best regards

                Kenny

                086-13885725077

                • 5. Re: need design 8bit division on psoc4
                  BoTa_264741

                  Kenny,

                  As I understand, the project counts pulses (e.g. RPM speed), but the output needed is inverse (e.g. time period). This can be easily accomplished using Timer component to measure period (time intervals between pulses) directly. Timer output can be DMA transferred to VDAC directly, no 1/n conversion required.

                  /odissey1

                  • 6. Re: need design 8bit division on psoc4

                    Hi

                      my design is using counter to count the system clock every pulse from the motor encoder, such as, my system clock is 250K, encoder is 1000 per rev, if motor in 60rpm, encoder is 1k frequency, so counter data is 250K/1k=250, DAC output voltage is 2500.612(current)6.5(resistance)/255=3.9v, if motor in 15000rpm, encoder is 250k, counter data is 250K/250K=1, DAC V=10.6126.5/255=0.0156V, but this design is invert for me, i hope 60rpm my output is 0.0156V, and 15000rmp is 3.9V, and the voltage must be linear, so i need a hardware divider to deal with data as this divider data=255/(counter data), and use DMA to transmit divider data to DAC

                     

                     

                    Best regards

                    Kenny

                    086-13885725077

                    • 7. Re: need design 8bit division on psoc4
                      BoTa_264741

                      Kenny,

                      Now, with the encoder example, the subject is more clear . My suggestion is to inverse counting: instead of counting 250k clock per encoder period, count encoder pulses fer fixed period. For example, lets set a timer period 1ms and count pulses from encoder per each 1ms interval. At 60RPM (1Hz x 1000 = 1kHz), there will be 1kHz x 1ms =1 count per period; and at 15000RPM  (250Hz x 1000 = 250kHz), the amount of counts is 250kHz x 1ms = 250.

                       

                      Due to rotor inertia the motor control doesn't need such fast measurement, so using longer interval time (32-128 ms) should suffice, which is also improves reading accuracy. The final result can be obtained by simply shifting down the result by 5-7 bits.

                      /odissey1