UART qt到微控制器,无法正常发送数据

时间:2015-04-04 08:28:49

标签: c++ qt microcontroller uart

我使用许多不同的微控制器多次遇到同样的问题。今天我想最终解决这个问题。

问题:

我正在尝试将数据从我的Qt UI发送到mycrocontroller。 现在我能够发送它,我的mc接收我的数据(100%肯定)。 每次我向我的mc发送数据时,LED应该闪烁。 但是......在某些时刻,我的领导眨眼,有时候却没有。 当我只发送'D'时,没有问题,我可以看到我的指示灯闪烁。 但是当我发送“Hello world D \ n”时,led不会闪烁。

为什么呢?请

我的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 个答案:

答案 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,这不是必需的。
  • 您可能不希望以某种方式突破中断,因为它会跳过您下次设置它的代码。
  • 当在中断中更改它们时,将jgotDataQt声明为易失性。
  • 查看volatile关键字和原子操作。如果您通常使用8位微控制器和8位数据类型,则操作将是原子操作,但是在8位微控制器上它们是16位,您可能希望在读取/写入时禁用中断代码,以防止读取和写入中断发生时只写入部分数据的内容。

一般来说,尝试使中断例程做得尽可能少,并避免其中的任何延迟和循环,因此您在主代码中使用标志和执行LED闪烁等的一般方法是好。