📄 zb.c
字号:
#define ZB_GLOBALS
#include "includes.h"
/****************************变量定义*****************************/
static data INT8U ZB_BitCnt; /*位计数*/
static data INT8U ZB_ByteCnt; /*字节计数*/
static data INT8U ZB_GetSyncFlag; /*接受同步头标志*/
static data INT8U ZB_GetDatFlag; /*接受数据内容标志*/
static data INT8U ZB_GetSuccessFlag; /*接收一字节数据成功标志*/
static data INT8U ZB_HeadDatLen; /*同步头长度*/
static data INT16U ZB_HeadDat; /*同步头数据*/
static data INT8U ZB_SendByte; /*要发送的字节数据*/
static data INT8U ZB_RcvByte; /*接收到的字节数据*/
Com ZB_Com; /*通讯使用结构*/
/****************************本地函数定义*************************/
static void ZB_Tx (void);
static void ZB_Rx (void);
/****************************全局函数*****************************/
ZB_EXT void ZB_ParaInit (void)
/*===============================================
函数名: ZB_ParaInit
功能 : 载波功能参数初始化
输入 : 无
输出 : 无
===============================================*/
{
ZB_BitCnt = 0;
ZB_ByteCnt = 0;
ZB_GetSyncFlag = 1;/*接收头标志*/
ZB_GetDatFlag = 0;
ZB_GetSuccessFlag = 0;
ZB_HeadDatLen = 0;
ZB_HeadDat = 0;
ZB_SendByte = 0;
ZB_RcvByte = 0;
ZB_MaxLen = 0;
}
ZB_EXT void ZB_Course (void)
/*===============================================
函数名 : ZB_Course
功能 : 载波主流程
输入 : 无
输出 : 无
===============================================*/
{
if (ZB_SendFlag){
ZB_SendFlag = 0;
PLM_RST = 0xa2;
PLM_RS = 1;/*转发送*/
}
}
/****************************本地函数*****************************/
void ZB_Int (void) interrupt 7
/*===============================================
函数名 : ZB_Int
功能 : 载波同步中断
输入 : 无
输出 : 无
===============================================*/
{
if (1 == PLM_RS){
ZB_Tx();
}else{
ZB_Rx();
}
}
static void ZB_Tx (void)
/*===============================================
函数名 : ZB_Tx
功能 : 载波发送数据
输入 : 无
输出 : 无
===============================================*/
{
if (0 == ZB_BitCnt){ /*取数据*/
switch (ZB_Com.TxPhase){
case 0:
ZB_SendByte = 0xff;
ZB_HeadDatLen ++;
if (6 == ZB_HeadDatLen){
ZB_HeadDatLen = 0;
ZB_Com.TxPhase = 1;
}
break;
case 1:
LED_ZB = 0; /*开载波发送指示灯*/
ZB_SendByte = 0x09;
ZB_Com.TxPhase = 2;
break;
case 2: /*前3部分都是发送同步头,和数据无关*/
ZB_SendByte = 0xaf;
ZB_Com.TxPhase = 3;
break;
case 3: /*发整条帧*/
ZB_SendByte = COM_DatBuf[ZB_ByteCnt++];
if (ZB_ByteCnt == ZB_MaxLen){
ZB_ByteCnt = 0;
ZB_MaxLen = 0;
ZB_Com.TxPhase = 4;
}
break;
case 4: /*多发一字节,保证发送完整*/
ZB_SendByte = 0;
ZB_Com.TxPhase = 0;
ZB_Com.TxEnd = 1;
break;
default:
break;
}
}
PLM_RS = 1; /*启动发送*/
PLM_RST = 0xa2; /*防止发送时间过长,进入复位*/
if (ZB_BitCnt <8){ /*从高位到低位发送数据*/
if ((ZB_SendByte<<ZB_BitCnt) & 0x80){
ZB_RS = 1;
}else{
ZB_RS = 0;
}
ZB_BitCnt ++;
if (8 == ZB_BitCnt){ /*一个字节数据发送完成*/
ZB_BitCnt = 0;
if (1 == ZB_Com.TxEnd){ /*数据发送完成*/
ZB_Com.TxEnd = 0;
LED_ZB = 1; /*关载波发送指示灯*/
PLM_RS = 0; /*转接收*/
}
}
}
}
static void ZB_Rx (void)
/*===============================================
函数名 : ZB_Rx
功能 : 载波接收数据
输入 : 无
输出 : 无
===============================================*/
{
if (1 == ZB_GetSyncFlag){ /*接收头标志*/
ZB_HeadDat <<= 1;
if (1 == ZB_RS){ /*判断P3.7,载波数据收发位*/
ZB_HeadDat |= 1;
}
if (0x09af == ZB_HeadDat){ /*同步头接收成功*/
LED_ZB = 0; /*开载波接收指示灯*/
ZB_GetSyncFlag = 0;
ZB_GetDatFlag = 1;
}
}else if (1 == ZB_GetDatFlag){ /*开始接收数据部分*/
ZB_RcvByte <<= 1;
if (1 == ZB_RS){
ZB_RcvByte |= 1;
}
ZB_BitCnt ++;
if (ZB_BitCnt == 8){
ZB_BitCnt = 0;
ZB_GetSuccessFlag = 1;
}
}
if (ZB_GetSuccessFlag){ /*接收一个字节成功*/
ZB_GetSuccessFlag = 0;
switch (ZB_Com.RxPhase){
case 0:/*第一起始符*/
if (0xfe == ZB_RcvByte){
ZB_Com.RxPhase = 0;
COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
}else if (0x68 == ZB_RcvByte){
ZB_Com.RxPhase = 2;
COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
}else if ((0x14 == ZB_RcvByte)||(0x24 == ZB_RcvByte)||(0x16 == ZB_RcvByte)||(0x10 == ZB_RcvByte)){
ZB_Com.RxPhase = 1;
COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
}else{
ZB_Com.RxErr = 1;
}
break;
case 1:/*浩迪规约第二起始符*/
if ((0x11 == ZB_RcvByte)||(0xee == ZB_RcvByte)){
ZB_Com.RxPhase = 2;
COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
}else{
ZB_Com.RxErr = 1;
}
break;
case 2:/*地址域*/
COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
ZB_Com.AdrLenCnt ++;
if (6 == ZB_Com.AdrLenCnt){
ZB_Com.AdrLenCnt = 0;
ZB_Com.RxPhase = 3;
}else if (ZB_Com.AdrLenCnt > 6){/*为了防止不可预知的错误*/
ZB_Com.RxErr = 1;
}
break;
case 3:/*数据起始符*/
if (0x68 == ZB_RcvByte){
ZB_Com.RxPhase = 4;
COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
}else if (0xaa == ZB_RcvByte){
ZB_Com.RxPhase = 4;
COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
}else{
ZB_Com.RxErr = 1;
}
break;
case 4:/*控制码*/
COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
ZB_Com.RxPhase = 5;
break;
case 5:/*数据长度*/
if (30 > ZB_RcvByte){/*最长数据为20个字节*/
COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
ZB_Com.RxDatLen = ZB_RcvByte;
ZB_Com.RxPhase = 6;
}else{
ZB_Com.RxErr = 1;
}
break;
case 6:/*数据域*/
COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
ZB_Com.DatLenCnt ++;
if (ZB_Com.DatLenCnt == ZB_Com.RxDatLen){
ZB_Com.RxPhase = 7;
ZB_Com.DatLenCnt = 0;
ZB_Com.RxDatLen = 0;
}else if (ZB_Com.DatLenCnt > ZB_Com.RxDatLen){/*为了防止不可预知的错误*/
ZB_Com.RxErr = 1;
}
break;
case 7:/*校验码*/
COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
ZB_Com.RxPhase = 8;
break;
case 8:/*结束符*/
if (0x16 == ZB_RcvByte){
COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
ZB_Com.RxPhase = 0;
UART0_SendFlag = 1;
UART0_MaxLen = ZB_MaxLen;
ZB_MaxLen = 0;
ZB_GetSyncFlag = 1;
ZB_GetDatFlag = 0;
LED_ZB = 1;
}else if (0xff == ZB_RcvByte){
COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
ZB_Com.RxPhase = 9;
}else{
ZB_Com.RxErr = 1;
}
break;
case 9:/*浩迪CRC校验*/
COM_DatBuf[ZB_MaxLen ++] = ZB_RcvByte;
ZB_Com.CrcLenCnt ++;
if (ZB_Com.CrcLenCnt == 2){
ZB_Com.RxPhase = 0;
ZB_Com.CrcLenCnt = 0;
UART0_SendFlag = 1;
UART0_MaxLen = ZB_MaxLen;
ZB_MaxLen = 0;
ZB_GetSyncFlag = 1;
ZB_GetDatFlag = 0;
LED_ZB = 1;
}else if (ZB_Com.CrcLenCnt > 2){/*为了防止不可预知的错误*/
ZB_Com.RxErr = 1;
}
break;
default:
break;
}
if (ZB_Com.RxErr){/*如果帧接收有错误*/
ZB_Com.RxErr = 0;
ZB_Com.RxPhase = 0;
ZB_Com.RxDatLen = 0;
ZB_Com.DatLenCnt = 0;
ZB_Com.CrcLenCnt = 0;
ZB_Com.AdrLenCnt = 0;
ZB_GetSyncFlag = 1;
ZB_GetDatFlag = 0;
ZB_MaxLen = 0;
LED_ZB = 1;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -