Thread: Uart interrupt triggers after one keystroke

  1. #1
    Registered User
    Join Date
    Mar 2014
    Posts
    7

    Uart interrupt triggers after one keystroke

    Can someone explain to me why i can only take in a single keystroke from hyperterminal/putty for the embedded program pasted below (main.c and retarget.c) before the ISR triggers.
    Ultimately I would like to take in and store a larger number than a single digit.
    I have tried increasing the size of ch[16], i understand that this is the input array size but i can only get it working with 16, is this because an integer is 16 bits?

    The hardware is arm m0 based and the uart is implemented in hardware(memory mapped)

    Code:
    //------------------------------------------------------------------------------
    // main.c
    //------------------------------------------------------------------------------
    
    
    #include <stdio.h>
    #include <time.h>
    #include <rt_misc.h>
    #include <stdlib.h>
    
    
    #define AHB_LED_BASE				0x50000000
    #define AHB_UART_BASE				0x51000000
    
    
    
    
    void UART_ISR(void)
    {
    			int sample;
    			char ch [16];
    			sample = atoi (ch);
    			printf("the value entered is %d\n", sample);
    }
    
    
    //////////////////////////////////////////////////////////////////
    // Main Function
    //////////////////////////////////////////////////////////////////
    
    
    int main() {
    	
    	{
    		char ch [16];
    		fgets (ch, 16, stdin);
    	}
    }

    Code:
    #include <stdio.h>
    #include <time.h>
    #include <rt_misc.h>
    
    
    #define AHB_LED_BASE				0x50000000
    #define AHB_UART_BASE				0x51000000
     
    #pragma import(__use_no_semihosting)
    
    
    struct __FILE { 
    	unsigned char * ptr;
    	};
    
    
    FILE __stdout = 	{(unsigned char *)	AHB_UART_BASE};
    FILE __stdin = 		{(unsigned char *)	AHB_UART_BASE};
    
    
    int fputc(int ch, FILE *f)
    {
      return(uart_out(ch));
       
    }
    
    
    int fgetc(FILE *f)
    { 
     	return(uart_in());
    }
    
    
    int ferror(FILE *f)
    {
      return 0; 
    }
    
    
    int uart_out(int ch)
    {
    	int* UARTPtr;
    	UARTPtr = (int*)AHB_UART_BASE;
    	*UARTPtr = (int)ch;
    	return(ch);
    }
    
    
    int uart_in()
    {
    	int ch;
    	int* UARTPtr;
    	UARTPtr = (int*)AHB_UART_BASE;	
    	ch = *UARTPtr;
    	uart_out(ch);
    	return((int)ch);
    }
    
    
    void _ttywrch(int ch)
    { 
      fputc(ch,&__stdout); 
    }
    
    
    void _sys_exit(void) {
    
    
    
    
    	while(1); 
    	
    }

  2. #2
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,859
    I don't know enough about your environment to know how the semihosting works

    However, when you usually deal with UART/USART the input is unbuffered

    The way you would implement a buffer is usually something like:
    Put input on buffer
    Is the input '\n'
    yes: Signal new input
    no: Move on with code
    Fact - Beethoven wrote his first symphony in C

  3. #3
    Registered User
    Join Date
    Mar 2014
    Posts
    7
    I'm sorry im just starting out with c, could you explain this further? Could i put fgets on a loop till i get the full number?
    Last edited by munchie146; 03-30-2014 at 05:25 PM.

  4. #4
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,859
    could you write this for me?
    For free?!?!?!?!?!...

    ?!?!?!?!?...

    ??...


    But seriously, declare and array and put the chars in the array. It's not that hard once you think about it.
    Fact - Beethoven wrote his first symphony in C

  5. #5
    Registered User
    Join Date
    Mar 2014
    Posts
    7
    apologies, i edited just before you posted that. Bit cheeky of me! haha. So define the array size and loop fgets till the array is filled?

  6. #6
    Registered User
    Join Date
    Apr 2013
    Posts
    1,654
    Even in the case of a buffered UART, the input interrupt will be asserted when ever there's one or more characters in the input buffer. For output the output interrupt will be asserted whenever there is space in the UART's output buffer, so it's normally disabled by software until one or more output characters have been transferred to the UART, in which case it's enabled, then for each interrupt, another character is output from an interrupt processed software buffer or if that buffer is empty, the transmit interrupt is disabled. A separate status bit usually needs to be polled to determine when all character's in the UART's transmit buffer have been transmitted.

  7. #7
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,859
    I'd have a way of telling when you are at the end of a packet

    I usually put packets between '<' and '>' so I can easily see when the start and finish is -> Other systems have a \n, you could also have a \0

    If you wait for the array to be completely full, you may loose data.

    I'd be more inclined to use fgetc then fgets.
    Fact - Beethoven wrote his first symphony in C

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. UART Serial Communication
    By VoqionXazr in forum Networking/Device Communication
    Replies: 2
    Last Post: 11-03-2013, 11:50 PM
  2. Getting a string from the UART/COM port
    By thatchergrey in forum C Programming
    Replies: 10
    Last Post: 01-23-2009, 04:18 AM
  3. loading struct from UART received data
    By droseman in forum C Programming
    Replies: 19
    Last Post: 01-08-2009, 09:38 AM
  4. 16450 UART interupt issue
    By abachler in forum Networking/Device Communication
    Replies: 4
    Last Post: 04-25-2008, 12:50 PM
  5. Bluetooth UART
    By ssharish2005 in forum Tech Board
    Replies: 2
    Last Post: 02-06-2008, 06:31 AM

Tags for this Thread