You are here

PSOC4 HOW TO USE UART SEND DATA | Cypress Semiconductor

PSOC4 HOW TO USE UART SEND DATA

Summary: 10 Replies, Latest post by lsw on 13 Jun 2017 07:33 PM PDT
Verified Answers: 1
Last post
Log in to post new comments.
lsw
lsw's picture
User
8 posts

PSOC4 HOW TO USE UART SEND DATA?

when i send data more than TX buffer size(8),there are some problem.Because my LED is abnormal .

I want to use uart send 12(frame) data,and receive 10(frame) data.

but External Interrupt must set tx/rx Buffers size  8 can be use.

when i to use uart send 8(frame) data,and receive 8(frame) data,there is no problem to use External Interrupt.And the UART IS OK.

So i think clear TX buffer may be ok.

but it only send wrong data to PC.How to fix it?What is the difference between External Interrupt and Internal Interrupt?

MCU CY8C4125 as a master.when it send data,Slaver  MCU response.The following is my program.

CY_ISR(MY_UART_ISR);

void Init_UART(void)
{
    /* Start SCB (UART mode) operation */
    UART_1_Start();
    UART_1_SCB_IRQ_StartEx(MY_UART_ISR);
}

CY_ISR(MY_UART_ISR)
{
    if (UART_1_GetRxInterruptSourceMasked() & UART_1_INTR_RX_NOT_EMPTY)
    {
        Deal_UartRX();
    }
    UART_1_SpiUartClearRxBuffer();
    UART_1_ClearRxInterruptSource(UART_1_INTR_RX_NOT_EMPTY);

}

void Deal_UartTX(void)  //20ms once
{

…………

UART_1_SpiUartPutArray(&UartTXData[0], 8);

UART_1_SpiUartClearTxBuffer();

UART_1_SpiUartPutArray(&UartTXData[8], 4);

}

 

 

user_1377889's picture
User
10803 posts

When you send more data than the Tx buffer can hold, the call will wait (block) until all data fits into the buffer.

The internal interrupt provides software that handles the transfer from an to the receive and transmit buffer automatically. I do suggest using this algorithms as they are easy to use and are error free ( opposed to my algorithms ;-). Use a reasonable buffer size as 100 to 200 bytes for Rx and Tx. Use the GetRxBufferSize() APIs to check for the number of bytes still in buffer or GetTxBufferSize() to see if a transfer is complete. There is no need to clear the buffers manually. The external interrupt will need you to supply an interrupt handler that does read and write the data and do just what you want. Needs some experience in writing interrupt driven programs.

 

Bob

lsw
lsw's picture
User
8 posts

Hi,Bob,Now i like to use internal interrupt,Then set TX buffer size(12)  RX Buffers size(10) .

I want send data(12 frame) every 20 ms first,and then receive data(10 frame) from other.

I use GetRxBufferSize() and GetTxBufferSize() can not  collect to send or receive data.Because i find it always enter interrupt which is not "UART_1_INTR_RX_NOT_EMPTY".

So i have to close internal interrupt receive data in main().Then set TX buffer size(12)  RX Buffers size(8) .So can use None interrupt .The following is my program.

   for(;;)

{  

        if (UART_1_SpiUartGetRxBufferSize())
        {
            Deal_UartRX();
        }

       if(A20ms)//20ms once

      {

             Deal_UartTX();//UART_1_SpiUartPutArray(&UartTXData_DISP[0], 12);

      }

}

 

it test ok.But i still do not know how to use internal interrupt receive data which more than size(8).

I find if i set internal interrupt sourcest "RX FIFO not empty",it can enter interrupt"TX FIFO not full",so my program is abnormal。

But i do not set interrupt sources t"TX FIFO not full",why it run in?

     (UART_1_GetTxInterruptSourceMasked() & UART_1_INTR_TX_NOT_FULL)//debug ,this is 1(ture).

hli
user_78878863's picture
User
2759 posts

SpiUartPutArray is potentially blocking - it waits until it can place data into the TX FIFO. So you should not use it in an ISR, because this ISR will then be active for too long.

For TX purposes its better to only set a flag in the ISR, and evaluate this flag in the main loop.

You can set larger buffers, which will create  an internal ISR (because then the component needs to handle sending the data). But he component will provide with the ability to set an interrupt callback which will be called to signal when data needs to be received / sent.

user_1377889's picture
User
10803 posts

It is easier for us when you post your complete project so that we all can have a look at all of your settings. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.

 

Bob

 

user_1377889's picture
User
10803 posts

You have two exclusive choices:

  • Using the internal interrupt
  • Providing an own external interrupt

No mixing of those

My suggestions:

Increase Rx and Tx buffer size in UART to 80 (there are plenty of bytes in your PSoC)

Poll for UART_SpiUartGetRxBufferSize() to see if a character was received.

When transmitting data, just send them using UART_SCB_UartPutString() and do not forget the null-termination of the string.

No need for polling with UART_SpiUartGetTxBufferSize() except you want to know when the transmit has been done.

 

Bob

lsw
lsw's picture
User
8 posts

Hi,Bob

You say "The internal interrupt provides software that handles the transfer from an to the receive and transmit buffer automatically."

That means internal interrupt  transfer from an to the receive and transmit buffer only can use in ISR program?not in main()?

I understand external interrupt and No interrupt to deal with the UART.I have test program OK.

but I don't understand internal interrupt how to deal with data to send or receive.How to write program?

CY_ISR(MY_UART_ISR)
{
    if (UART_1_GetRxInterruptSourceMasked() & UART_1_INTR_RX_NOT_EMPTY)
    {
        Deal_UartRX();
        Deal_UartTX();
    }

    UART_1_ClearRxInterruptSource(UART_1_INTR_RX_NOT_EMPTY);

}

like this ?

user_1377889's picture
User
10803 posts

like this ?

No, you misunderstood me. Internal interrupt implies that the component will care for the interrupt and the handling. You do NOT provide an interrupt handler. Instead you use in main() the GetRxBufferSize() API to see if (or how many) bytes were received and with the UART_UartGetByte() API you retrieve the byte(s) from the buffer.

while ( UART_SpiUartGetRxBufferSize())  //  while there are bytes in the buffer

{

    MyByte = UART_UartGetByte();

    // Do what you need with MyByte

}

 

Bob

lsw
lsw's picture
User
8 posts

Hi,Bob

If Internal interrupt that "use in main() the GetRxBufferSize() API to see if (or how many) bytes were received and with the UART_UartGetByte() API you retrieve the byte(s) from the buffer"

It means that is the same way to deal with "None"interrupt?Why we can select interrupt sources"RX FIFO NOT EMPTY" when we set "internal"interrupt?And that means i select any interrupt sources when i use internal can not affect anything.

All the way deal with "internal"interrupt as the way which you say?But not in CY_ISR().

 

 

user_1377889's picture
User
10803 posts

If you had changed the Rx buffer size to 80 (as I suggested) the Rx FIFO Empty interrupt would be grayed out.

"It means that is the same way to deal with "None"interrupt?" No, not at all. When you are too slow fetching the data from the FIFO some bytes may be lost without the interrupt. The internal interrupt will fetch the data from FIFO and shovels them into the Rx Buffer which will give you more time when the buffer is large enough. This method is the safest way.

 

Bob

lsw
lsw's picture
User
8 posts

Ok,thank you.

Log in to post new comments.