在中断处理程序STM32F407中禁用中断 [英] Disabling interrupt in interrupt handler STM32F407

查看:742
本文介绍了在中断处理程序STM32F407中禁用中断的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来的,我正在尝试解决我的项目问题。我正在尝试通过UART将发送数据从Raspberry Pi B +发送到我的STM32F407,并实时处理该数据。我的问题是:如何实际同步main()thred和UART中断处理程序,使其长时间不停止UART中断。从Raspberry发送的数据看起来像(其中n是数字):nwnx代码:

I'm new here and I'm trying to solve my projects problem. I'm trying to send send data over UART from Raspberry Pi B+ to my STM32F407 and process that data in real-time. My problem is: How to actually synchronize main() thred and UART interruption handler not to stop for a long time my UART interruption. Data sent from Raspberry looks like (where n is number): nwnx Code:

void UART4_IRQHandler(void)
{
    if(USART_GetITStatus(UART4, USART_IT_RXNE))
    {
        if(!flag)
        {
            processing = true;
            widthTemp[j] = USART_ReceiveData(UART4);
            USART_ClearITPendingBit(UART4, USART_IT_RXNE);

            if(widthTemp[j] != 'w')
            {
                j++;
            }
            else
            {
                j = 0;
                flaga = true;
                processing = false;
                //__disable_irq();
                NVIC_DisableIRQ(UART4_IRQn);
            }
        }else if(flag)
        {
            processing = true;
            heightTemp[j] = USART_ReceiveData(UART4);
            USART_ClearITPendingBit(UART4, USART_IT_RXNE);

            if(heightTemp[j] != 'x')
            {
                j++;
            }
            else
            {
                j++;
                heightTemp[j] = '\n';
                j = 0;
                processing = false;
                flag = false;
                NVIC_DisableIRQ(UART4_IRQn);
            }
        }
    }
}

现在的主要代码:

while (1)
{
    if(!NVIC_GetPendingIRQ(UART4_IRQn))
    {
        //if()
        if(flag == true && processing == false)
        {
            sscanf(heightTemp, "%d", &height );
            USART_puts(UART4, heightTemp); // sending back data to raspberry (temporary)
            for(i = 0; i< sizeof(widthTemp);i++)
            {
                heightTemp[i] = '\0';
            }
            NVIC_EnableIRQ(UART4_IRQn);
        }
        if(flag == false && processing == false)
        {
            sscanf(widthTemp, "%d", &width );
            USART_puts(UART4, widthTemp); // sending back data to raspberry (temporary)
            for(i = 0; i< sizeof(widthTemp);i++)
            {
                widthTemp[i] = '\0';
            }
            NVIC_EnableIRQ(UART4_IRQn);
        }
    }
}

我的问题是

问题:
1.我可以像在代码中那样禁止中断处理程序中的中断吗?我的main()知道它可以继续处理数据吗?如果是,我是否要为此任务检查好注册?
2.是否有更好的方法将缓冲区(widthTemp f.e.)发送到某个变量?也许我不需要像这样使我的代码复杂化。
3.我可以在代码中使用thred吗?有帮助吗?
4.这是我的第一篇文章,所以有关如何格式化问题,有关代码的建议等的任何信息都将很不错。

Questions: 1. Can I disable interruptions in interruption handler like I did in my code to let my main() know that it can proceed data ? And if yes, do I check good register for this task ? 2. Is there a better way to send buffer (widthTemp f.e.) to some variable ? Maybe I don't need to complicate my code like this. 3. Can I use maybe threding in my code ? Will it help ? 4. This is my first post so any information about how to format questions, advices about the code etc. will be nice.

推荐答案

通常,您的UART ISR应该做的事情不外乎:

In general, your UART ISR should do little more than:


  • 对于接收中断,将来自RXD的字符放入一个环形缓冲区

  • 用于发送中断,从环形缓冲区获取字符并将其放置在TXD中。在STM32上,如果环形缓冲区为空,则必须显式关闭发送器。

  • 清除中断标志(错误标志的处理可选)。

  • For a receive interrupt, place character from RXD in a ring buffer
  • for a transmit interrupt, get character from a ring buffer and place it in TXD. On STM32, if the ring buffer is empty, you must explicitly switch off the transmitter.
  • clear interrupt flags (handling of error flags optional).

然后,您的主线程(或其他一些线程/任务,如果使用线程调度程序或RTOS),只需从Rx环形缓冲区读取(或写入Tx环形缓冲区)。

Then your main thread (or some other thread/task if using an thread scheduler or RTOS), simply reads from the Rx ring buffer (or writes to the Tx ring buffer).

请注意,在STM32上,如果发送器未运行,则第一个字符应直接放置在TXD中,然后发送器启动,然后将后续字符放置在Tx环中

Note that on STM32 if the transmitter is not running, the first character should be placed directly in TXD, and the transmitter started, subsequent characters are then places in the Tx ring buffer.

如果使用RTOS或其他操作系统,则可以使用队列或邮箱,而不是实现自己的环形缓冲区。当有多个上下文正在访问控制数据时,需要格外小心以确保一致的缓冲区控制。

If using an RTOS or other OS, you might use a queue or mailbox rather then implementing your own ring buffer. Some care is required to ensure consistent buffer control when more than one context is accessing the control data.

请注意,STM32能够使用DMA传输至UART操作,这可能会提供了一种替代解决方案,特别是在数据速率非常快的情况下,因为STM32 UART没有FIFO,并且如果在接收另一个字符的时间内没有从RXD中删除每个字符,它将超出RXD。

Note that the STM32 is capable of using DMA transfers to UART operation which may offer an alternative solution, especially if the data rate is very fast, since the STM32 UART has no FIFO and will overrun the RXD if each character is not removed from RXD in the time taken to receive another.

这篇关于在中断处理程序STM32F407中禁用中断的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆