[SOLVED] Problem in USART0 interrupt rx_buffer0

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi all,

  Good Day!  i am coding in CodeVision AVR and using Atmega 128 IC. In this i am trying to do in frame format. in this i used USART0 and size of rx_buffer size is 256. in this i am always receiving only 3 char in rx_buffer0. the size is 256 but it is always 3 char only.  I not getting why it is always like this. i think little error is there but i couldn't find it out. Can you please help me to find out the problem.

 

And my code is :

 

/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.3 Standard
Automatic Program Generator
© Copyright 1998-2011 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project :
Version :
Date    : 3/27/2015
Author  : Dev6
Company : sass
Comments:


Chip type               : ATmega128
Program type            : Application
AVR Core Clock frequency: 14.745600 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 1024
*****************************************************/

#include <mega128.h>
#include <stdio.h>
#include <delay.h>
#include <string.h>

unsigned char rcv_comp=0, rx_rcv=0;
unsigned char uartin_data[256];
unsigned int i = 0;


#ifndef RXB8
#define RXB8 1
#endif

#ifndef TXB8
#define TXB8 0
#endif

#ifndef UPE
#define UPE 2
#endif

#ifndef DOR
#define DOR 3
#endif

#ifndef FE
#define FE 4
#endif

#ifndef UDRE
#define UDRE 5
#endif

#ifndef RXC
#define RXC 7
#endif

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART0 Receiver buffer  //8
#define RX_BUFFER_SIZE0 256
char rx_buffer0[RX_BUFFER_SIZE0];

#if RX_BUFFER_SIZE0 <= 256
unsigned char rx_wr_index0,rx_rd_index0,rx_counter0;
#else
unsigned int rx_wr_index0,rx_rd_index0,rx_counter0;
#endif

// This flag is set on USART0 Receiver buffer overflow
bit rx_buffer_overflow0;

// USART0 Receiver interrupt service routine
interrupt [USART0_RXC] void usart0_rx_isr(void)
{
    char status,data;
    status=UCSR0A;
    data=UDR0;

    if(data == '*')
    {
        rcv_comp=0;
        rx_wr_index0 = 0;
        rx_rcv=1;
        puts("\n* matched");
    }

    if(data == '#')
    {
        rcv_comp=1;
        puts("\n# matched");
    }

    if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
    {
       rx_buffer0[rx_wr_index0++]=data;
       printf("\ninterrupt = %s", rx_buffer0);
       //puts(rx_buffer0);     //
    #if RX_BUFFER_SIZE0 == 256
       // special case for receiver buffer size=256
       if (++rx_counter0 == 0) rx_buffer_overflow0=1;
    #else
       if (rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0;
       if (++rx_counter0 == RX_BUFFER_SIZE0)
       {
          rx_counter0=0;
          rx_buffer_overflow0=1;
       }
    #endif
    }
}

#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART0 Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
    char data;
//    puts("\nin getchar");
    while (rx_counter0==0);
    data=rx_buffer0[rx_rd_index0++];
//    putchar(data);
    #if RX_BUFFER_SIZE0 != 256
    if (rx_rd_index0 == RX_BUFFER_SIZE0) rx_rd_index0=0;
    #endif
    #asm("cli")
    --rx_counter0;
    #asm("sei")
    return data;
}
#pragma used-
#endif


void frame_function()
{
    if(rx_rcv==1)
    {
        if(rcv_comp==1)
        {
            printf("\nsize_rx_buffer0: %d", sizeof(rx_buffer0));
            puts("\nstart_buf");
            putchar(rx_buffer0[1]);
            putchar(rx_buffer0[2]);
            putchar(rx_buffer0[3]);
            putchar(rx_buffer0[4]);
            putchar(rx_buffer0[5]);
            delay_ms(100);
            puts("\nend_buf");
            strcpy(uartin_data,rx_buffer0);
            //puts(uartin_data);
            //delay_ms(100);
            puts("\nstart_uart");
            for(i=0;i<7;i++)
            {
                printf("\nuartin[%d]= %c", i,uartin_data[i]);
                //putchar(uartin_data[i]);
            }
            puts("\nend_uart");
        }
        delay_ms(1000);
    }
    rx_rcv=0;
    rcv_comp=0;
}

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Port E initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTE=0x00;
DDRE=0x00;

// Port F initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTF=0x00;
DDRF=0x00;

// Port G initialization
// Func4=In Func3=In Func2=In Func1=In Func0=In
// State4=T State3=T State2=T State1=T State0=T
PORTG=0x00;
DDRG=0x00;

// USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Receiver: On
// USART0 Transmitter: On
// USART0 Mode: Asynchronous
// USART0 Baud Rate: 9600
UCSR0A=0x00;
UCSR0B=0x98;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x5F;

// Global enable interrupts
#asm("sei")

puts("\nStart\n");

while (1)
      {
      // Place your code here

        frame_function();
        delay_ms(1000);

      }
}

 

if my input is *s# then i am getting exact output *s#.

What ever the input is but the output is only 3 chars.

I am sending *INCRE# but i am getting *IN only 

My Output is:

 

 

This topic has a solution.

-----------------------

Thanks & Regards,

Sasi

-----------------------

GO GREEN

Last Edited: Sat. Mar 28, 2015 - 05:03 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks to all. I got the solution. just removed the print function in interrupt then i got the output what i expected.

but i don't know why it is not working with print function?

 

 

And my new working code is: 

/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.3 Standard
Automatic Program Generator
© Copyright 1998-2011 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project :
Version :
Date    : 3/27/2015
Author  : Dev6
Company : sass
Comments:


Chip type               : ATmega128
Program type            : Application
AVR Core Clock frequency: 14.745600 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 1024
*****************************************************/

#include <mega128.h>
#include <stdio.h>
#include <delay.h>
#include <string.h>

unsigned char rcv_comp=0, rx_rcv=0;
unsigned int uartin_ctr=0;
unsigned char uartin_data[256];
unsigned int i = 0;


#ifndef RXB8
#define RXB8 1
#endif

#ifndef TXB8
#define TXB8 0
#endif

#ifndef UPE
#define UPE 2
#endif

#ifndef DOR
#define DOR 3
#endif

#ifndef FE
#define FE 4
#endif

#ifndef UDRE
#define UDRE 5
#endif

#ifndef RXC
#define RXC 7
#endif

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART0 Receiver buffer  //8
#define RX_BUFFER_SIZE0 256
char rx_buffer0[RX_BUFFER_SIZE0];

#if RX_BUFFER_SIZE0 <= 256
unsigned char rx_wr_index0,rx_rd_index0,rx_counter0;
#else
unsigned int rx_wr_index0,rx_rd_index0,rx_counter0;
#endif

// This flag is set on USART0 Receiver buffer overflow
bit rx_buffer_overflow0;

// USART0 Receiver interrupt service routine
interrupt [USART0_RXC] void usart0_rx_isr(void)
{
    char status,data;
    status=UCSR0A;
    data=UDR0;

    if(data == '*')
    {
        uartin_ctr=0;
        rcv_comp=0;
        rx_wr_index0 = 0;
        rx_rcv=1;
        //puts("\n* matched");  //
    }

    if(data == '#')
    {
        rcv_comp=1;
        //puts("\n# matched"); //
        //printf("\ndata# =  %s", rx_buffer0); //
    }

    if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
    {
       rx_buffer0[rx_wr_index0++]=data;
       //printf("\ninterrupt = %s", rx_buffer0); //
    #if RX_BUFFER_SIZE0 == 256
       // special case for receiver buffer size=256
       if (++rx_counter0 == 0) rx_buffer_overflow0=1;
    #else
       if (rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0;
       if (++rx_counter0 == RX_BUFFER_SIZE0)
       {
          rx_counter0=0;
          rx_buffer_overflow0=1;
       }
    #endif
    }
}

#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART0 Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
    char data;
    while (rx_counter0==0);
    data=rx_buffer0[rx_rd_index0++];
    #if RX_BUFFER_SIZE0 != 256
    if (rx_rd_index0 == RX_BUFFER_SIZE0) rx_rd_index0=0;
    #endif
    #asm("cli")
    --rx_counter0;
    #asm("sei")
    return data;
}
#pragma used-
#endif


void frame_function()
{
    if(rx_rcv==1)
    {
        if(rcv_comp==1)
        {
            //printf("\nsize_rx_buffer0: %d", sizeof(rx_buffer0));
            puts("\nstart_buf");
            putchar(rx_buffer0[1]);
            putchar(rx_buffer0[2]);
            putchar(rx_buffer0[3]);
            putchar(rx_buffer0[4]);
            putchar(rx_buffer0[5]);
            delay_ms(100);
            puts("\nend_buf");
            strcpy(uartin_data,rx_buffer0);
            //puts(uartin_data);
            //delay_ms(100);
            puts("\nstart_uart");
            for(i=0;i<7;i++)
            {
                printf("\nuartin[%d]= %c", i,uartin_data[i]);
                //putchar(uartin_data[i]);
            }
            puts("\nend_uart");
        }
        delay_ms(1000);
    }
    rx_rcv=0;
    rcv_comp=0;
}

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Port E initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTE=0x00;
DDRE=0x00;

// Port F initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTF=0x00;
DDRF=0x00;

// Port G initialization
// Func4=In Func3=In Func2=In Func1=In Func0=In
// State4=T State3=T State2=T State1=T State0=T
PORTG=0x00;
DDRG=0x00;

// USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Receiver: On
// USART0 Transmitter: On
// USART0 Mode: Asynchronous
// USART0 Baud Rate: 9600
UCSR0A=0x00;
UCSR0B=0x98;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x5F;

// Global enable interrupts
#asm("sei")

puts("\nStart\n");

while (1)
      {
      // Place your code here

        frame_function();
        delay_ms(1000);

      }
}

 

 

 

-----------------------

Thanks & Regards,

Sasi

-----------------------

GO GREEN

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Your original code had problems as whilst printf was sending out characters, it could no longer receive characters as printf was in the receive isr and it could not do anything else.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

but i don't know why it is not working with print function?

How long does that print function take? How many characters arrive and are lost while it is executing?

 

This is an important lesson to learn. On a micro and especially one that does not have an interrupt priority system you always need to keep your interrupt[] code as short as possible. Like in the region of microseconds. At 9600 baud you are receiving close to 1,000 characters per second. So even if your interrupt[] code only took 1 millisecond there might be a chance of losing something. As it is I bet it was taking 10's if not 100's of milliseconds.

 

In fact the whole point of using USART0_RXC is so that your AVR can get on and do "other stuff" while the characters "silently" arrive in the background. That interrupt code should do NOTHING but retrieve the arrived character and put it at the "next place" in some buffer. If you want to "consume" the characters that are being received you do that using code in main() not in the interrupt and that includes (especially) long operations like printing what's being received.

 

In fact once you have a getchar() that is simply receiving bytes from an RXC buffer then your entire access to the data should be via that getchar(). When you call other <stdio> functions like gets() or scanf() they will, in turn, simply make calls to getchar(). Nothing access the interrupt code or it's buffers directly - only getchar() and because it does it in the foreground (called from main() not an interrupt) there are no issues with things "taking too long".

 

Obviously (at least I hope it's obvious?) you should not call getchar() or any stdio functions that access stdin from the interrupt itself.

 

The one thing the interrupt might do apart from just put the received characters into a buffer is look out for some "special character" passing by (often '\n') it might then set a separate flag that code in main() would read and this flag would effectively be saying "I just saw the end of line character so we probably have a whole "sentence" to work on now".

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Good Day! Thank you so much  Clawson. yes now i got it why the problem was happened.  And also understood what is interrupt function is.  Now i got clear idea about interrupt function.

-----------------------

Thanks & Regards,

Sasi

-----------------------

GO GREEN

Last Edited: Sat. Mar 28, 2015 - 05:02 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Good Day!. Thanks a lot  Kartman  and  clawson .  I got it now. And also understood what is interrupt function is.  Now i got clear idea about interrupt function. Thanks to all.

-----------------------

Thanks & Regards,

Sasi

-----------------------

GO GREEN

Last Edited: Sat. Mar 28, 2015 - 05:01 AM