请教大家一个关于IAR volatile的问题
我用IAR 4.2来编译ATMEL官方的串口中断通信程序(稍微改动,主要是波特率定义等,不影响这个问题),编译后提示Warning: undefined behavior: the order of volatile accesses is undefined in this statement 大体上看,这个警告是说volatile的访问顺序没定义,那应该如果解决呢? 附源代码:// AVR306: Using the AVR USART in C
// Routines for interrupt controlled USART
// Last modified: 02-06-21
// Modified by: AR
/* Includes */
#include <iom16.h>
#include <intrinsics.h>
/* USART Buffer Defines */
#define USART_RX_BUFFER_SIZE 32 /* 2,4,8,16,32,64,128 or 256 bytes */
#define USART_TX_BUFFER_SIZE 32
#define USART_RX_BUFFER_MASK ( USART_RX_BUFFER_SIZE - 1 )
#if ( USART_RX_BUFFER_SIZE & USART_RX_BUFFER_MASK )
#error RX buffer size is not a power of 2
#endif
#define USART_TX_BUFFER_MASK ( USART_TX_BUFFER_SIZE - 1 )
#if ( USART_TX_BUFFER_SIZE & USART_TX_BUFFER_MASK )
#error TX buffer size is not a power of 2
#endif
/* Static Variables */
static unsigned char USART_RxBuf;
static volatile unsigned char USART_RxHead;
static volatile unsigned char USART_RxTail;
static unsigned char USART_TxBuf;
static volatile unsigned char USART_TxHead;
static volatile unsigned char USART_TxTail;
/* Prototypes */
void InitUSART( unsigned char baudrate );
unsigned char ReceiveByte( void );
void TransmitByte( unsigned char data );
/* Main - a simple test program*/
void main( void )
{
InitUSART( 47 ); /* Set the baudrate to 19,200 bps using a 3.6864MHz crystal */
__enable_interrupt(); /* Enable interrupts => enable USART interrupts */
for( ; ; ) /* Forever */
{
TransmitByte( ReceiveByte() ); /* Echo the received character */
}
}
/* Initialize USART */
void InitUSART( unsigned char baudrate )
{
//unsigned char x;
UBRRH = (unsigned char)(baudrate>>8);
UBRRL = (unsigned char)baudrate;/* Set the baud rate */
/* Enable USART receiver and transmitter, and receive interrupt */
//UCR = ( (1<<RXCIE) | (1<<RXEN) | (1<<TXEN) );
UCSRB = ( (1<<RXEN) | (1<<TXEN) | (1<<RXCIE) );/* Enable USART receiver and transmitter */
UCSRC = ((1<<URSEL)|(3<<UCSZ0));
//x = 0; /* Flush receive buffer */
USART_RxTail = 0;
USART_RxHead = 0;
USART_TxTail = 0;
USART_TxHead = 0;
}
/* Interrupt handlers */
#pragma vector=USART_RXC_vect
__interrupt void USART_RX_interrupt( void )
{
unsigned char data;
unsigned char tmphead;
data = UDR; /* Read the received data */
/* Calculate buffer index */
tmphead = ( USART_RxHead + 1 ) & USART_RX_BUFFER_MASK;
USART_RxHead = tmphead; /* Store new index */
if ( tmphead == USART_RxTail )
{
/* ERROR! Receive buffer overflow */
}
USART_RxBuf = data; /* Store received data in buffer */
}
#pragma vector=USART_UDRE_vect
__interrupt void USART_TX_interrupt( void )
{
unsigned char tmptail;
/* Check if all data is transmitted */
if ( USART_TxHead != USART_TxTail )
{
/* Calculate buffer index */
tmptail = ( USART_TxTail + 1 ) & USART_TX_BUFFER_MASK;
USART_TxTail = tmptail; /* Store new index */
UDR = USART_TxBuf;/* Start transmition */
}
else
{
UCSRB &= ~(1<<UDRIE); /* Disable UDRE interrupt */
}
}
/* Read and write functions */
unsigned char ReceiveByte( void )
{
unsigned char tmptail;
while ( USART_RxHead == USART_RxTail )/* Wait for incomming data */
;
tmptail = ( USART_RxTail + 1 ) & USART_RX_BUFFER_MASK;/* Calculate buffer index */
USART_RxTail = tmptail; /* Store new index */
return USART_RxBuf; /* Return data */
}
void TransmitByte( unsigned char data )
{
unsigned char tmphead;
/* Calculate buffer index */
tmphead = ( USART_TxHead + 1 ) & USART_TX_BUFFER_MASK; /* Wait for free space in buffer */
while ( tmphead == USART_TxTail );
USART_TxBuf = data; /* Store data in buffer */
USART_TxHead = tmphead; /* Store new index */
UCSRB |= (1<<UDRIE); /* Enable UDRE interrupt */
}
unsigned char DataInReceiveBuffer( void )
{
return ( USART_RxHead != USART_RxTail ); /* Return 0 (FALSE) if the receive buffer is empty */
} if ( USART_TxHead != USART_TxTail )
while ( USART_RxHead == USART_RxTail )/* Wait for incomming data */
return ( USART_RxHead != USART_RxTail ); /* Return 0 (FALSE) if the receive buffer is empty */
这三行提示警告信息 遇到同样的问题 ~~把volatile去掉就好了.....求解ing volatile类型的变量一般不直接参与运算,因为在运算的过程中该变量就已经改变 使用一个临时变量将volatile修饰的变量读出来参与运算。。。 xuhaikun 发表于 2011-8-20 13:13
使用一个临时变量将volatile修饰的变量读出来参与运算。。。
好办法! 本帖最后由 bli19 于 2014-9-7 01:20 编辑
UB,就是不符合编译器所遵循的C标准,可能会带来不可预知的结果。应该是C99吧。。
你可以忽略,前提是你知道你自己在做什么。
原作者既然说好用,那自然有他的道理。
----
建议看看此贴,很详细:
http://www.amobbs.com/thread-5497299-1-1.html
页:
[1]