/****************************************************
** 函数名称: UartIRQ
** 输 入: 无
** 输 出: 无
** 功能描述: 串口中断服务程序
*****************************************************/
void UartIRQ(void)interrupt 4
{
static UINT8 uccnt=0;
UINT8 uclen;
UINT16 uscrc;
if(RI) //是否接收到数据
{
RI=0;
PktCrcEx.p[uccnt++]=SBUF;//获取单个字节
if(PktCrcEx.r.m_ucHead1 == DCMD_CTRL_HEAD1)//是否有效的数据帧头部1
{
if(uccnt<CTRL_FRAME_LEN+PktCrcEx.r.m_ucDataLength+CRC16_LEN)//是否接收完所有数据
{
if(uccnt>=2 && PktCrcEx.r.m_ucHead2!=DCMD_CTRL_HEAD2)//是否有效的数据帧头部2
{
uccnt=0;
return;
}
}
else
{
uclen=CTRL_FRAME_LEN+PktCrcEx.r.m_ucDataLength;//获取数据帧有效长度(不包括校验值)
uscrc=CRC16Check(PktCrcEx.p,uclen);//计算校验值
//这样做的原因是因为有时写数据长度不一样,导致PktCrcEx.r.m_szCrc会出现为0的情况,所以使用BufCpy将校验值复制到相应的位置
BufCpy(PktCrcEx.r.m_szCrc,&PktCrcEx.p[uclen],CRC16_LEN);
if((UINT8)(uscrc>>8) !=PktCrcEx.r.m_szCrc[1]\
||(UINT8) uscrc !=PktCrcEx.r.m_szCrc[0])//校验值是否匹配
{
uccnt=0;
return;
}
switch(PktCrcEx.r.m_ucOptCode)//从命令码中获取相对应的操作
{
case DCMD_CTRL_BELL://控制蜂鸣器命令码
{
if(DCTRL_BELL_ON==PktCrcEx.r.m_szDataBuf[0])//数据部分含控制码
{
bBellOn=TRUE;
}
else
{
bBellOn=FALSE;
}
}
break;
case DCMD_CTRL_LED://控制LED命令码
{
if(DCTRL_LED_ON==PktCrcEx.r.m_szDataBuf[0])//数据部分含控制码
{
bLedOn=TRUE;
}
else
{
bLedOn=FALSE;
}
}
break;
case DCMD_REQ_DATA://请求数据命令码
{
bReqData=TRUE;
}
break;
}
uccnt=0;
return;
}
}
else
{
uccnt=0;
}
}
}
/****************************************************
** 函数名称: main
** 输 入: 无
** 输 出: 无
** 功能描述: 函数主题
*****************************************************/
void main(void)
{
UINT8 i=0;
UINT16 uscrc=0;
UartInit();//串口初始化
EA=1; //开总中断
while(1)
{
if(bLedOn) //是否点亮Led
{
LED(ON);
}
else
{
LED(OFF);
}
if(bBellOn)//是否响蜂鸣器
{
BELL(ON);
}
else
{
BELL(OFF);
}
if(bReqData)//是否请求数据
{
bReqData=FALSE;
NOT_EN_UART(); //禁止串口中断
PktCrcEx.r.m_ucHead1=UCMD_CTRL_HEAD1;//MCU上传数据帧头部1
PktCrcEx.r.m_ucHead2=UCMD_CTRL_HEAD2;//MCU上传数据帧头部2
PktCrcEx.r.m_ucOptCode=UCMD_REQ_DATA;//MCU上传数据帧命令码
uscrc=CRC16Check(PktCrcEx.p,CTRL_FRAME_LEN+PktCrcEx.r.m_ucDataLength);//计算校验值
PktCrcEx.r.m_szCrc[0]=(UINT8) uscrc; //校验值低字节
PktCrcEx.r.m_szCrc[1]=(UINT8)(uscrc>>8);//校验值高字节
//这样做的原因是因为有时写数据长度不一样,导致PktCrcEx.r.m_szCrc会出现为0的情况,所以使用BufCpy将校验值复制到相应的位置
BufCpy(&PktCrcEx.p[CTRL_FRAME_LEN+PktCrcEx.r.m_ucDataLength],PktCrcEx.r.m_szCrc,CRC16_LEN);
UartSendNBytes(PktCrcEx.p,CTRL_FRAME_LEN+PktCrcEx.r.m_ucDataLength+CRC16_LEN);//发送数据
EN_UART();//允许串口中断
}
}
} |