problem about checking the USART receive data

Thread Starter

kj4g09

Joined Dec 4, 2011
29
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:

tshuck

Joined Oct 18, 2012
3,534
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?
 

Thread Starter

kj4g09

Joined Dec 4, 2011
29
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;
}
 

Thread Starter

kj4g09

Joined Dec 4, 2011
29
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.
 

spinnaker

Joined Oct 29, 2009
7,830
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.

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".
 

Thread Starter

kj4g09

Joined Dec 4, 2011
29
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".
The problem with this debugger is that the code will stop at the USART receive function. Im using Atmel Studio 6.
 

tshuck

Joined Oct 18, 2012
3,534
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...
 

Thread Starter

kj4g09

Joined Dec 4, 2011
29
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...
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.
 

Thread Starter

kj4g09

Joined Dec 4, 2011
29
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.
 

Thread Starter

kj4g09

Joined Dec 4, 2011
29
Rich (BB code):
#include <avr/io.h>
#include <util/delay.h>

void USART_Init( unsigned int ubrr);
void USART_Transmit( unsigned int data );
unsigned int USART_Receive( void );

#define MYUBRR 12
#define F_CPU 1000000

//led
#define LED1_ON    (PORTB |= (1<<PORT1));
#define LED1_OFF   (PORTB &= (0<<PORT1));

int main(void)
{
    //led
    DDRB = 0x02;
    //USART output and input
    DDRD = 0x02;

unsigned int info;
    USART_Init(MYUBRR);
while(1)
    {
        info = USART_Receive();
        
        if ( (info>> 4) == 10 )
        {
            LED1_ON;
        }
        USART_Transmit(info);
   }
}
void USART_Init( unsigned int ubrr)
{
    
    /*Set baud rate */
    UBRR0H = (unsigned int)(ubrr>>8);
    UBRR0L = (unsigned int)ubrr;
    //UBRR0H = 0x00;
    //UBRR0L = 0xc;
    /*Set Double USART Transmission Speed */
    UCSR0A = (1<<U2X0);// | (1<<UDRE0);
    /*Enable receiver and transmitter */
    UCSR0B = (1<<RXEN0) | (1<<TXEN0);
    /*Set frame format: 8 data bits, 1 stop bit */
    UCSR0C = (1 << UCSZ01) | (1 << UCSZ00) | (0 << USBS0) |
    (0 << UPM01) | (0 << UPM00) | (0 << UMSEL01) |
    (0 << UMSEL00);
}
void USART_Transmit( unsigned int data )
{
    /*Wait for empty transmit buffer */
    while ( !( UCSR0A & (1<<UDRE0)));
    /*Put data into buffer, sends the data */
    UDR0 = data;
    //data = 0;
}
unsigned int USART_Receive( void )
{
    
    /*Wait for data to be received */
    while ( !(UCSR0A & (1<<RXC0)) );
    /*Get and return received data from buffer */
    //counter += 1;
    return UDR0;
}
 
Last edited by a moderator:

kubeek

Joined Sep 20, 2005
5,796
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.
 

spinnaker

Joined Oct 29, 2009
7,830
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.
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.
 

tshuck

Joined Oct 18, 2012
3,534
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.
OP seems to have mention that in #10....


Also, I want to point out that
Rich (BB code):
/*Set Double USART Transmission Speed */
    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
 

Thread Starter

kj4g09

Joined Dec 4, 2011
29
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.
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'.
 
Top