想要停止 UART_RxChar() ,等待大约 1 秒后接收到数据 UART_RxChar() 并且 运行 while(1) 不断循环
Want to stop UART_RxChar() , waiting for data received UART_RxChar() after about 1 second and run while(1) loop continuously
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;
}
}
}
您的代码存在几个设计问题:
delay_ms
和类似的将阻止代码的其他部分执行。虽然这样的延迟很容易让您第一次获得一个简单的程序 运行,但随着您的应用程序不断增长并处理更复杂的任务,保留这样的设计问题将是一个真正的痛苦。示例是键去抖的阻塞实现。最好有一个定时器中断 运行,然后基于该中断每隔 10ms..20ms(50Hz..100Hz)检查一次 PORTA。这足以进行去抖动。根据读取的值,主程序决定是短按键还是长按键或者双击。
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;
}
这是非阻塞的:代码的其他部分将仅在该函数 returns 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;
}
}
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;
}
}
}
您的代码存在几个设计问题:
delay_ms
和类似的将阻止代码的其他部分执行。虽然这样的延迟很容易让您第一次获得一个简单的程序 运行,但随着您的应用程序不断增长并处理更复杂的任务,保留这样的设计问题将是一个真正的痛苦。示例是键去抖的阻塞实现。最好有一个定时器中断 运行,然后基于该中断每隔 10ms..20ms(50Hz..100Hz)检查一次 PORTA。这足以进行去抖动。根据读取的值,主程序决定是短按键还是长按键或者双击。
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;
}
这是非阻塞的:代码的其他部分将仅在该函数 returns 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;
}
}