scanf problem

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I asked this in the other forum, but this one might be better.
The thing is that I have problems with scanf. Ok, everybody tells me not to use it since it eats a lot of memory. I know, was just playing around....

The problem is best described by showing the following code. Please note the commented block.


int main (void) 
{ 

   char test[16]; 
   int k, res; 
    ioinit(); //Setup IO pins and defaults 
 
    while(1) 
    { 
/*    
   printf("Waiting for string input:\n"); 
   res = scanf("%s", test); 
   printf("res %d \n %s\n", res, test); 
*/ 
   printf("Waiting for int input:\n"); 
   res = scanf("%3d", &k); 
   printf("res %d \n %d\n", res, k); 
    
   } 
    
    return(0); // never get here 
} 

the output is as follows with only the int reading when I input once a non-int character (e.g. a 'y'). It will never stop and run continuesly :

res 0 
0 
Waiting for int input: 
res 0 
0 
Waiting for int input: 
res 0 
0 
Waiting for int input: 
res 0 

That's not good.

Now if I include the string input routine it works correct:

Waiting for string input: 
res 1 
test1 
Waiting for int input: 
res 1 
123 
Waiting for string input: 
res 1 
test2 
Waiting for int input: 
res 1 
321 
Waiting for string input: 

and now if I put a 'y' at the prompt for an int:

Waiting for string input: 
res 1 
hallo 
Waiting for int input: 
res 1 
0 
Waiting for string input: 
res 1 
ahallo2 
Waiting for int input: 
res 1 
222 
Waiting for string input: 

Apparantly res=1 even when a rubbisch character for the int is put in...

Questions:

- Am I doing the routines correctly?
- Is the scanf routine buggy?

Ps. I use the latest winavr / avr studio

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
- Am I doing the routines correctly?

Since you haven't given us any indication as to how you set up scanf, it makes it impossible to tell.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ok c file:


/*
    Simple serial i/o without interrupts
*/

#include 
#include 
#include 
#include 
#include 
//#include 
#include "rs232-t.h"


//Define functions
//======================			
void ioinit(void);     							// initializes IO
static int uart_putchar(char c, FILE *stream);	// stream based i/o. used for printf and scanf (?buggy?).
static int uart_getchar(FILE *stream);
uint8_t uart_get_c(void); 						// gets ascii character

static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);


//======================

int main (void)
{

	char test[16];
	int  k, res;
	
    ioinit(); //Setup IO pins and defaults

	

    while(1)
    {
	
	

/*	printf("Waiting for input: "); 
	k = uart_get_c();
	printf("scancode= %d , character=%c \n", k, k);
	if (k == 'y') printf("you typed a 'y'\n");
*/

	
    /*    
   printf("Waiting for string input:\n"); 
   res = scanf("%s", test); 
   printf("res %d \n %s\n", res, test); 
*/ 
   printf("Waiting for int input:\n"); 
   res = scanf("%3d", &k); 
   printf("res %d \n %d\n", res, k); 

	}
   
    return(0); // never get here
}




void ioinit (void)
{
 
// set default baud rate 
    UART0_UBRR_HIGH = UART_BAUD_SELECT >> 8;  

    UART0_UBRR_LOW	= UART_BAUD_SELECT;  


#if defined (ATMEGA_USART)
    // enable receive, transmit and ensable receive interrupts 
    UART0_CONTROL = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
    // set default format, asynch, n,8,1
    #ifdef URSEL
    	UCSRC = (1<<URSEL)|(3<<UCSZ0);
    #else
    	UCSRC = (3<<UCSZ0);
    #endif 
    
#elif defined (ATMEGA_USART0 )
    // enable receive, transmit and ensable receive interrupts 
    UART0_CONTROL = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);
    // set default format, asynch, n,8,1
 /*   #ifdef URSEL0
	    UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
    #else
    	UCSR0C = (3<<UCSZ00);
    #endif 
*/
#endif

    // enable interrupts 
    //sei();


    
    stdout = stdin = &mystdout; //Required for printf init
	
}



static int uart_putchar(char c, FILE *stream)
{
    if (c == '\n') uart_putchar('\r', stream);
  
    loop_until_bit_is_set(UCSR0A, UDRE0);
    UDR0 = c;
    
    return 0;
}

static int uart_getchar(FILE *STREAM)
{
    while( !(UCSR0A & (1<<RXC0)) );
    return(UDR0);
}

uint8_t uart_get_c(void)
{
    while( !(UCSR0A & (1<<RXC0)) );
    return(UDR0);
}

h file:


#define sbi(var, mask)   ((var) |= (uint8_t)(1 << mask))
#define cbi(var, mask)   ((var) &= (uint8_t)~(1 << mask))

#define STATUS_LED 0

// requires the constant F_CPU to be set to the frequency of the CPU crystal 
#if !defined F_CPU
#error Constant F_CPU not set !
#endif



#if defined(__AVR_ATmega8__)  	|| defined(__AVR_ATmega16__) || 	\
	defined(__AVR_ATmega32__) 	|| defined(__AVR_ATmega8515__) || 	\
	defined(__AVR_ATmega8535__) || defined(__AVR_ATmega323__)    
	 
//
// Single USART devices
//
#define ATMEGA_USART
#define UART0_UBRR_HIGH 	UBRRH
#define UART0_UBRR_LOW 	UBRRL
#define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
#define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
#define UART0_STATUS		UCSRA
#define UART0_CONTROL  	UCSRB
#define UART0_DATA     	UDR
#define UART0_UDRIE    	UDRIE


#elif defined(__AVR_ATmega168__)
#define ATMEGA_USART0
#define UART0_UBRR_HIGH 	UBRR0H
#define UART0_UBRR_LOW 	    UBRR0L
#define UART0_RECEIVE_INTERRUPT   SIG_USART_RECV
#define UART0_TRANSMIT_INTERRUPT  SIG_USART_DATA
#define UART0_STATUS		UCSR0A
#define UART0_CONTROL  	UCSR0B
#define UART0_DATA     	UDR0
#define UART0_UDRIE    	UDRIE0

#elif defined(__AVR_ATmega644__)

#define ATMEGA_USART0
#define UART0_UBRR_HIGH 	UBRR0H
#define UART0_UBRR_LOW 	    UBRR0L
#define UART0_RECEIVE_INTERRUPT   SIG_USART_RECV
#define UART0_TRANSMIT_INTERRUPT  SIG_USART_DATA
#define UART0_STATUS		UCSR0A
#define UART0_CONTROL  	UCSR0B
#define UART0_DATA     	UDR0
#define UART0_UDRIE    	UDRIE0

#elif 	defined(__AVR_ATmega162__) || \
	 	defined(__AVR_ATmega64__)  || \
		defined(__AVR_ATmega128__) 
//
// Dual USART devices
//
#define ATMEGA_USART0
#define UART0_UBRR_HIGH  	UBRR0H
#define UART0_UBRR_LOW   	UBRR0L
#define UART0_RECEIVE_INTERRUPT   SIG_USART0_RECV
#define UART0_TRANSMIT_INTERRUPT  SIG_USART0_DATA
#define UART0_STATUS    	UCSR0A
#define UART0_CONTROL   	UCSR0B
#define UART0_CONTROL2  	UCSR0C
#define UART0_DATA     	UDR0
#define UART0_UDRIE    	UDRIE0

#define ATMEGA_USART1
#define UART1_UBRR_HIGH  	UBRR1H
#define UART1_UBRR_LOW   	UBRR1L
#define UART1_RECEIVE_INTERRUPT   SIG_USART1_RECV
#define UART1_TRANSMIT_INTERRUPT  SIG_USART1_DATA
#define UART1_STATUS    	UCSR1A
#define UART1_CONTROL   	UCSR1B
#define UART1_CONTROL2  	UCSR1C
#define UART1_DATA     	UDR1
#define UART1_UDRIE    	UDRIE1

#else
//
// unsupported type
//
#error "Processor type not supported in uart.c !"
#endif

//
// UART Default Baud rate calculation 
//
#define UART_BAUD_RATE			115200	    // On some computers this introduces errors. 
											// Too fast to receive. perhaps a jumper/test on the atmega and using setspeed?
// #define U2X 0							// not using u2x
// u2x0 for atmega644
#define USING_U2X0 (F_CPU < 2000000ul && defined(U2X0)) 
#define BAUD_DIV (USING_U2X0? 8: 16) 

#define UART_BAUD_SELECT (((F_CPU + (UART_BAUD_RATE) * (BAUD_DIV / 2)) / ((UART_BAUD_RATE) * BAUD_DIV) - 1)) 


  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But you've got the same topic going over in the AVR forum!

How many times do you think you need to post this topic to get answers?

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

Topic locked