【问题标题】:Want to stop UART_RxChar() , waiting for data received UART_RxChar() after about 1 second and run while(1) loop continuously想要停止 UART_RxChar() ,等待大约 1 秒后接收到数据 UART_RxChar() 并连续运行 while(1) 循环
【发布时间】:2020-01-26 05:53:03
【问题描述】:

UART_RxChar() 一直在等待,直到接收到数据。但我想停止等待接收到的数据并连续运行我的 while(1) 循环。所以我想在等待大约 1 秒后停止 UART_RxChar() 并连续运行 while(1) 循环。这是我的代码。我应该如何改变它...有人可以帮我解决这个问题。


    #define F_CPU 8000000UL         /* Define frequency here its 8MHz */
    #include <avr/io.h>
    #include <util/delay.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #define USART_BAUDRATE 9600
    #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)


    void UART_init(void)
    {
        UBRRH = (BAUD_PRESCALE >> 8);   /* Load upper 8-bits*/
        UBRRL = BAUD_PRESCALE;      /* Load lower 8-bits of the baud rate value */
        UCSRB |= (1 << RXEN) | (1 << TXEN);/* Turn on transmission and reception */
        UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);/* Use 8-bit character sizes */


    }

    unsigned char UART_RxChar(void)
    {
        while ((UCSRA & (1 << RXC)) == 0);/* Wait till data is received */
        return UDR;         /* Return the byte*/
    }

    void UART_TxChar(uint8_t data)
    {
        while (! (UCSRA & (1<<UDRE)));  /* Wait for empty transmit buffer*/
        UDR = data ;
    }

    void UART_SendString(char *str)
    {
        for(int i=0;i<strlen(str);i++){
            UART_TxChar(str[i]);
        }
    }

    int main()
    {
        char RecievedByte;
        UART_init();
        DDRA=0x00;// for input port-LED
        DDRB=0xff;// for output port-Switch
        while(1)
        {
            if((PINA==0x01))// checking the status of PIN  PA0 (whether push button is pressed), if it is '1', turns on the LED
            {
                _delay_ms(100); // for debouncing of switch
                PORTB=0x01;   // Turning on the LED PB0
                _delay_ms(200);
                PORTB=0x00;

            }

            else if( (UART_RxChar()=='s'))// else checking whether 's'  is received, if it is '1', turns on the LED
            {       
                //want to ignore UART_RxChar()=='s' is waiting untill 's' is received after sometime and continiously run while(1) loop

                _delay_ms(100); // for debouncing of switch
                PORTB=0x02;   // Turning on the LED PB1
                _delay_ms(200);
                PORTB=0x00;

            }
        }   
    }

【问题讨论】:

    标签: interrupt uart serial-communication


    【解决方案1】:

    您的代码中有几个设计问题:

    delay_ms 类似的会阻止代码的其他部分执行。虽然这样的延迟很容易让一个简单的程序第一次运行,但保留这样的设计问题将是一个真正的痛苦,因为您的应用程序将增长并处理更复杂的任务。示例是键去抖的阻塞实现。最好运行一个定时器中断,然后基于该检查 PORTA 每隔 10ms..20ms(在 50Hz..100Hz 时)。这足以去抖动。根据读取的值,主程序决定是短按还是长按或双击。

    while(wait_for_event) 也阻止了您的应用程序。例如,

    while ((UCSRA & (1 << RXC)) == 0);/* Wait till data is received */
    

    阻塞了你的整个应用程序,直到 UART 接收到一些东西。它适用于简单的程序,但对于不重要的程序,它通常是一个问题。在 UART 接收/发送的情况下,您还使用了一些 UART 中断。如果你更喜欢轮询而不是中断,那么编写轮询时不要永远阻塞其他东西。

    一般来说,主循环的结构是

    while (1)
    {
        if (condition_1)
        {
           reset_condition_1();
           nonblocking_action_for_condition_1();
        }
        if (condition_2)
        {
           reset_condition_2();
           nonblocking_action_for_condition_2();
        }
    }
    

    例如,有时我会像这样使用轮询来进行简单的 UART 接收(您设备上的 SFR 可能不同):

    int uart_getc_nowait (void)
    {
        return (UCSRA & (1 << RXC)) ? 0xff & UDR : -1;
    }
    

    这是非阻塞的:代码的其他部分只有在此函数返回 0...255 时才会执行。

    当您传输数据时,您可以考虑使用FIFO:您会将字符串写入 FIFO,ISR 会选择单个字节并发送它们。伪代码:

    ISR (uart-dataregister-is-empty)
    {
        if (fifo-is-empty)
        {
            disable-uart-dataregister-is-empty-interrupt;
        }
        else
        {
            byte = read-one-byte-from-fifo;
            uart-dataregister = byte;
        }
    }
    
    void uart_putc (byte)
    {
        if (fifo-is-full)
        {  
            do-something-if-fifo-is-full;
        }
        else
        {
            write-byte-to-fifo;
            // Following action is no problem if respective IRQ is already enabled.
            enable-uart-dataregister-is-empty-interrupt;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-09-03
      • 1970-01-01
      • 2022-10-18
      • 2022-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多