Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
5 years, 11 months ago.
I want to receive data via serial using interrupt.It is printing a garbage value after buffer full.
- 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();
} }
2 Answers
5 years, 11 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.
5 years, 11 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; } }
In the future please use
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 2019Thanks for sharing with us. It's helpful for my blog too https://quotesgems.com
posted by Aamir Khanp 06 May 2019