5 years, 3 months ago.

I want to receive data via serial using interrupt.It is printing a garbage value after buffer full.

  1. include "mbed.h"
  2. define size 25 Serial pc(PA_9, PA_10); DigitalOut myled(PA_0); char rxBuff[size];array to store unsigned int bufferWritingIndex = 0;Writing Pointer unsigned int bufferReadingIndex = 0;Reading Pointer

void RxInterrupt(void); void readPc(void);

int main(void) { confSysClock(); Configure system clock (72MHz HSE clock, 48MHz USB clock)

pc.baud(115200); pc.attach(&RxInterrupt, Serial::RxIrq); myled = 0; turn the LED on wait(1); 200 millisecond myled = 1; turn the LED off wait(1); 1000 millisecond RxInterrupt(); pc.printf("Hello! World\r\n"); wait(1); pc.printf("Please, Enter ANY Text"); while(1) { The on-board LED is connected, via a resistor, to +3.3V (not to GND). So to turn the LED on or off we have to set it to 0 or 1 respectively. readPc();

} }

In the future please use

<<code>>
your code
<</code>>

#include "mbed.h"
#define size 25

Serial pc(PA_9, PA_10);
DigitalOut myled(PA_0);
char rxBuff[size]; //array to store 
unsigned int bufferWritingIndex = 0; //Writing Pointer
unsigned int bufferReadingIndex = 0; //Reading Pointer

void RxInterrupt(void);
void readPc(void);

int main(void) {
  confSysClock();// Configure system clock (72MHz HSE clock, 48MHz USB clock)
  pc.baud(115200);
   pc.attach(&RxInterrupt, Serial::RxIrq);
   myled = 0; //turn the LED on
   wait(1);  //200 millisecond 
  myled = 1; //turn the LED off 
  wait(1); //1000 millisecond 
  RxInterrupt();
   pc.printf("Hello! World\r\n");
   wait(1); 
  pc.printf("Please, Enter ANY Text"); 
  while(1) { // The on-board LED is connected, via a resistor, to +3.3V (not to GND). So to turn the LED on or off we have to set it to 0 or 1 respectively.
   readPc();
  }
}
posted by Andy A 15 Jan 2019

Well the most obvious problem is that RxInterrupt isn't defined in the code you posted. Please include your function definitions.

posted by Andy A 15 Jan 2019

Thanks for sharing with us. It's helpful for my blog too https://quotesgems.com

posted by Aamir Khanp 06 May 2019

2 Answers

5 years, 3 months ago.

Three small changes to your code on lines 6, 38 and 56:

#include "mbed.h"
#define size 1000
Serial      pc(PA_9, PA_10);
DigitalOut  myled(PA_0);
char rxBuff[size];//array to store
volatile unsigned int bufferWritingIndex = 0;//Writing Pointer   <---- Make this volatile
unsigned int bufferReadingIndex = 0;//Reading Pointer
 
void RxInterrupt(void);
void readPc(void);
 
int main(void) 
{
   // confSysClock();     //Configure system clock (72MHz HSE clock, 48MHz USB clock)
    
    
    pc.baud(115200);
    pc.attach(&RxInterrupt, Serial::RxIrq);
    myled = 0;      // turn the LED on
    wait(1);   // 200 millisecond
    myled = 1;      // turn the LED off
    wait(1);  // 1000 millisecond
   // RxInterrupt();
    pc.printf("Hello! World\r\n");
    wait(1);
    pc.printf("Please, Enter ANY Text");
    while(1) 
    {
        // The on-board LED is connected, via a resistor, to +3.3V (not to GND). 
        // So to turn the LED on or off we have to set it to 0 or 1 respectively.
        readPc();  
        
    }
}
 
void RxInterrupt(void)
{
   while(pc.readable())  // <---- won't have any effect but see comments below.
    {
        rxBuff[bufferWritingIndex++]=pc.getc();
        if(bufferWritingIndex>=size)
        bufferWritingIndex=0;    
    }
    
}
 
 
void readPc(void)
{
    char rxByte;
    while(bufferReadingIndex != bufferWritingIndex)
    {
        rxByte = rxBuff[bufferReadingIndex++];
        pc.putc(rxByte);
        if(bufferReadingIndex>=size)
         bufferReadingIndex=0; // <------------ You were resetting the Writing index not the reading index
    }
}

The last of the 3 changes is the big one. It looks like you had a copy and paste error and had forgotten to change which variable you were resetting.

The first of the changes is also very important. After making the fix there is a risk that the compiler will look at your while(1) loop and decide that since nothing in that loop can change the write pointer it only needs to load the value into a CPU register once at the start of the loop and never check it again. The keyword volatile forces the compiler to always check to see if the value has been changed by some unknown means (i.e. an interrupt). Because this will depend on how things have been optimized this sort of bug can result in code that will work one time and then you make a minor unrelated change and things stop working. Simple rule - any counters or indexes that are changed in an interrupt and used anywhere outside that interrupt should always be volatile.

The 3rd change is fairly minor, you are in an Rx interrupt, there will always be a char waiting or you wouldn't be there so the if(pc.readable()) is not needed. But you could potentially have two bytes waiting in the buffer and so the while will catch that situation and read them both. Highly unlikely unless some other interrupt is blocking things for a long time (which would normally mean you've got bigger problems) but it doesn't hurt to check.

Accepted Answer

Thankyou! So Much now it is working...

posted by Rajkumar Singh 15 Jan 2019
5 years, 3 months ago.

Thanks for sharing

https://questionsgems.com/questions-to-ask-siri/

MY Code is

#include "mbed.h"
#define size 1000
Serial      pc(PA_9, PA_10);
DigitalOut  myled(PA_0);
char rxBuff[size];//array to store
unsigned int bufferWritingIndex = 0;//Writing Pointer
unsigned int bufferReadingIndex = 0;//Reading Pointer

void RxInterrupt(void);
void readPc(void);

int main(void) 
{
   // confSysClock();     //Configure system clock (72MHz HSE clock, 48MHz USB clock)
    
    
    pc.baud(115200);
    pc.attach(&RxInterrupt, Serial::RxIrq);
    myled = 0;      // turn the LED on
    wait(1);   // 200 millisecond
    myled = 1;      // turn the LED off
    wait(1);  // 1000 millisecond
   // RxInterrupt();
    pc.printf("Hello! World\r\n");
    wait(1);
    pc.printf("Please, Enter ANY Text");
    while(1) 
    {
        // The on-board LED is connected, via a resistor, to +3.3V (not to GND). 
        // So to turn the LED on or off we have to set it to 0 or 1 respectively.
        readPc();  
        
    }
}

void RxInterrupt(void)
{
    if(pc.readable())
    {
        rxBuff[bufferWritingIndex++]=pc.getc();
        if(bufferWritingIndex>=size)
        bufferWritingIndex=0;    
    }
    
}


void readPc(void)
{
    char rxByte;
    while(bufferReadingIndex != bufferWritingIndex)
    {
        rxByte = rxBuff[bufferReadingIndex++];
        pc.putc(rxByte);
        if(bufferReadingIndex>=size)
         bufferWritingIndex=0;
    }
}
posted by Rajkumar Singh 15 Jan 2019