This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Serial Array

Hello All, I am working with interrupt based UART0, and I do have little problem in receiving data and storing it in array.

Here is the working ISR

void UART0ISR(void)__irq
{


        if(U0IIR & RDA)
        {
                rxmessage=U0RBR;
                VICVectAddr = 0x00;
         }


}

The problem is I will be receiving a sequence of Hex Data. For eg. 5A AA 06 at first. In this header the third byte 0x06 indicates the length of the characters that will be received further. Later.... I will be receiving 83 00 0A 01 00 01 . I am struggling to figure out and store these things in an array. None of the method I tried seemed to be useless. Can anyone please give some example or advise on it.

Warm Regards

  • What's the problem, exactly?

    Do you know how to use arrays in 'C'?

  • Define a global array of the maximum length required.

    eg:
    unsigned char rx_array[50];

    A counter variable is needed to count the position in which the data will be written when the data will be received. The variable needs to be incremented by 1 after the data is written in that position.
    NOTE: This counter variable can be a local variable, but has to be 'static'.
    eg:
    static char rx_cntr=0;

    Then the code becomes:

    void UART0ISR(void)__irq
    {
       static char rx_cntr=0;
    
            if(U0IIR & RDA)
            {
                    rx_array[rx_cntr++] = U0RBR;
                    VICVectAddr = 0x00;
    
             }
    }
    

    Have taught you to use array. Develop the logic of what you want to achieve exactly.
    [& send me the Tuition fees ;) ]

    Read about the following topics ["GOOGLE Search"]
    static variables, local variables and global variables in C

  • ... to consider what happens when you reach the end of the array?

    Further reading: "Circular" or "Ring" buffers

  • The advantage with a proper circular buffer is that it has two indices - one owned by the ISR for inserting data. One owned by the main loop for reading data. So no locking is needed to protect these two indices, as long as the processor can read/write them atomically.

    The world is full of code examples.

    Just that the world expects people to have a working knowledge about Google and the other available search engines. Because they are so very much faster at producing an answer to most questions compared to forum threads.

  • The world is full of code examples.
    
    Just that the world expects people to have a working knowledge about Google and the other available search engines.
    Because they are so very much faster at producing an answer to most questions compared to forum threads.
    

  • Hi... I know a bit about array and to let you know I have just started to learn Keil and Arm. Here is the code I am using...

    #define CR     0x0D
    #include "LPC214x.H"
    #include "stdio.h"
    //CCLK=12xM=12x5=60MHZ
    //PCLK=CCLK (VPBDIV=0x00)
    
    #define RDR        0x01
    #define THRE    0x20
    #define RDA        0x04
    
    
    void UART0ISR(void)__irq;
    
    
    
    int putchara (int ch);
    
    
    unsigned char rxmessage[30];
    unsigned char rx_cntr=0;
    unsigned char rx_mcntr=0;
    
    
    int putchara (int ch)                      /* Write character to Serial Port    */
    {
    
      if (ch == '\n')  {
        while (!(U0LSR & 0x20));
        U1THR = CR;                    /* output CR */
      }
      while (!(U0LSR & 0x20));
      return (U0THR = ch);
    }
    
    
    void Init_UART0(void)
    {
      PINSEL0       = 0x00000005;
      U0LCR         = 0x00000083;
      U0DLL         = 98;
      U0DLM                 = 0;
      U0LCR         = 0x00000003;
      U0IER = 0x00000003;
    
    }
    
    
    void Init_VIC(void)
    {
    
        VICVectCntl2 = 0x26;
        VICVectAddr2 = (unsigned long int)UART0ISR;
        VICIntEnable |= 0x00000040;          //enable UART0 interrupt
    
    }
    
    
    
    void delay(void)
    {
        unsigned short int i;
        for(i=0;i<50000;i++);
    }
    
    int main(void)
    {
            int a;
        Init_UART0();
        Init_VIC();
    
    
         while(1)
          {
    
              ;
    
        }
    }
    
    
    void UART0ISR(void)__irq
    {
    
    
                    if(U0IIR & RDA)
                    {
    
                                              rxmessage[rx_cntr++]=U0RBR;
                                              VICVectAddr = 0x00;
    
    
                                              if(rx_cntr>=3 && rx_mcntr==0)
                                              {
                                              rx_mcntr=rxmessage[2];
                                              rx_cntr=0;
                                              //putchara(rxmessage[0]);
                                              //putchara(rxmessage[1]);
                                              //putchara(rxmessage[2]);
                                              }
    
    
                                              if(rx_cntr>=rx_mcntr && rx_mcntr!=0)
                                              {
                                              rx_mcntr=0;
                                              rx_cntr=0;
                                              putchara('0');
                                              }
    
    
            }
    
    
    }
    
    

    I am having the the following data sent to the processor 0xAA 0xAB 0x06 0x88 0x00 0x0A 0x01 0x00 0x01 . As you can see the third byte indicates the number of bytes that will be transmitted ( after 3rd byte) in this case 0x06 = 6 bytes. My problem is when I test with proteus it considers the decimal equivalent for 6 which equals to 54 and it waits for further 54 characters instead of 6. In real hardware it does not work at all. Please advise.

  • Hi Can you please google and find me an example for what I am looking for. In the view of a beginner. To let you know, I am posting here after searching google first.

  • 54 in decimal is 36 is ASCII.

    your code is absolutely working fine if it waits for 54 more characters to be received.

    your mistake: You are transmitting 0x36 ('6' in ASCII).
    soln: Transmit 0x06 or in the isr code subtract 0x30 from the 3rd byte which indicates the number of bytes to be received after the 3rd byte.

    in ISR, change this...

    rx_mcntr=rxmessage[2] - 0x30;
    

    which is same as

    rx_mcntr=rxmessage[2] - '0';
    

  • in ISR, change this...

    rx_mcntr=rxmessage[2];
    

    to

    rx_mcntr=rxmessage[2] - 0x30;  // or rx_mcntr=rxmessage[2] - '0';
    

  • 54 in decimal is '6' is ASCII.
    54 in decimal is 36 in hexadecimal.