UART qt в микроконтроллер, не может правильно отправлять данные

У меня была одна и та же проблема несколько раз со многими разными микроконтроллерами. Сегодня я хотел бы наконец решить это.

Эта проблема:

Я пытаюсь отправить данные из моего интерфейса Qt на мой микроконтроллер.
Теперь я могу отправить его, и мой mc получает мои данные (уверен на 100%).
Каждый раз, когда я отправляю данные на мой mc, светодиод должен мигать.
Но … В какой-то момент мой светодиод мигает, а в некоторых — нет.
Когда я посылаю только «D», нет никаких проблем, я вижу, что мой светодиод мигает.
Но когда я посылаю «Hello world D \ n», светодиод не мигает.

Зачем? пожалуйста

мой код Qt:

Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
//SETS up my serial port
serialPort = new QSerialPort(this);
serialPort->setPortName("COM13");
serialPort->setBaudRate(QSerialPort::Baud115200);

if (!serialPort->open(QIODevice::ReadWrite))
{
qDebug("some error when opening\n");
}

}

void Widget::on_pushButton_clicked()
{

if(ui->radioButton->isChecked()==true)
{
serialPort->write("Hello world D\n"); //doesn't work fine
}

else if(ui->radioButton_3->isChecked()==true)
{
serialPort->write(" D\n"); //works fine
}

}

Мой код микроконтроллера:

void blinkLed()
{

volatile uint32_t ui32Loop;
SYSCTL_RCGCGPIO_R = SYSCTL_RCGCGPIO_R12;
ui32Loop = SYSCTL_RCGCGPIO_R;
GPIO_PORTN_DIR_R = 0x01;
GPIO_PORTN_DEN_R = 0x01;

while(1)
{
GPIO_PORTN_DATA_R |= 0x01;
for(ui32Loop = 0; ui32Loop < 200000; ui32Loop++)
{
}
GPIO_PORTN_DATA_R &= ~(0x01);
for(ui32Loop = 0; ui32Loop < 200000; ui32Loop++)
{
}
}
}void
UARTIntHandler(void)
{int j=0;
int ulStatus=0;for(j=0;j<20;j++)
{
receivedDataQt[j] = UARTCharGet(UART0_BASE);
if(receivedDataQt[j]=='D')
{
gotDataQt=1; //this is a global variable
break;
}
}

ulStatus = UARTIntStatus(UART0_BASE, true);
UARTIntClear(UART0_BASE, ulStatus);
initUART(); //re setup UART after interrupt
}

int main(void)
{

while(1)
{
initUART();
setUARTinterrupt();

setupI2c();
setupSensor();

while(1)
{
// communicate with sensor

if(gotDataQt==1) //when it returns from the interrupt this (global) bit  is set
{
blinkLed(); //makes my led
gotDataQt=0;
}}

}
}

1

Решение

Проблема заключается в том, что вы пытаетесь прочитать несколько символов в обработчике прерываний, не проверяя, доступно ли больше символов. Общий подход — это код, похожий на следующий, который читает один символ на прерывание:

#define BUF_SIZE 20
volatile int j;

void UARTIntHandler(void)
{
int ulStatus=0;
ulStatus = UARTIntStatus(UART0_BASE, true);
while(UARTCharsAvail(UART0_BASE))
{
char c = UARTCharGet(UART0_BASE);
if (j < BUF_SIZE)
receivedDataQt[j++] = c;
if (c == 'D')
gotDataQt=1; //this is a global variable
}
UARTIntClear(UART0_BASE, ulStatus);
}

int main(void)
{
while(1)
{
initUART();
setUARTinterrupt();

setupI2c();
setupSensor();
j = 0;

while(1)
{
if(gotDataQt==1) //when it returns from the interrupt this (global) bit  is set
{
blinkLed(); //makes my led
j = 0;
gotDataQt=0;
}
}
}
}

Вышеприведенное не проверено, и я не знаком с используемым вами микроконтроллером, поэтому может потребоваться некоторая работа в соответствии с вашим приложением, но несколько вещей, на которые следует обратить внимание:

  • Убедитесь, что доступно больше символов, и не пытайтесь повторно инициализировать UART при каждом прерывании, в этом нет необходимости.
  • Вы, вероятно, не хотите прерываться таким образом, потому что он пропустит ваш код, который устанавливает его в следующий раз.
  • декларировать j а также gotDataQt как изменчивый, когда они могут быть изменены в прерывании.
  • Взгляните на ключевое слово volatile и атомарные операции. Если вы используете 8-битный микроконтроллер и 8-битные типы данных, как правило, операция будет атомарной, но, скажем, они 8-битные на 8-битном микро, вы можете отключить прерывания при чтении / записи в основном коде, чтобы не допускать чтения и записи, когда при прерывании была записана только часть данных.

В общем, лучше всего попытаться сделать так, чтобы подпрограммы прерывания делали как можно меньше и избегали каких-либо задержек и циклов внутри них, поэтому ваш общий подход к использованию флагов и выполнению миганий светодиодов и т.п. в основном коде хорош.

1

Другие решения


По вопросам рекламы [email protected]