simple printing to uart

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

I'm sure this is simple for most of you, but I can't get this code to work. I just want to add some debug statements in my code. I created some simple uart functions, but when I simulate with AVR Studio, these statements get skipped.

Here's my code.

main() {
...
    uart0_tx_string( ". Year: ");
    uart0_tx_int_dec( year );
}

void uart0_tx_int_dec(int x) {
  itoa(x, tx0_string, 10);
  uart0_tx_string(*tx0_string);
}

char tx0_string[10];

void uart0_tx_string(char* string_ptr) {
  while (*string_ptr != 0) {
    uart0_tx_char(*string_ptr);
    string_ptr++;
  }
  return;
}

The simulator seems to jump over the itoa statement and the uart0_tx_str call.

I'm sure this is simple. What am I doing wrong?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
uart0_tx_string(*tx0_string); 

This should be:

uart0_tx_string(tx0_string); 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Tried that. I get this from the compiler:
../uart_routines.c:63: warning: passing argument 1 of 'uart0_tx_string' from incompatible pointer type

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

Try declaring tx0_string prior to its usage in uart0_tx_int_dec rather than afterwards.

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

kmr wrote:
Try declaring tx0_string prior to its usage in uart0_tx_int_dec rather than afterwards.

Actually, I did. I just was cutting/pasting from AVR Studio. But, tx0_string is declared at the top of my uart_routines.c file as a global.

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

Rather than showing us snippets, give us a complete test program that shows the problem you are having. To get you started I wrote this, it compiles without any warnings:

#include 
#include 

char tx0_string[10]; 

void uart0_tx_char(char c){
	UDR = c;
}

void uart0_tx_string(char* string_ptr) { 
  while (*string_ptr != 0) { 
    uart0_tx_char(*string_ptr); 
    string_ptr++; 
  } 
}

void uart0_tx_int_dec(int x) { 
  itoa(x, tx0_string, 10); 
  uart0_tx_string(tx0_string); 
} 

int main(void) {
	uart0_tx_int_dec(2008);
	while(1);
}

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

I'll have to post the entire code when I get home tonight. But, a couple of thoughts:

1. Should I declare tx0_string as "volatile"?
2. It seems to me that the uart0_tx_string function is expecting a constant because when I do uart0_tx_string("hello world"); it works.

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

1) No, why?
2) but that form just puts that string into SRAM passes a pointer to char into the routine. Note however that it is a pointer to char. Not a pointer to "signed char" or a pointer to "unsigned char". I wonder if this is what's behind your issue but in the example I posted above there is no warning because tx0_string is defined as a pointer to char.

Cliff

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

Okay, I just tried this code:

#include  
#include  

char tx0_string[10]; 

void UART0setup(void) {

  #define USART_BAUDRATE 9600
  #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1) 

  // baud rate
  UBRR0H = (BAUD_PRESCALE >> 8);
  UBRR0L = BAUD_PRESCALE;

  // enable RX and TX
  UCSR0B = (1<<RXEN0) | (1<<TXEN0);

  UCSR0C = (0<<USBS0) | (1<<UCSZ01) | (1<<UCSZ00);  // async, no parity, 1 stop bit, 8-bit data 

}

void uart0_tx_char(char c) {
  while (!(UCSR0A & (1<<UDRE0))); // wait till transmit Data register is empty 
  UDR0 = c; // send the character 
  return;
} 


void uart0_tx_string(char* string_ptr) { 
  while (*string_ptr != 0) { 
    uart0_tx_char(*string_ptr); 
    string_ptr++; 
  } 
} 

void uart0_tx_int_dec(int x) { 
  itoa(x, tx0_string, 10); 
  uart0_tx_string(tx0_string); 
} 

void main(void) { 
   UART0setup();
   uart0_tx_int_dec(2008); 
   while(1); 
} 

This compiles okay, but doesn't output anything on the USART in the simulator. This is for an atmega324p running at 1.8432MHz.

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

Quote:
This compiles okay, but doesn't output anything on the USART in the simulator. This is for an atmega324p running at 1.8432MHz.

What is it your not seeing output in the simulator? The UDR reg?
Have you tried it on the actual device yet?

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

Not yet, but I have other C code that writes to the UDR and the simulator shows it. I looked at the .lss file and I can see it doesn't write to the the UDR register.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
  UDR0 = c; // send the character
 116:	90 93 c6 00 	sts	0x00C6, r25

I setup a project and it seems to be the correct code but the simulator doesn't seem to be supporting the UDR reg. The above line from the .lss file shows that it is writing to UDR.

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

Sorry but what were folks expecting to see in UDR anyway? Remember that the location is TWO registers. One read (what's been received) and one write. If you write 0xA5 to the UDR and then immediately read it back (or try to "see" it in the simulator) you will not see 0xA5. That's gone into the write-only part of the register and has disappeared off into a "black hole" (I blame the LHC!).

EDIT: Actually a test, single stepping the Asm, shows that the value written is shown in the UDR display for the one cycle after the OUT/STS is executed but then the display reverts to 0x00.

So maybe try single stepping the Asm not the C and watching the register for the one cycle after the write to UDR

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

Quote:

EDIT: Actually a test, single stepping the Asm, shows that the value written is shown in the UDR display for the one cycle after the OUT/STS is executed but then the display reverts to 0x00.

So maybe try single stepping the Asm not the C and watching the register for the one cycle after the write to UDR

It seems UDR only shows the value when UDR is not an extended i/o address (When out is used). Seems to just be another little Studio quirk :?

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

I'll have to try it on the chip. I just wanted to debug as much as possible in the simulator beforehand. It seems strange that sometimes the UDR register show the correct value and other times it doesn't.

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

Quote:
It seems strange that sometimes the UDR register show the correct value and other times it doesn't.

There speaks a man who hasn't used the simulator much!

(if the AVR you are programming for is supported by Sim V2 then it almost always pays to switch over)