need design 8bit division on psoc4

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

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.

0 Likes
1 Solution

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 

View solution in original post

0 Likes
7 Replies
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

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

0 Likes
Anonymous
Not applicable

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

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

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

0 Likes
Anonymous
Not applicable

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

0 Likes

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

0 Likes
Anonymous
Not applicable

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

0 Likes

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 

0 Likes