本人最近在调试一个程序,关于串口通讯。硬件没有问题,可就是接收不到数据,每次程序执行中断时,RI都不等于1,不知道怎么回事。请高手帮我看看。
//***********************************************************
#include <reg51.H>
#include <intrins.h> // 使用_nop_()函数
#include "222.h" // 常量定义
sbit L=P0^0;
// --------------------------------------------------------------------------
// 内部函数定义
void Dev_Init(void);
void Delay1us(void);
void DelayXus(uINT8 nUS);
void DelayXms(uINT8 nMS);
char SiargoPutChar(char c);
char SiargoGetKey(void);
char SiargoGetChar(void);
// ---------------------------------------------------------------------------
// 程序源代码
//
// ---------------------------------------------------------------------------
/***********************************************************
** 函数名称: Dev_Init
**-------------------------------------------------------------------------------------------------------
************************************************************
void Dev_Init(void)
{
EA = 0;
TR1 = 0;
TR0 = 0;
ET0 = 0;
ET1 = 0;
TMOD = 0x20;
TH1 = 0xFD;
TL1 = 0xFD; //采用38400波特率
SCON = 0x90;
PCON = 0x80;
TR1 = 1;
EA = 1;
ES = 1;
}
// ------------------------------------------------------------------------------------------------------
/***********************************************************
** 函数名称: Delay1us
** 功能描述: 根据不同的振荡器频率,产生1us延时。
*/void Delay1us(void)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: DelayXus
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void DelayXus(uINT8 nUS)
{
nUS++;
while (--nUS)
{
Delay1us();
}
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: DelayXms
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void DelayXms(uINT8 nMS)
{
nMS++;
while (--nMS)
{
DelayXus(250);
DelayXus(250);
DelayXus(250);
DelayXus(250);
}
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: SiargoPutChar
** 功能描述: 仅实现基本的字符输出功能。本文件修改自Keil公司的同名C文件。
** 输 入: c:要从串口输出的字符。
** 输 出: 无
** 返 回:返回要从串口输出的字符(即原样返回)。
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
char SiargoPutChar(char c)
{
if (TI)
TI = 0;
SBUF = c;
while (!TI);
TI = 0;
return c;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: main
** 功能描述: 主程序。
** 输 入: 无
** 输 出: 无
** 返 回:无
** 该程序是每隔100ms发送一组数据,单片机通过串行中断接收数据,如果接收数据正确点亮灯。
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void main(void)
{
uINT8 ucCrc1,ucRxData;
Dev_Init(); // 初始化硬件设备 波特率设置 开串行中断
L = 1; // 灯灭
flag = 0; // 判断接收正确标志
mucRxdStateMachine = 0; // 接收数据标志置初值
while (TRUE) // 主程序循环
{
DelayXms(100); // 测试目的,每间隔100ms读取一次数据
TB8 = 1; // 准备发送帧头
SiargoPutChar(0x9D); // 发送帧头
DelayXms(5); // 实测后不要也可正常工作,不过建议保留(延时时间可在1~10ms内设置)
TB8 = 0; // 准备发送命令、数据长度、数据、校验和及帧尾
SiargoPutChar(0xF0); // 发送读测量数据命令
DelayXms(5); // 实测后不要也可正常工作,不过建议保留(延时时间可在1~10ms内设置)
SiargoPutChar(0x01); // 发送数据长度
DelayXms(5); // 实测后不要也可正常工作,不过建议保留(延时时间可在1~10ms内设置)
SiargoPutChar(0x08); // 发送数据
DelayXms(5); // 实测后不要也可正常工作,不过建议保留(延时时间可在1~10ms内设置)
SiargoPutChar(0xF9); // 发送校验和
DelayXms(5); // 实测后不要也可正常工作,不过建议保留(延时时间可在1~10ms内设置)
SiargoPutChar(0x0D); // 发送帧尾
if(flag==1) // 如果接收了曾灯亮
{
L = 0;
}
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: UART0_ISR
** 功能描述: 用户接口串行中断服务程序。采用中断接收数据
** 输 入: 无
** 输 出: 无
** 返 回:无
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void UART0_ISR(void) interrupt INT_UART0
{
uINT8 ucCrc1,ucRxData;
flag=1;
if (RI) // 是接收中断则清除接收中断并处理接收命令
{
RI = CLR_BIT;
ucRxData = SBUF;
flag=1; // 只要进入接收就置灯亮标志位
if (mucRxdStateMachine == 0) // 接收并检查帧头:0x9D
{
if (ucRxData == 0x9D)
mucRxdStateMachine = 1;
else
return;
}
else if (mucRxdStateMachine == 1) // 接收并检查命令:0xF0
{
if (ucRxData == 0xF0)
{
ucCrc1 = ucRxData;
mucRxdStateMachine = 2;
}
else
{
mucRxdStateMachine = 0;
return;
}
}
else if (mucRxdStateMachine == 2) // 接收并检查数据长度:0x03
{
if (ucRxData == 0x03)
{
ucCrc1 ^= ucRxData;
mucRxdStateMachine = 3;
}
else
{
mucRxdStateMachine = 0;
return;
}
}
else if (mucRxdStateMachine == 3) // 接收数据(FRH)
{
mltFlow.Byte[1] = ucRxData;
ucCrc1 ^= ucRxData;
mucRxdStateMachine = 4;
}
else if (mucRxdStateMachine == 4) // 接收数据(FRM)
{
mltFlow.Byte[2] = ucRxData;
ucCrc1 ^= ucRxData;
mucRxdStateMachine = 5;
}
else if (mucRxdStateMachine == 5) // 接收数据(FRL)
{
mltFlow.Byte[3] = ucRxData;
ucCrc1 ^= ucRxData;
mucRxdStateMachine = 6;
flag=1;
}
else if (mucRxdStateMachine == 6) // 接收并检查校验和
{
if (ucCrc1 == ucRxData)
mucRxdStateMachine = 7;
else
{
mucRxdStateMachine = 0;
return;
}
}
else if (mucRxdStateMachine == 7) // 接收并检查帧尾:0x0D
{
mucRxdStateMachine = 0;
if (ucRxData != 0x0D)
return;
}
else
{ // 无效数据,复位接收逻辑
mucRxdStateMachine = 0;
return;
}
}
} |