External interrupts of 8051 in c - interrupt-handling

This code written to display speed in mph by calculating number of external interrupts at INT0 for a particular time delay, works a part ie it just displays 'Read out:'
and then nothing.
I have seen 8051 derivatives page in c51 development tools. It shows me no needed information.
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.kui0002a/c51_dv_8051deriv.htm
I have not understood why sometimes its written
void ex0_isr(void) interrupt 0 using 2
Can someone help me understand where am wrong?
Simulation is working fine.
//Calculating speed
#include <reg51.h>
#include <string.h>
void read(unsigned int q);
void delay(void);
void delay1(unsigned long int time);
void SerInit();
void SerTx(unsigned char x);
void SerTx_str(unsigned char msg[]);
unsigned char msg[]="Speed= ";
unsigned char buffer[12];
sbit in_port=P3^2;
sbit EDGT=TCON^0;
unsigned char volatile count;
unsigned int q;
void ex0_isr(void) interrupt 0
{
count++;
}
void timer0(void) interrupt 1
{
TR0=0;
{
void main()
{
SerInit(); //serial initialisation
SerTx_str("Read out:"); //send string to hyperterminal
SerTx('\n');
delay1(20); //delay using loop
SerTx('\r');
in_port=1; //input port pin
EDGT=1; //make IT0 =1 an edge triggered
while(1)
{
count=0; //initialize count
IE=IE|0x81; //enable global and INT0
delay(); //delay using timers for a time to measure count
SerTx_str("Dbg"); //check
IE=IE&0xFE; //disable INT0
q=count;
read(q); //function called for ASCII conversion
SerTx_str(msg); //send message to terminal
SerTx_str(buffer); // send count to terminal
SerTx('\n');
delay1(2000);
SerTx('\r');
}
}
void read( unsigned int q)
{
unsigned int d1,d2,d3;
d1=q%10;
q=q/10;
d2=q%10;
d3=q/10;
buffer[0]=d3+'0';
buffer[1]=d2+'0';
buffer[2]=d1+'0';
}
void delay(void)
{
unsigned int i;
for(i=0;i<45;i++)
{
TMOD=0x01; //Timer 0, mode1(16 bit)
TL0=0xFD; //load TL0
TH0=0x4B; //load TH0
IE=IE|0x02; //enable Timer 0 interrupt
TR0=1; //turn on Timer 0
do
{
q=count;
}
while(TF0==0);
//if there's overflow ie, TF=1, goto interrupt 1
//
//> TMOD=0x01;
> TL0=0xFD;
> TH0=0x4B;
> TR0=1;
> while(TF==0);
> TR0=0;
> TF0=0; // previous code
}
}

My guess is that by doing:
IE=0x81;
You are accidentally disabling the timer interrupts, which means that your delay() function never returns. I suspect you probably want to do something like this instead:
IE = IE | 0x01; // enable INT0
delay(); // delay using timers for a time to measure count
IE = IE & 0xFE; // disable INT0

Related

Servo motor won't work for a specific code

I have written a code with interrupts to control the servo but my servos are not working. One is meant to work with interrupt but the other one has to simply move but it is also not working. Even the serial window shows that the code is working properly ut the servos aren't moving I have checked both my servos with same connections and Sweep example of Arduino and both work fine.
#include <TimerOne.h> // Header file for TimerOne library
#include <Servo.h>
#define trigPin 12 // Pin 12 trigger output
#define echoPin 2 // Pin 2 Echo input
#define echo_int 0 // Interrupt id for echo pulse
#define TIMER_US 50 // 50 uS timer duration
#define TICK_COUNTS 4000 // 200 mS worth of timer ticks
volatile long echo_start = 0; // Records start of echo pulse
volatile long echo_end = 0; // Records end of echo pulse
volatile long echo_duration = 0; // Duration - difference between end and start
volatile int trigger_time_count = 0; // Count down counter to trigger pulse time
volatile long range_flasher_counter = 0; // Count down counter for flashing distance LED
int sound = 250;
Servo servo1; //Servos
Servo servo2;
const int button1 = 10; //Buttons
const int button2 = 8;
const int button3 = 13;
const byte interruptPin = 3;
int pos;
void setup() {
servo1.attach(9); // servo for arm
servo2.attach(5); // servo for base
pinMode(trigPin, OUTPUT); // Trigger pin set to output
pinMode(echoPin, INPUT); // Echo pin set to input
// Onboard LED pin set to output
Timer1.initialize(TIMER_US); // Initialise timer 1
Timer1.attachInterrupt( timerIsr ); // Attach interrupt to the timer service routine
attachInterrupt(echo_int, echo_interrupt, CHANGE);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin),Metal_detected, HIGH);
pinMode(button1, INPUT);
pinMode(button2, INPUT);
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
servo1.write(0); // These will make the servos move to the mapped angles
servo2.write(90);
distance_checking();
if(digitalRead(button1) == HIGH)
{
while(digitalRead(button2) == LOW)
{
Serial.println("Entering Sweeping mode");
for (pos = 30; pos <= 150; pos += 1)
{ Serial.print("Angle is :");
Serial.println(pos);
servo2.write(pos);
distance_checking();
//delay(0.1); // waits 15ms for the servo to reach the position
if(digitalRead(button2) == HIGH)
{
Serial.print("Exiting Sweeping");
goto label;}
}
for (pos = 150; pos >= 30; pos -= 1) { // goes from 180 degrees to 0 degree
Serial.print("Angle is :");
Serial.println(pos);
servo2.write(pos); // tell servo to go to position in variable 'pos'
distance_checking();
//delay(0.1); // waits 15ms for the servo to reach the position
if(digitalRead(button2) == HIGH)
{
goto label;
Serial.print("Exiting Sweeping");}
}
}
}
//reset th
label:
if(digitalRead(button2) == HIGH){
servo1.write(0);
servo2.write(90);
Serial.println("press the sweeping button to enter sweeeping mode");
delay(300);
}
}
void distance_checking()
{
if (echo_duration/58 <= 20)
{
Serial.println("the servo angle is 30");
servo1.write(30);
delay(1500);
}
else {
servo1.write(0);
}
delay(500);
}
void Metal_detected()
{if(digitalRead(button2) == LOW)
{delay(5000);
Serial.print("Metal detected at servo angle:");
Serial.println(servo2.read());
servo1.write(servo1.read());
servo2.write(servo2.read());
Serial.println("Motion is stopped");
Serial.println("Press reset to go to the home position");
}
//while(digitalRead(button2) == HIGH)
// {
// Serial.print("Reseting");
// return 0;}
}
void timerIsr()
{
trigger_pulse(); // Schedule the trigger pulses
// Flash the onboard LED distance indicator
}
// --------------------------
// trigger_pulse() called every 50 uS to schedule trigger pulses.
// Generates a pulse one timer tick long.
// Minimum trigger pulse width for the HC-SR04 is 10 us. This system
// delivers a 50 uS pulse.
// --------------------------
void trigger_pulse()
{
static volatile int state = 0; // State machine variable
if (!(--trigger_time_count)) // Count to 200mS
{ // Time out - Initiate trigger pulse
trigger_time_count = TICK_COUNTS; // Reload
state = 1; // Changing to state 1 initiates a pulse
}
switch(state) // State machine handles delivery of trigger pulse
{
case 0: // Normal state does nothing
break;
case 1: // Initiate pulse
digitalWrite(trigPin, HIGH); // Set the trigger output high
state = 2; // and set state to 2
break;
case 2: // Complete the pulse
default:
digitalWrite(trigPin, LOW); // Set the trigger output low
state = 0; // and return state to normal 0
break;
}
}
// --------------------------
// echo_interrupt() External interrupt from HC-SR04 echo signal.
// Called every time the echo signal changes state.
//
// Note: this routine does not handle the case where the timer
// counter overflows which will result in the occassional error.
// --------------------------
void echo_interrupt()
{
switch (digitalRead(echoPin)) // Test to see if the signal is high or low
{
case HIGH: // High so must be the start of the echo pulse
echo_end = 0; // Clear the end time
echo_start = micros(); // Save the start time
break;
case LOW: // Low so must be the end of hte echo pulse
echo_end = micros(); // Save the end time
echo_duration = echo_end - echo_start; // Calculate the pulse duration
break;
}
}
I tested my motors with this code one by one and they worked absolutely fine:
#include <Servo.h>
Servo myservo; // create servo object to control a servo
// twelve servo objects can be created on most boards
int pos = 0; // variable to store the servo position
void setup() {
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}
void loop() {
for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
}

User input stuck in loop

I have made this code on Arduino where the objective is to have the user type in a delay time into the serial monitor, and then the LED should be blink with that delay time. For example if I type in 1000 the LED should be turned on for 1 second then off for 1 second, then repeat.
My problem is that when the code has finished running once, it waits for a new user input, instead of continuing to blink. I think i have to take the Serial.parseInt out of the loop but i'm not sure how as every time I have tried to put it somewhere else the LED just lights up constantly.
Here is the code:
int ledPin = 13;
void setup() {
// put your setup code here, to run once:
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
Serial.print(" Enter delay time: ");
while (!Serial.available());
}
void loop() {
// put your main code here, to run repeatedly
int delayTime = Serial.parseInt();
digitalWrite(ledPin, HIGH);
delay(delayTime);
digitalWrite(ledPin, LOW);
delay(delayTime);
}
Serial.parseInt is a blocking function. That means it waits for valid serial input until it times out. Because of this, any other action in loop has to wait too. Reading user input in setup works only once though, so it never asks the user for input again.
To avoid this, you'll have to check the serial buffer, and then read each byte individually, while also doing the LED blinking in the main loop.
Another thing to avoid now, is the use of the delay function, because it also hangs the entire main loop (including the serial readings) for the given parameter time. You can still blink the LED by using timestamp intervals.
For a nice example of a non-blocking serial read, we can use this sample from the Arduino docs. Additionally, for another nice example of an LED-blinking sketch without using delay, we can use the BlinkWithoutDelay sample from the Arduino docs too.
String inString = "";
unsigned long previousMillis = 0;
int delayTime = 0;
int ledState = LOW;
int ledPin = 13;
void nonBlockingSerialReadDelayTime() {
while (Serial.available() > 0) {
int inChar = Serial.read();
if (isDigit(inChar)) {
// convert the incoming byte to a char and add it to the string
inString += (char)inChar;
}
// if you get a newline (user pressed ENTER on the serial console)
if (inChar == '\n') {
// set our new delay time
delayTime = inString.toInt();
// clear the string for new input
inString = "";
// ask user again
Serial.print(" Enter delay time: ");
}
}
}
void blinkLED() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= delayTime) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
// set the LED with the ledState of the variable
digitalWrite(ledPin, ledState);
}
}
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
while (!Serial.available());
Serial.print(" Enter delay time: ");
}
void loop() {
nonBlockingSerialReadDelayTime();
blinkLED();
}
Simply read the delay time in your setup befor you enter loop
int ledPin = 13;
int delayTime = 0;
void setup() {
// put your setup code here, to run once:
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
Serial.print(" Enter delay time: ");
while (!Serial.available());
delayTime = Serial.parseInt();
}
void loop() {
// put your main code here, to run repeatedly
digitalWrite(ledPin, HIGH);
delay(delayTime);
digitalWrite(ledPin, LOW);
delay(delayTime);
}
Sure Serial.parseInt() is blocking, but you can combine it with Serial.available()
const int ledPin = 13;
int delayTime = 1000;
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
Serial.print(" Enter delay time: ");
}
void loop() {
digitalWrite(ledPin, HIGH);
delay(delayTime);
digitalWrite(ledPin, LOW);
delay(delayTime);
if (Serial.available()) {
int temp = Serial.parseInt();
if (temp > 0) delayTime = temp;
Serial.print(" Enter delay time: ");
}
}
Of course this approach does not allow to break into a very slow blink cycle immediately, but that's a different issue.

UART sending wrong characters on pic18

I'm trying to simply send characters trough my UART Interface by calling the funktion: UART_Write_Text("hello");
this is the code executed in the the uart.c file:
void UART_Init(void)
{
//115200bps deafult value for RN4678
BRGH = 0; //Setting High Baud Rat
BRG16 = 0; //8-Bit mode
SPBRG = 8; //Writing SPBRG Register
TXSTAbits.SYNC = 0; //Setting Asynchronous Mode, ie UART
RCSTAbits.SPEN = 1; //Enables Serial Port
RCSTAbits.CREN = 1; //Enables Reception
TXSTAbits.TXEN = 1; //Enables Transmission
}
/******************************************************************************/
//-----UART write byte
/******************************************************************************/
void UART_Write(char data)
{
while(!TRMT);
TXREG = data;
}
/******************************************************************************/
//-----UART check tx queue
/******************************************************************************/
char UART_TX_Empty(void)
{
return TRMT;
}
/******************************************************************************/
//-----UART write string
/******************************************************************************/
void UART_Write_Text(char *text)
{
for(int i=0; text[i]!='\0' || text[i] !=0x00; i++){
UART_Write(text[i]);
}
UART_Write('\n');
}
/******************************************************************************/
//-----UART data ready to read
/******************************************************************************/
char UART_Data_Ready(void)
{
return RCIF;
}
/******************************************************************************/
//-----UART read byte
/******************************************************************************/
char UART_Read(void)
{
while(!RCIF);
return RCREG;
}
/******************************************************************************/
//-----UART read string
/******************************************************************************/
void UART_Read_Text(char *Output, unsigned int length)
{
unsigned int i;
for(int i=0;i<length;i++)
Output[i] = UART_Read();
}
Now when I'm debugging it, I see that it writes the wright charakters into the TXREG. At the end it sended the following characters: 'h', 'e', 'l', 'l', 'o', '\n'.
I send them to the bluetooth module RN4678 with a baud rate of 115200bps which is also the default baud rate of the BT module. However when I read the sended character on my phone with a Bluetooth terminal i get only some characters wright and the other ones are questionmarks, so it doesn't recognise them (not always the same character unrecognised).
I already experimented with the baud rate, but it looks like its the right value I writed into the SPBRG.
I'm also polling the TRMT so there shouldn't be any collisions...
Someone knows what I'm doing wrong?
#include "Configuration_bits.h"
#include <xc.h>
#include <stdio.h>
#include <p18f67k22.h>
#include <string.h>
#include <stdlib.h>
#define _XTAL_FREQ 16000000
void UART_Init_1(){
TRISCbits.TRISC6=1; // TX1 Pin-31
TRISCbits.TRISC7=1; // RX1 Pin-32
RC1IE=1;
SPBRG1=34; // Baud Rate 115200
BAUDCON1bits.BRG16=1;
TXSTA1bits.BRGH=1;
//TXSTA 1 Register
TXSTA1bits.TX9=0; // 8-bit transmission
TXSTA1bits.TXEN=0;
TXSTA1bits.TXEN=1; // Transmit is enabled
TXSTA1bits.SYNC=0; // Asynchronous mode
TXSTA1bits.TRMT=1; // Transmit Shift Register Status bit
//RXSTA 1 Register
RCSTA1bits.SPEN=1; // Serial Port Enable bit
RCSTA1bits.RX9=0; // 8-bit reception
RCSTA1bits.CREN=1; // Continuous Receive Enable bit
}
void UART_Tx_1(unsigned char z[])
{
unsigned int uart_tx1=0;
while(z[uart_tx1]!='\0')
{
while(!TX1IF);
TXREG1=z[uart_tx1];
uart_tx1++;
}
}
void UART_Rx_1()
{
string_rx1[uart_rx1]=RCREG1;
uart_rx1++;
}
void interrupt ISR(void)
{
if(RC1IF && RC1IE) // UART_1
{
}
}
void main(void)
{
System_Initialization();
UART_Init_1();
while(1)
{
UART_Tx_1("HELLO\r\n"); // Transmit Hello
}
}

Interrupt Handling 18F4550 PIC

I'm trying to get myself familiar with Interrupts when it comes to the 18F4550 PIC. At this point I've written a software that would light up an LED whenever the INT0 raises a flag.
My code states that every 500 ms, INT0 will raise a flag and "is supposed to" jump into an ISR and fire up a LED all while "transferring dummy data between Port C and Port D"
I've tried debugging, but once the debugger gets to the code that sets the INT0 flag to 1, the debugger says "No source code lines were found at current PC".
Here's the code below. Any kind of help is greatly appreciated. Thanks a lot!
Please note that I am using MPLAB X and a PicKit3
#include <xc.h>
#include <p18f4450.h>
#include <stdlib.h>
#define mybit LATBbits.LATB1 //LED
#define _XTAL_FREQ 10000000 //Using a crystal oscillator
void chk_isr(void);
void INT0_ISR(void);
void delay(unsigned int);
#pragma interrupt chk_isr //used for high-priority interrupt only
void chk_isr (void)
{
if(INTCONbits.INT0IF == 1) //INT0 causes interrupt?
INT0_ISR(); //Yes, Execute INT0ISR
}
#pragma code My_HiPrio_Int=0x08//high priority interrupt
void My_HiPrio_Int (void)
{
asm("GOTO chk_isr");
}
void main(void)
{
TRISBbits.TRISB1 = 0; //RB1 = output
mybit = 0; //Initially LED is OFF
TRISC = 0xFF; //PORTC = input
TRISD = 0; //PORTD = output
INTCONbits.INT0IF = 0; //clear INT0
INTCONbits.INT0IE = 1; //enable INT0 interrupt
INTCONbits.GIE = 1; //enable all interrupts globally
while(1)
{
PORTD = PORTC;
delay(500); //After 500 ms
INTCONbits.INT0IF = 1; //Flag
}
}
void INT0_ISR(void)
{
mybit=~mybit; //Toggle LED
INTCONbits.INT0IF = 0; //clear INT0 Flag
}
void delay(unsigned int delayInput) {
unsigned int mul = delayInput/50;
unsigned int count = 0;
for (count = 0; count <= mul; count ++)
__delay_ms(50);
}

Why does UART transmit interrupt fail to work in this case?

I am using stm32f0 MCU.
I have a simple UART echo code in which every byte received will be transmitted out. I tested that it works. Here it is;
uint8_t Rx_data[5];
uint32_t tx_timeout = 0;
//Interrupt callback routine
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1) //current UART
{
HAL_UART_Transmit(&huart1, &Rx_data[0], 1, tx_timeout);
HAL_UART_Receive_IT(&huart1, Rx_data, 1); //activate UART receive interrupt every time on receiving 1 byte
}
}
I do not feel comfortable with the code even though it works. Firstly, tx_timeout is 0 and most code examples are non-zero. I do not know the side effect. Secondly, HAL_UART_Transmit() is a blocking call and it is not advisable to use blocking calls inside an interrupt. So, I decided to use an interrupt for uart transmission HAL_UART_Transmit_IT()instead of a blocking call. Here is the modified code;
uint8_t Rx_data[5];
uint32_t tx_timeout = 0;
//Interrupt callback routine
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1) //current UART
{
HAL_UART_Transmit_IT(&huart1, &Rx_data[0], 1);
HAL_UART_Receive_IT(&huart1, Rx_data, 1); //activate UART receive interrupt every time on receiving 1 byte
}
}
However, it does not work as expected. My PC transmits ASCII 12345678 to stm32. If things work as expected, the PC should be receiving 12345678 back. However, the PC receives 1357 instead. What is wrong with this code that uses HAL_UART_Transmit_IT()?
First:
As has been described in answers to your previous question null timeout just exclude wait for flag state. If you open HAL_UART_Transmit code - you will see that when you send 1 byte without timeout no any blocking state will!
Second:
It's not true method to send/receive one byte from a huge HAL's functions and their callbacks. I guess: next your question will "how i must implement parse there?". And I hope you will not insert you parse function in IRQ callback!
So generally you need buffers. And it is good idea to use cyclic buffer.
mxconstants.h:
/* USER CODE BEGIN Private defines */
/* Buffer's length must be select according to real messages frequency */
#define RXBUF_LEN 128 // must be power of 2
#define TXBUF_LEN 128 // must be power of 2
#define RXBUF_MSK (RXBUF_LEN-1)
#define TXBUF_MSK (TXBUF_LEN-1)
/* USER CODE END Private defines */
main.c:
uint8_t rx_buf[RXBUF_LEN], tx_buf[TXBUF_LEN];
/* xx_i - counter of input bytes (tx - pushed for transmit, rx - received)
xx_o - counter of output bytes (tx - transmitted, rx - parsed)
xx_e - counter of echoed bytes */
volatile uint16_t rx_i = 0, tx_o = 0;
uint16_t rx_o = 0, rx_e = 0, tx_i = 0;
volatile uint8_t tx_busy = 0;
void transmit(uint8_t byte)
{
tx_buf[TXBUF_MSK & tx_i] = byte;
tx_i++;
tx_busy = 1;
__HAL_UART_ENABLE_IT(&huart1, UART_IT_TXE);
}
void main(void)
{
/* Initialization code */
/* ... */
/* Enable usart 1 receive IRQ */
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
for (;;) {
/* Main cycle */
while (rx_i != rx_e) {
/* echo here */
transmit(rx_buf[RXBUF_MSK & rx_e]);
rx_e++;
}
while (rx_i != rx_o) {
/* parse here */
/* ... */
rx_o++;
}
/* Power save
while (tx_busy);
HAL_UART_DeInit(&huart1);
*/
}
}
stm32f0xx_it.c:
extern uint8_t rx_buf[RXBUF_LEN], tx_buf[TXBUF_LEN];
extern volatile uint16_t rx_i, tx_o;
extern uint16_t rx_o, rx_e, tx_i;
extern volatile uint8_t tx_busy;
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
if((__HAL_UART_GET_IT(&huart1, UART_IT_RXNE) != RESET) &&
(__HAL_UART_GET_IT_SOURCE(&huart1, UART_IT_RXNE) != RESET))
{
rx_buf[rx_i & RXBUF_MSK] = (uint8_t)(huart1.Instance->RDR & 0x00FF);
rx_i++;
/* Clear RXNE interrupt flag */
__HAL_UART_SEND_REQ(&huart1, UART_RXDATA_FLUSH_REQUEST);
}
if((__HAL_UART_GET_IT(&huart1, UART_IT_TXE) != RESET) &&
(__HAL_UART_GET_IT_SOURCE(&huart1, UART_IT_TXE) != RESET))
{
if (tx_i == tx_o) {
__HAL_UART_DISABLE_IT(&huart1, UART_IT_TXE);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_TC);
} else {
huart1.Instance->TDR = (uint8_t)(tx_buf[TXBUF_MSK & tx_o] & (uint8_t)0xFF);
tx_o++;
}
}
if((__HAL_UART_GET_IT(&huart1, UART_IT_TC) != RESET) &&
(__HAL_UART_GET_IT_SOURCE(&huart1, UART_IT_TC) != RESET))
{
tx_busy = 0;
__HAL_UART_DISABLE_IT(&huart1, UART_IT_TC);
}
/* And never call default handler */
return;
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
And third!!!
And about this:
Why HAL_UART_Transmit_IT not help/work?
Because it's too slow! And if you try to count HAL_BUSY results:
uint8_t Rx_data[5];
uint32_t tx_timeout = 0;
//Interrupt callback routine
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
static uint32_t hal_busy_counter = 0;
if (huart->Instance == USART1) //current UART
{
if (HAL_UART_Transmit_IT(&huart1, &Rx_data[0], 1) == HAL_BUSY) {
hal_busy_counter++;
}
HAL_UART_Receive_IT(&huart1, Rx_data, 1); //activate UART receive interrupt every time on receiving 1 byte
}
}
When you pause MCU in debugger after data exchange - you will be suprised: it will be equal to count of missed chars.