|
发表于 2023-10-19 11:09:53
|
显示全部楼层
/**
* @brief 中断服务函数
* @param 无
* @retval 无
*/
void UART2_ISR_Handler (void) interrupt UART2_VECTOR
{
if(RI2)
{
CLR_RI2();
ZYLoRa_buff[ZYLoRa_p++] = S2BUF;
Timer_Multiple_timings(USART2_RxTimeOut_NO,5);
}
if(TI2)
{
CLR_TI2();
Busy_uartii = 0; //复位标志
}
}
/**
* @brief 初始化串口2
* @param 无
* @retval 无
*/
void Uart2_Init(void) // 9600bps@24.000MHz
{
COMx_InitDefine COMx_InitStructure; //结构定义
GPIO_InitTypeDef GPIO_InitStructure; //结构定义
GPIO_InitStructure.Pin = GPIO_Pin_0 | GPIO_Pin_1; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P1,&GPIO_InitStructure); //初始化
COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
COMx_InitStructure.UART_BRT_Use = BRT_Timer2; //选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)
COMx_InitStructure.UART_BaudRate = 9600ul; //波特率, 一般 110 ~ 115200
COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLE
COMx_InitStructure.BaudRateDouble = DISABLE; //波特率加倍, ENABLE或DISABLE
UART_Configuration(UART2, &COMx_InitStructure); //初始化串口1 UART1,UART2,UART3,UART4
NVIC_UART2_Init(ENABLE,Priority_1); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
UART2_SW(UART2_SW_P10_P11); //UART2_SW_P10_P11,UART2_SW_P46_P47
Busy_uartii = 0; //复位标志
Busy_UartRxd = 0;
ZYLoRa_MD0 = 1;
ZYLoRa_MD1 = 0;
ZYLoRa_AUX = 1;
}
/**
* @brief 数据发送字节
* @param 无
* @retval 无
*/
void Uart2Send(u8 dat)
{
while(Busy_uartii);
Busy_uartii = 1;
S2BUF = dat;
}
/**
* @brief 发送指定长度的字符串
* @param 无
* @retval 无
*/
void ZYLoRa_SendStr_length( u8 *str,u8 strlen )
{
u8 k=0;
do
{
Uart2Send( *(str + k) );
k++;
} while(k < strlen);
}
/**
* @brief CRC_16校验值计算
* @apply 内部调用
* @param void
* @retval
**/
unsigned short ZY_CRC16 (unsigned char *ppdata, unsigned int len)
{
//初始值
u8 i;
u16 crc16 = 0xFFFF;
while( len-- ) {
for(i=0x80; i!=0; i>>=1) {
if((crc16 & 0x8000) != 0) {
crc16 = crc16 << 1;
crc16 = crc16 ^ 0x1021;
}
else {
crc16 = crc16 << 1;
}
if((*ppdata & i) != 0) {
crc16 = crc16 ^ 0x1021; //crc16 = crc16 ^ (0x10000 ^ 0x11021)
}
}
ppdata++;
}
return crc16;
}
/**
* @brief 中断接收数据处理
* @apply 线程调用
* @param void
* @retval
**/
void ZYLoRa_DataRec(void)
{
u8 i=0;
if( CheckTimerOut(USART2_RxTimeOut_NO) == 0 )
{
if(ZYLoRa_p > 0)
{
/* 完成标志 */
if(Busy_UartRxd == 0)
{
zylora_cmdflg.LoRaRcvCnt = ZYLoRa_p;
memcpy(zylora_cmdpro.lorarevcmdinfo,ZYLoRa_buff,ZYLoRa_p);
ZYLoRa_SendStr_length(zylora_cmdpro.lorarevcmdinfo,zylora_cmdflg.LoRaRcvCnt); //返回接收信息
Busy_UartRxd = 1;
zylora_cmdflg.LoRaRcvFlg = 1;
}
/* 清除缓存标志 */
memset(ZYLoRa_buff,0,ZYLoRa_p);
ZYLoRa_p = 0;
}
}
}
/**
* @brief LoRa数据帧校验
* @apply 线程调用
* @param void
* @retval
**/
void ZYLoRa_Dataverification(void)
{
u8 i;
u16 Len_Storage = 0;
u16 CrcValue_Storage = 0;
//数据处理帧有无处理
if(zylora_cmdflg.LoRaRcvFlg == 1)
{
zylora_cmdflg.LoRaRcvFlg = 0;
}
else
{
return;
}
//遍历验证数据处理帧
for(i = 0;i < zylora_cmdflg.LoRaRcvCnt;i++)//解析从下位机接收的储物格控制板数据
{
if(zylora_cmdpro.lorarevcmdinfo == 0x7B)//判断帧头
{
if( (zylora_cmdpro.lorarevcmdinfo[i + 1] == 0x01) || (zylora_cmdpro.lorarevcmdinfo[i + 1] == 0x02) || (zylora_cmdpro.lorarevcmdinfo[i + 1] == 0x04) )//判断帧类型
{
Len_Storage = zylora_cmdpro.lorarevcmdinfo[i + 9];
CrcValue_Storage = ZY_CRC16(&zylora_cmdpro.lorarevcmdinfo,Len_Storage + 10);
if( (zylora_cmdpro.lorarevcmdinfo[i + Len_Storage + 10] == (CrcValue_Storage >> 8))&&(zylora_cmdpro.lorarevcmdinfo[i + Len_Storage + 11] == (CrcValue_Storage & 0xff)))//判断帧校验
{
zylora_cmdflg.LoRaRcvFinishFlg = 0x01;
/* break可以在if-else中使用直接跳出当前for循环。*/
break;
}
}
}
else
{
/* continue语句的作用是跳过循环体中剩余的语句并到循环末尾而强行执行下一次循环。*/
continue;
}
}
//数据处理帧遍历后无效
if(i >= zylora_cmdflg.LoRaRcvCnt)
{
//没有找到有效帧
zylora_cmdflg.LoRaRcvFinishFlg = 0x00;
memset(zylora_cmdpro.lorarevcmdinfo,0,zylora_cmdflg.LoRaRcvCnt);
zylora_cmdflg.LoRaRcvCnt = 0;
Busy_UartRxd = 0;
}
}
/**
* @brief LoRa数据帧ID验证
* @apply 线程调用
* @param void
* @retval
**/
u8 array_equal(u8 *a,u8 *b,int size)
{
int i;
for(i = 0; i<size; i++)
{
if(a != b)
{
return 0;
}
}
return 1;
}
void ZYLoRa_Datavalidation(void)
{
int n;
//数据处理帧有无处理
if(zylora_cmdflg.LoRaRcvFinishFlg == 1)
{
zylora_cmdflg.LoRaRcvFinishFlg = 0;
}
else
{
return;
}
//验证ID,开始数据帧解析处理 memcmp,strcmp 此方法不可用。
n = memcmp( ControllerID_add,&zylora_cmdpro.lorarevcmdinfo[2],6);
if( n == 0 )
{
ZYLoRa_SendStr_length(zylora_cmdpro.lorarevcmdinfo,zylora_cmdflg.LoRaRcvCnt); //返回接收信息
ZYLoRa_SlaveDevproStart();
}
else if( n > 0 )
{
memset(zylora_cmdpro.lorarevcmdinfo,0,zylora_cmdflg.LoRaRcvCnt);
ZYLoRa_SendStr_length(zylora_cmdpro.lorarevcmdinfo,zylora_cmdflg.LoRaRcvCnt); //返回接收信息
ZYLoRa_SendStr_length(zylora_cmdpro.lorarevcmdinfo,6); //返回接收信息
ZYLoRa_SendStr_length(&zylora_cmdpro.lorarevcmdinfo[2],6); //返回接收信息
zylora_cmdflg.LoRaRcvCnt = 0;
Busy_UartRxd = 0;
}
else if( n < 0 )
{
memset(zylora_cmdpro.lorarevcmdinfo,0,zylora_cmdflg.LoRaRcvCnt);
ZYLoRa_SendStr_length(zylora_cmdpro.lorarevcmdinfo,zylora_cmdflg.LoRaRcvCnt); //返回接收信息
ZYLoRa_SendStr_length(ControllerID_add,6); //返回接收信息
ZYLoRa_SendStr_length(&zylora_cmdpro.lorarevcmdinfo[2],6); //返回接收信息
zylora_cmdflg.LoRaRcvCnt = 0;
Busy_UartRxd = 0;
}
}
/**
* @brief LoRa数据帧解析处理
* @apply 线程调用
* @param void
* @retval
**/
#define ZYLoRa_SLAVE_PRO_STATE_IDLE 0
#define ZYLoRa_SLAVE_PTL_STATE_S0 1
#define ZYLoRa_SLAVE_PTL_STATE_S1 2
unsigned char ZYLoRaSlaveDevproState = 0;
void ZYLoRa_SlaveDevproStart(void)
{
ZYLoRaSlaveDevproState = ZYLoRa_SLAVE_PTL_STATE_S0;
}
void ZYLoRa_SlaveDevpro(void)
{
unsigned char RevCmd = 0;
unsigned char Flg = 0;
switch(ZYLoRaSlaveDevproState)
{
case ZYLoRa_SLAVE_PRO_STATE_IDLE:
{
}
break;
case ZYLoRa_SLAVE_PTL_STATE_S0:
{
RevCmd = zylora_cmdpro.revcmd_info.Cmd;
if(TASK_SUCESS == CheckDataframeCmd(RevCmd) ) //判断CMD是否有效
{
//协议处理数据更新
Flg = DataframeCmdPro();
if(TASK_SUCESS == Flg) //成功
{
/* 清除标志 */
memset(zylora_cmdpro.lorarevcmdinfo,0,zylora_cmdflg.LoRaRcvCnt);
Busy_UartRxd = 0;
ZYLoRaSlaveDevproState = ZYLoRa_SLAVE_PRO_STATE_IDLE;
}
else if(TASK_FAIL == Flg) //失败
{
/* 清除标志 */
memset(zylora_cmdpro.lorarevcmdinfo,0,zylora_cmdflg.LoRaRcvCnt);
Busy_UartRxd = 0;
ZYLoRaSlaveDevproState = ZYLoRa_SLAVE_PRO_STATE_IDLE;
}
}
else //CMD无效
{
/* 清除标志 */
memset(zylora_cmdpro.lorarevcmdinfo,0,zylora_cmdflg.LoRaRcvCnt);
Busy_UartRxd = 0;
ZYLoRaSlaveDevproState = ZYLoRa_SLAVE_PRO_STATE_IDLE;
}
}
break;
default:
break;
}
}
/**
* @brief LoRa模块通信状态机调用函数
* @param 无
* @retval 无
*/
void LoRaCommunication_StateMAC(void)
{
ZYLoRa_DataRec();
ZYLoRa_Dataverification();
ZYLoRa_Datavalidation();
ZYLoRa_SlaveDevpro();
}
/**
* @brief LoRa数据帧CMD指令验证
* @apply 状态机调用
* @param void
* @retval
**/
u8 CheckDataframeCmd(u8 CollectorTmpCmd)
{
u8 Cmd;
u8 BackCode = 0;
Cmd = CollectorTmpCmd;
switch(Cmd)
{
case Valveswitchcontrol_CMD:
case Readvalvestatus_CMD:
case Readvalveaddress_CMD:
case Readsoftwareversion_CMD:
case Readbatteryvoltage_CMD:
case Setvalveaddress_CMD:
case Acquisitiondata_CMD:
BackCode = TASK_SUCESS;
break;
default:
BackCode = TASK_FAIL;
break;
}
return BackCode;
}
/**
* @brief LoRa数据帧CMD指令处理
* @apply 线程调用
* @param void
* @retval
**/
u8 DataframeCmdPro(void)
{
u8 Cmd;
u8 BackCode = 0;
u8 ndelay;
u16 CrcValue_Storage = 0;
Cmd = zylora_cmdpro.revcmd_info.Cmd;
switch(Cmd)
{
case Valveswitchcontrol_CMD: //0x61
{
/* 选择阀门 */
if(zylora_cmdpro.revcmd_info.Data[0] == 1) //阀门1控制
{
ndelay=zylora_cmdpro.revcmd_info.Data[1];
if( (0 < ndelay) && (ndelay < 10) )
{
switch (zylora_cmdpro.revcmd_info.Data[2])
{
case 0x02:
{
BoostControl_Switch(1); //开启升压
delay_ms(100); //延时
Valvecontrol_One(0x01);//1关
delay_ms(ndelay*1000); //延时
Valvecontrol_One(0x11);//1低
delay_ms(100); //延时
BoostControl_Switch(0); //关闭升压
/* 保存控制器电磁阀实时状态 */
IapErase(0x0241);
IapProgram(0x0241,zylora_cmdpro.revcmd_info.Data[2]);
Devicedata.Storedata_info.Valvestatus_1 = IapRead(0x0241);
/* 返回执行情况 */
Cmd_Valvestatus[1] = zylora_cmdpro.revcmd_info.Instructiontype;
Cmd_Valvestatus[7] = zylora_cmdpro.revcmd_info.Deviceadd[1];
Cmd_Valvestatus[8] = zylora_cmdpro.revcmd_info.Cmd+1;
Cmd_Valvestatus[9] = 0x03;
Cmd_Valvestatus[10] = 0x01;
Cmd_Valvestatus[11] = zylora_cmdpro.revcmd_info.Data[1];
Cmd_Valvestatus[12] = zylora_cmdpro.revcmd_info.Data[2];
CrcValue_Storage = ZY_CRC16(Cmd_Valvestatus,13);
Cmd_Valvestatus[13] = CrcValue_Storage >> 8;
Cmd_Valvestatus[14] = CrcValue_Storage & 0xFF;
ZYLoRa_SendStr_length(Cmd_Valvestatus,15);//返回命令执行状态
}
break;
case 0x01:
{
BoostControl_Switch(1); //开启升压
delay_ms(100); //延时
Valvecontrol_One(0x10);//1开
delay_ms(ndelay*1000); //延时
Valvecontrol_One(0x00);//1断
delay_ms(100); //延时
BoostControl_Switch(0); //关闭升压
/* 保存控制器电磁阀实时状态 */
IapErase(0x0241);
IapProgram(0x0241,zylora_cmdpro.revcmd_info.Data[2]);
Devicedata.Storedata_info.Valvestatus_1 = IapRead(0x0241);
/* 返回执行情况 */
Cmd_Valvestatus[1] = zylora_cmdpro.revcmd_info.Instructiontype;
Cmd_Valvestatus[7] = zylora_cmdpro.revcmd_info.Deviceadd[1];
Cmd_Valvestatus[8] = zylora_cmdpro.revcmd_info.Cmd+1;
Cmd_Valvestatus[9] = 0x03;
Cmd_Valvestatus[10] = 0x01;
Cmd_Valvestatus[11] = zylora_cmdpro.revcmd_info.Data[1];
Cmd_Valvestatus[12] = zylora_cmdpro.revcmd_info.Data[2];
CrcValue_Storage = ZY_CRC16(Cmd_Valvestatus,13);
Cmd_Valvestatus[13] = CrcValue_Storage >> 8;
Cmd_Valvestatus[14] = CrcValue_Storage & 0xFF;
ZYLoRa_SendStr_length(Cmd_Valvestatus,15);//返回命令执行状态
}
break;
default:
break;
}
BackCode = TASK_SUCESS;
}
else
{
BackCode = TASK_FAIL;
}
}
else if(zylora_cmdpro.revcmd_info.Data[0] == 2) //阀门2控制
{
ndelay=zylora_cmdpro.revcmd_info.Data[1];
if( (0 < ndelay) && (ndelay < 10) )
{
switch (zylora_cmdpro.revcmd_info.Data[2])
{
case 0x02:
{
BoostControl_Switch(1); //开启升压
delay_ms(100); //延时
Valvecontrol_Two(0x01);//1关
delay_ms(ndelay*1000); //延时
Valvecontrol_Two(0x11);//1低
delay_ms(100); //延时
BoostControl_Switch(0); //关闭升压
/* 保存控制器电磁阀实时状态 */
IapErase(0x0442);
IapProgram(0x0442,zylora_cmdpro.revcmd_info.Data[2]);
Devicedata.Storedata_info.Valvestatus_2 = IapRead(0x0442);
/* 返回执行情况 */
Cmd_Valvestatus[1] = zylora_cmdpro.revcmd_info.Instructiontype;
Cmd_Valvestatus[7] = zylora_cmdpro.revcmd_info.Deviceadd[1];
Cmd_Valvestatus[8] = zylora_cmdpro.revcmd_info.Cmd+1;
Cmd_Valvestatus[9] = 0x03;
Cmd_Valvestatus[10] = 0x02;
Cmd_Valvestatus[11] = zylora_cmdpro.revcmd_info.Data[1];
Cmd_Valvestatus[12] = zylora_cmdpro.revcmd_info.Data[2];
CrcValue_Storage = ZY_CRC16(Cmd_Valvestatus,13);
Cmd_Valvestatus[13] = CrcValue_Storage >> 8;
Cmd_Valvestatus[14] = CrcValue_Storage & 0xFF;
ZYLoRa_SendStr_length(Cmd_Valvestatus,15);//返回命令执行状态
}
break;
case 0x01:
{
BoostControl_Switch(1); //开启升压
delay_ms(100); //延时
Valvecontrol_Two(0x10);//1开
delay_ms(ndelay*1000); //延时
Valvecontrol_Two(0x00);//1断
delay_ms(100); //延时
BoostControl_Switch(0); //关闭升压
/* 保存控制器电磁阀实时状态 */
IapErase(0x0442);
IapProgram(0x0442,zylora_cmdpro.revcmd_info.Data[2]);
Devicedata.Storedata_info.Valvestatus_2 = IapRead(0x0442);
/* 返回执行情况 */
Cmd_Valvestatus[1] = zylora_cmdpro.revcmd_info.Instructiontype;
Cmd_Valvestatus[7] = zylora_cmdpro.revcmd_info.Deviceadd[1];
Cmd_Valvestatus[8] = zylora_cmdpro.revcmd_info.Cmd+1;
Cmd_Valvestatus[9] = 0x03;
Cmd_Valvestatus[10] = 0x02;
Cmd_Valvestatus[11] = zylora_cmdpro.revcmd_info.Data[1];
Cmd_Valvestatus[12] = zylora_cmdpro.revcmd_info.Data[2];
CrcValue_Storage = ZY_CRC16(Cmd_Valvestatus,13);
Cmd_Valvestatus[13] = CrcValue_Storage >> 8;
Cmd_Valvestatus[14] = CrcValue_Storage & 0xFF;
ZYLoRa_SendStr_length(Cmd_Valvestatus,15);//返回命令执行状态
}
break;
default:
break;
}
BackCode = TASK_SUCESS;
}
else
{
BackCode = TASK_FAIL;
}
}
}
break;
case Readvalvestatus_CMD: //0x63
{
Cmd_batteryvoltage[1] = zylora_cmdpro.revcmd_info.Instructiontype;
Cmd_batteryvoltage[7] = zylora_cmdpro.revcmd_info.Deviceadd[1];
Cmd_batteryvoltage[8] = zylora_cmdpro.revcmd_info.Cmd+1;
Cmd_batteryvoltage[9] = 0x02;
Cmd_batteryvoltage[10] = Devicedata.Storedata_info.Valvestatus_1;
Cmd_batteryvoltage[11] = Devicedata.Storedata_info.Valvestatus_2;
CrcValue_Storage = ZY_CRC16(Cmd_batteryvoltage,12);
Cmd_batteryvoltage[12] = CrcValue_Storage >> 8;
Cmd_batteryvoltage[13] = CrcValue_Storage & 0xFF;
ZYLoRa_SendStr_length(Cmd_batteryvoltage,14);//返回状态
BackCode = TASK_SUCESS;
}
break;
case Readvalveaddress_CMD: //0x65
{
Cmd_executecom[1] = zylora_cmdpro.revcmd_info.Instructiontype;
Cmd_executecom[7] = zylora_cmdpro.revcmd_info.Deviceadd[1];
Cmd_executecom[8] = zylora_cmdpro.revcmd_info.Cmd+1;
Cmd_executecom[9] = 0x01;
Cmd_executecom[10] = ControllerID_add[5];
CrcValue_Storage = ZY_CRC16(Cmd_executecom,11);
Cmd_executecom[11] = CrcValue_Storage >> 8;
Cmd_executecom[12] = CrcValue_Storage & 0xFF;
ZYLoRa_SendStr_length(Cmd_executecom,13);//返回状态
BackCode = TASK_SUCESS;
}
break;
case Readsoftwareversion_CMD: //0x67
{
Cmd_version[1] = zylora_cmdpro.revcmd_info.Instructiontype;
Cmd_version[7] = zylora_cmdpro.revcmd_info.Deviceadd[1];
Cmd_version[8] = zylora_cmdpro.revcmd_info.Cmd+1;
Cmd_version[9] = 0x0B;
CrcValue_Storage = ZY_CRC16(Cmd_version,21);
Cmd_version[21] = CrcValue_Storage >> 8;
Cmd_version[22] = CrcValue_Storage & 0xFF;
ZYLoRa_SendStr_length(Cmd_version,23);//返回状态
BackCode = TASK_SUCESS;
}
break;
case Readbatteryvoltage_CMD: //0x69
{
Cmd_batteryvoltage[1] = zylora_cmdpro.revcmd_info.Instructiontype;
Cmd_batteryvoltage[7] = zylora_cmdpro.revcmd_info.Deviceadd[1];
Cmd_batteryvoltage[8] = zylora_cmdpro.revcmd_info.Cmd+1;
Cmd_batteryvoltage[9] = 0x02;
Cmd_batteryvoltage[10] = VBACCount() >> 8;
Cmd_batteryvoltage[11] = VBACCount() & 0xFF;
CrcValue_Storage = ZY_CRC16(Cmd_batteryvoltage,12);
Cmd_batteryvoltage[12] = CrcValue_Storage >> 8;
Cmd_batteryvoltage[13] = CrcValue_Storage & 0xFF;
ZYLoRa_SendStr_length(Cmd_batteryvoltage,14);//返回状态
BackCode = TASK_SUCESS;
}
break;
case Setvalveaddress_CMD: //0x6B
{
IapErase(0x0040);
IapProgram(0x0040,zylora_cmdpro.revcmd_info.Data[0]);
ControllerID_add[5] = IapRead(0x0040);
Cmd_executecom[1] = zylora_cmdpro.revcmd_info.Instructiontype;
Cmd_executecom[7] = zylora_cmdpro.revcmd_info.Deviceadd[1];
Cmd_executecom[8] = zylora_cmdpro.revcmd_info.Cmd+1;
Cmd_executecom[9] = 0x01;
Cmd_executecom[10] = 0x01;
CrcValue_Storage = ZY_CRC16(Cmd_executecom,11);
Cmd_executecom[11] = CrcValue_Storage >> 8;
Cmd_executecom[12] = CrcValue_Storage & 0xFF;
ZYLoRa_SendStr_length(Cmd_executecom,13);//返回状态
BackCode = TASK_SUCESS;
}
break;
case Acquisitiondata_CMD: //0x6D
{
Cmd_executecom[1] = zylora_cmdpro.revcmd_info.Instructiontype;
Cmd_executecom[7] = zylora_cmdpro.revcmd_info.Deviceadd[1];
Cmd_executecom[8] = zylora_cmdpro.revcmd_info.Cmd+1;
Cmd_executecom[9] = 0x01;
Cmd_executecom[10] = 0xFF;
CrcValue_Storage = ZY_CRC16(Cmd_executecom,11);
Cmd_executecom[11] = CrcValue_Storage >> 8;
Cmd_executecom[12] = CrcValue_Storage & 0xFF;
ZYLoRa_SendStr_length(Cmd_executecom,13);//返回状态
BackCode = TASK_SUCESS;
}
break;
default:
BackCode = TASK_FAIL;
break;
}
return BackCode;
}C:\Users\Administrator\Desktop\05 |
|