problem about checking the USART receive data

Discussion in 'Embedded Systems and Microcontrollers' started by kj4g09, Nov 27, 2012.

  1. kj4g09

    Thread Starter New Member

    Dec 4, 2011
    29
    0
    Hello everyone, I want to use IF statement to check the data read in by USART, and according the data to do different things. But it seems like the If statement doesn't work at all.
    I am using RS232 to transmit data to Atmega48, I do have a chip to convert the voltage between uC and RS232.

    the code:

    unsigned int info;
    while(1)
    {
    info = USART_Receive();// say info == 0b1010XXXX;

    if((info >> 4) == 10)//ater right shift info ==0b00001010, which = 10
    {
    LED_ON;
    }

    USART_Write(info);// I can observe the "info" here to make sure the data //is correct.
    }

    the LED never lights up, I only send the data to uC once, so the infinite loop must be hold by the USART_Receive(); function after first data entered.
     
    Last edited: Nov 27, 2012
  2. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    5,071
    1,176
    And what did you do to debug this code? What is info equal to at the if statement?
     
  3. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    Why don't you try echoing the data back to the computer to see what's actually being received?

    Are you sure your baud rate is set correctly?
     
  4. kj4g09

    Thread Starter New Member

    Dec 4, 2011
    29
    0
    I tried to send that data back to PC using USART transmitter, and the data is the same one I send out. Which makes me confused why the LED_ON; in the if statement doesn't lights up.

    I also tried comment out the USART receive function, and just define a data = 1010XXX, to test the if statement, and the LED does lights up.
    the code is as simple as:

    unsigned int info = 0b1010XXXX;
    if((info >> 4) == 10)
    {
    LED_ON;
    }
     
  5. kj4g09

    Thread Starter New Member

    Dec 4, 2011
    29
    0
    the way I debug it is just load the code into uC first, and use PC to send a byte to the uC. and hoping the LED lights up which unfortunately does not.
    I also tried the code in #4, and that code can lights up the LED.

    the info in the if statement, in my opinion, will be shift right 4 bits first which will be equaled to 10 ((0b1010XXXX >> 4) == 0b00001010), and then the if statement will check if the info after it get shift by 4 bits equals to 10.
     
  6. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    What are you using to send the data? Are you using a terminal program, e.g. TeraTerm, Hyperterminal, Putty?
     
  7. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    5,071
    1,176

    Doesn't the Atmega48 environment have a debugger?? You should be able to set a breakpoint at the line and inspect values. It eliminates "assumptions".
     
  8. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    5,071
    1,176
    Can you write a program to simply turn on the LED? Forget about the if statement for now, just light the LED.
     
  9. kj4g09

    Thread Starter New Member

    Dec 4, 2011
    29
    0
    I use C# to send data to uC by opening the serial port and send the data.
     
  10. kj4g09

    Thread Starter New Member

    Dec 4, 2011
    29
    0
    Yes, that can be easy done on the same pin and different pin
     
  11. kj4g09

    Thread Starter New Member

    Dec 4, 2011
    29
    0
    The problem with this debugger is that the code will stop at the USART receive function. Im using Atmel Studio 6.
     
  12. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    Be sure that you are not sending an ASCII character as opposed to a binary sequence, otherwise, 4 becomes 0x34....

    If not, try posting the whole code so we can see what's going on...
     
  13. kj4g09

    Thread Starter New Member

    Dec 4, 2011
    29
    0
    Im sure the ASCII code is taken into account, Ill post my code as soon as I get back to my PC.
    Thank you very much.
     
  14. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    5,071
    1,176
    Not if you set the breakpoint properly.
     
  15. kj4g09

    Thread Starter New Member

    Dec 4, 2011
    29
    0
    im not really sure how to set the breakpoint properly. in the code, I have to read the in coming data first which give me no choice to put USART_receive function at the beginning of the code.
     
  16. kj4g09

    Thread Starter New Member

    Dec 4, 2011
    29
    0
    Code ( (Unknown Language)):
    1.  
    2. #include <avr/io.h>
    3. #include <util/delay.h>
    4.  
    5. void USART_Init( unsigned int ubrr);
    6. void USART_Transmit( unsigned int data );
    7. unsigned int USART_Receive( void );
    8.  
    9. #define MYUBRR 12
    10. #define F_CPU 1000000
    11.  
    12. //led
    13. #define LED1_ON    (PORTB |= (1<<PORT1));
    14. #define LED1_OFF   (PORTB &= (0<<PORT1));
    15.  
    16. int main(void)
    17. {
    18.     //led
    19.     DDRB = 0x02;
    20.     //USART output and input
    21.     DDRD = 0x02;
    22.  
    23. unsigned int info;
    24.     USART_Init(MYUBRR);
    25. while(1)
    26.     {
    27.         info = USART_Receive();
    28.        
    29.         if ( (info>> 4) == 10 )
    30.         {
    31.             LED1_ON;
    32.         }
    33.         USART_Transmit(info);
    34.    }
    35. }
    36. void USART_Init( unsigned int ubrr)
    37. {
    38.    
    39.     /*Set baud rate */
    40.     UBRR0H = (unsigned int)(ubrr>>8);
    41.     UBRR0L = (unsigned int)ubrr;
    42.     //UBRR0H = 0x00;
    43.     //UBRR0L = 0xc;
    44.     /*Set Double USART Transmission Speed */
    45.     UCSR0A = (1<<U2X0);// | (1<<UDRE0);
    46.     /*Enable receiver and transmitter */
    47.     UCSR0B = (1<<RXEN0) | (1<<TXEN0);
    48.     /*Set frame format: 8 data bits, 1 stop bit */
    49.     UCSR0C = (1 << UCSZ01) | (1 << UCSZ00) | (0 << USBS0) |
    50.     (0 << UPM01) | (0 << UPM00) | (0 << UMSEL01) |
    51.     (0 << UMSEL00);
    52. }
    53. void USART_Transmit( unsigned int data )
    54. {
    55.     /*Wait for empty transmit buffer */
    56.     while ( !( UCSR0A & (1<<UDRE0)));
    57.     /*Put data into buffer, sends the data */
    58.     UDR0 = data;
    59.     //data = 0;
    60. }
    61. unsigned int USART_Receive( void )
    62. {
    63.    
    64.     /*Wait for data to be received */
    65.     while ( !(UCSR0A & (1<<RXC0)) );
    66.     /*Get and return received data from buffer */
    67.     //counter += 1;
    68.     return UDR0;
    69. }
    70.  
     
    Last edited by a moderator: Nov 28, 2012
  17. kubeek

    AAC Fanatic!

    Sep 20, 2005
    4,688
    806
    You need to get better at debugging, do one small step at a time.
    First toggle the led on each received char.

    Also the #define LED1_ON (PORTB |= (1<<PORT1));
    #define LED1_OFF (PORTB &= (0<<PORT1)); doesn´t look correct, led off needs to be (PORTB &= ~(1<<4));if the led is on pin 5, similar for the led ON.
     
  18. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    5,071
    1,176
    You still have not told us if you can simply turn the LED on and off with some simple code. It should just take a few lines. Forget about the USART stuff for now. Get the LED working first.

    Once you have that working, you can set a breakpoint the line before this line with the changes below:

    if ( (info>> 4) == 10 )

    I would change it to this for debugging purposes

    info = info >> 4
    if ( info == 10 )

    Set the breakpoint on info = info >> 4 and inspect the value of info = info >> 4.

    Step through the >> 4 line and watch it change value. See if it is the value you are expecting.


    Hopefully you can limit the data sent to the mcu so you won't need to do too much stepping.
     
  19. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    OP seems to have mention that in #10....


    Also, I want to point out that
    Code ( (Unknown Language)):
    1. /*Set Double USART Transmission Speed */
    2.     UCSR0A = (1<<U2X0);// | (1<<UDRE0);
    doubles receiver speed, not transmission... I'd suggest going to regular speed as your timing requirements are stricter in 2x speed....It shouldn't make a difference, I just wanted to point that out...:p
     
  20. kj4g09

    Thread Starter New Member

    Dec 4, 2011
    29
    0
    I tried this method, but in order to do that, I have to comment out the USART_Receive function and define a value for 'info'. If I don't do that, the compiler will wait at code
    info = USART_Receive();
    function in order to assign data to 'info'.
     
Loading...