Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

How to transmit a 32bits data through Atmega16

Status
Not open for further replies.

Tsingran

New Member
Hedy guys :
Nowaday I was doing a project about data transmission with Atmega16's usart port ,here is the form of
data i need to transmit :
Command packet format:

2 bytes 4 bytes 1 byte 2 bytes 1 byte 4 bytes 2 bytes
0xef01 0xffffffff 0x01 0x0007 0x13 0x00000000 0x001c
I make an array like this
my_array [7]={0xef01, 0xffffffff, 0x01,0x0007,0x13, 0x00000000,0x001c};
and then use this code ,wanting to put every element by putting it into the Tx Buffer
uint i;
for(i=0;i<7;i++)
{
while(!(UCSRA&(BIT(UDRE)))) ;
UDR=ceshi;
while(!(UCSRA&(BIT(TXC))));
UCSRA|=BIT(TXC);
}

but as you can see the data length I want to transmit is 32 bits ,but the Tx register is only 8bits ,
it's obvious that this method is incorrect ,so I wish someone can help and solve this problem ,Thank you .
 
an example - there are many ways to do this... (scroll this code window)

Code:
// initialize UART for 8N1

// function to send a byte
void uartOut(unsigned char b)  {
while ( ! (UCSRA  &  (1<<UDRE) ) ) // wait for transmit register empty
       {};
  UDR = b; // no need to wait for TX complete, UART is double-buffered.
}

// this code is in your applicaition...
unsigned long myLong;
  uartOut(myLong >> 24); // right shift bits to send most significant byte first
  uartOut(myLong >> 16);
  uartOut(myLong >> 8);
  uartOut(myLong & 0xFF); // least significant goes last. One can recode this to reverse the order

//another coding...
  for (i = 0; i < 4; i++)
    uartOut(myLong >> (i*8));

//another coding...
  union {
    unsigned long myLong; // these two items are in same RAM locations
    unsigned char bytes[4];
  } longAndBytes;  

// later
  longAndBytes.myLong = 1234567; // store value
  int i; 
  for (i = 0; i < 4; i++)
    uartOut(longAndBytes.bytes[i]); // for bytes, same RAM as the long in the union
    // beware: the byte ordering for longs and ints varies from one microprocessor family to another. Read about "endian"
In any such arrangement, the sending and receiving devices need to agree on the byte order.
Better yet, send data on the UART in text/ASCII, so byte order doesn't have to be agreed to, as follows...
Code:
  char myString[16];
  itoa(myString, myLong); // convert to text/ASCII. Uses a common C library function. #include it
  i = 0;
  while (myString[i] != '\0')
    uartOut(myString[i]); // send next character
  uartOut('\r'); // send carriage return to signal end of data (or send a comma, etc)
 
Last edited:
Thank you,stevech!I was ill two days ago and haven't seen you reply .From you reply ,I know how to solve my puzzle problem yet .
 
Here is another way you can send a variable byte by byte. Assuming you allready have the function to send and receive bytes (chars) from uart.

The idea is to first take the address of the variable and then cast it to a char array. Then you can refer to each of the bytes individually. This technique works for variables of any size or type.

Sending:

Code:
uint32_t lemon;  // Unsigned 32 bit integer
char* buffer;

buffer =  (char*)(&lemon);

uart_writechar( buffer[0] );
uart_writechar( buffer[1] );
uart_writechar( buffer[2] );
uart_writechar( buffer[3] );

Receiving:

Code:
uint32_t lemon;  // Unsigned 32 bit integer
char* buffer;

buffer =  (char*)(&lemon);

buffer[0] = uart_readchar();
buffer[1] = uart_readchar();
buffer[2] = uart_readchar();
buffer[3] = uart_readchar();

// Variable 'lemon' now contains the received Unsigned 32 bit integer
 
Last edited:
QUOTE=misterT;879000]Here is another way you can send a variable byte by byte. Assuming you allready have the function to send and receive bytes (chars) from uart.

The idea is to first take the address of the variable and then cast it to a char array. Then you can refer to each of the bytes individually. This technique works for variables of any size or type.

Sending:

Code:
uint32_t lemon;  // Unsigned 32 bit integer
char* buffer;

buffer =  (char*)(&lemon);

uart_writechar( buffer[0] );
uart_writechar( buffer[1] );
uart_writechar( buffer[2] );
uart_writechar( buffer[3] );

Receiving:

Code:
uint32_t lemon;  // Unsigned 32 bit integer
char* buffer;

buffer =  (char*)(&lemon);

buffer[0] = uart_readchar();
buffer[1] = uart_readchar();
buffer[2] = uart_readchar();
buffer[3] = uart_readchar();

// Variable 'lemon' now contains the received Unsigned 32 bit integer
[/QUOTE]
Thank you,mister.It really help me a lot .It is very nice to be here ,solving problem with people form difierent place,and all guys are skillful,so I can learn a lot from you.[
 
I have to add an important point to my example code above. It's about taking addresses of variables and code efficiency.

If you take the address of a local variable (the “&lemon” construction), it is not likely to be allocated to a register, since it has to have an address and, thus, a place in memory (usually
on the stack). It also has to be written back to memory before each function call, just like a global variable, since some other function might have gotten hold of the address and is
expecting the latest value. Taking the address of a global variable does not hurt as much, since they have to have a memory address anyway.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top