STC单片机串口接收一帧数据全为0的原因和解决办法

	STC单片机串口接收一帧数据全为0的原因和解决办法
typedef unsigned char BYTE;

void UART_RX_DATA_JX(void)
{
	volatile BYTE Uart_Rx_temp = SBUF;//此处volatile修饰必须加,否则收到数据全为0.另一种解决方式是将Uart_Rx_temp定义为全局变量
	if(state_machine == 0)       // 协议解析状态机
	{
		if(Uart_Rx_temp == 0xA5)       // 接收到帧头第一个数据
		{
			state_machine = 1;
			m_ucData[0] = Uart_Rx_temp; 		  
		}
		else
		{
			state_machine = 0;      // 状态机复位	  
		}
	}
	else if(state_machine == 1)
	{
		if(Uart_Rx_temp == 0x5A)       // 接收到帧头第二个数据
		{
			state_machine = 2;
			m_ucData[1] = Uart_Rx_temp; 		
		}
		else
        { 
			state_machine = 0;      // 状态机复位
		}
	}
	else if(state_machine == 2)
	{
		rcvcount = Uart_Rx_temp;        // 要接收的字节数,仅指令和数据
		state_machine = 3;   
		lencnt = 0;
		m_ucData[2] = Uart_Rx_temp; 
	}
	else if(state_machine == 3)
	{
		m_ucData[lencnt+3] = Uart_Rx_temp;     // 数据保存
		if(lencnt == m_ucData[2]-1)      // 判断数据是否接收完毕
		{
			retval = 0xaa;    // 置标志,表示一个数据包接收到
			state_machine = 0;     //复位状态机
		}
		else
		{
		//	state_machine = 3;
			lencnt ++;
		}
    }
	else
	{
		state_machine = 0; 
	}
}	

/*----------------------------
UART 中断服务程序
-----------------------------*/
void Uart() interrupt 4 using 1
{
    if (RI)
    {
		UART_RX_DATA_JX();		
		RI = 0;                 //清除RI位
    }
    if (TI)
    {
        TI = 0;                 //清除TI位
        busy = 0;               //清忙标志
    }
}
	问题的关键在于对接收数据缓存Uart_Rx_temp的定义。如果不加volatile修饰,编译器会优化处理,导致收到数据全为0。另一种解决方式是将Uart_Rx_temp定义为全局变量。
	以上程序在STC单片机实测验证通过,其他51系列单片机可以借鉴。
发布了12 篇原创文章 · 获赞 4 · 访问量 1376

猜你喜欢

转载自blog.csdn.net/ydgd118/article/details/103974905