У меня была одна и та же проблема несколько раз со многими разными микроконтроллерами. Сегодня я хотел бы наконец решить это.
Эта проблема:
Я пытаюсь отправить данные из моего интерфейса 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;
}}
}
}
Проблема заключается в том, что вы пытаетесь прочитать несколько символов в обработчике прерываний, не проверяя, доступно ли больше символов. Общий подход — это код, похожий на следующий, который читает один символ на прерывание:
#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;
}
}
}
}
Вышеприведенное не проверено, и я не знаком с используемым вами микроконтроллером, поэтому может потребоваться некоторая работа в соответствии с вашим приложением, но несколько вещей, на которые следует обратить внимание:
j
а также gotDataQt
как изменчивый, когда они могут быть изменены в прерывании. В общем, лучше всего попытаться сделать так, чтобы подпрограммы прерывания делали как можно меньше и избегали каких-либо задержек и циклов внутри них, поэтому ваш общий подход к использованию флагов и выполнению миганий светодиодов и т.п. в основном коде хорош.