UART_RxChar() is waiting for all the time untill data is received. But I want to stop waiting for the data received and run my while(1) loop continuosly. So I want to stop UART_RxChar() after about 1 second waiting and run while(1) loop continuously. This is my code. How should I change it... Can someone help me with this.
#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;
}
}
}
You have several design problems in your code:
delay_ms
and similar will block other parts of your code from executing. While such delays are tempting to get a simple program running for the first time, keeping such design issues will be a real pain as your application will grow and address more complex tasks. Example is the blocking implementation of key debounce. It's better to have a timer interrupt running, and then based on that check PORTA every, say, 10ms..20ms (at 50Hz..100Hz). This is enough for debouncing. Depending on the read value, the main program decides whether it's a short or long key-press or maybe a double-click.
while(wait_for_event)
is also blocking your application. For example,
while ((UCSRA & (1 << RXC)) == 0);/* Wait till data is received */
is blocking your whole application until UART receives something. It works for simple programs but for programs beyond trivial ones it is often an issue. In the case of UART receive / transmit, you's also use some of the UART interrupts. If you prefer polling over interrupts, then write polling in such a way that it does not block other stuff forever.
In general, the structure of you main loop would be
while (1)
{
if (condition_1)
{
reset_condition_1();
nonblocking_action_for_condition_1();
}
if (condition_2)
{
reset_condition_2();
nonblocking_action_for_condition_2();
}
}
For example, sometimes I am using polling for simple UART receive like so (on your device SFRs might be different):
int uart_getc_nowait (void)
{
return (UCSRA & (1 << RXC)) ? 0xff & UDR : -1;
}
This is non-blocking: Other parts of the code will only take actions if this function returns 0...255.
When you are transmitting data, you can consider using a FIFO: You would write the string to a FIFO, and an ISR would pick individual bytes and send them. Pseudo code:
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;
}
}