/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "can.h"
#include "tim.h"
#include "gpio.h"
#include <stdio.h>
#include <stdint.h>
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
CAN_TxHeaderTypeDef TXHeader1;
//CAN_RxHeaderTypeDef RXHeader1;
CAN_TxHeaderTypeDef TXHeader2;
CAN_RxHeaderTypeDef RXHeader2;
uint8_t H[50]={0};
uint8_t E[50]={0};
uint8_t NCell=40;
uint8_t SCmd;
uint8_t NE=0;
uint8_t NEE=0; //针对一个回“Y”的子节点都没有的情况
uint8_t NH=0;
uint8_t n=0;
uint8_t CRCJC=0;
uint32_t CRC_START=0xFFFFFFFF;
uint32_t CRC_OVER=0;
uint8_t num;
uint8_t num1;
uint8_t num2;
uint8_t num3;
uint8_t num4;
uint32_t crc;
uint32_t crc_set;
uint32_t result;
uint32_t poly=0x04C11DB7;
uint16_t clearCAN_Rxdata_LZG=0;
uint8_t m=0;
uint8_t mm=0;
uint8_t c=0;
uint8_t i=0;
uint8_t size=4;
uint8_t Error[4]={0x42,0x02,0,0};
uint8_t HAND[8];
uint8_t YAND[2];
uint8_t ZAND[3];
uint8_t RR[2];
uint8_t AS[3];
uint8_t TX0[7];
uint8_t TX1[8];
uint8_t TX2[8];
uint8_t TX3[8];
uint8_t TX4[8];
uint8_t TX5[4];
uint8_t QX0[1]={0x52};
uint8_t zxnumbers[3];
uint8_t pxnumbers[3];
uint32_t zzxnumbers[2];
uint32_t ppxnumbers[2];
uint32_t zzzxnumbers[4];
uint32_t pppxnumbers[4];
uint32_t fxmax;
uint32_t zxmax;
uint32_t pxmax;
uint8_t dmax;
uint8_t xmax;
uint8_t max;
uint8_t b[10]={0};
//uint8_t b2;
//uint8_t b3;
//uint8_t b4;
//uint8_t b5;
uint64_t combine_bytes(uint8_t b0,uint8_t b1,uint8_t b2,uint8_t b3,uint8_t b4)
{
return ((uint64_t)b0 << 32) |
((uint64_t)b1 << 24) |
((uint64_t)b2 << 16) |
((uint64_t)b3 << 8) |
(uint64_t)b4;
}
uint64_t csq;
uint8_t NQ;
uint8_t NL;//CRC不通过的子节点的数据的重发次数
uint8_t TXmessage2[8];
uint8_t RXmessage2[8];
uint32_t pTxMailbox = 0;
uint8_t RxData[8];
uint8_t Data[8];
uint8_t DataH[2];
uint8_t DataA[3];
uint8_t Dataa[8];
uint8_t Dataaa[8];
uint8_t NT; //定时器计数值
uint32_t TxMailbox;
uint8_t CAN_Rxdata_LZG[40*3*8*2];//总数据:0X43、0X00、0X40、64个字节数据+0X44、0X04、0X80、1152个字节数据
uint8_t RX_LEN_CAN=0;
uint8_t stage;
uint8_t stageZ='O';
uint8_t gu7SCIStatus=0;
uint8_t gu2SCIStatus=0;
uint8_t gu3SCIStatus=0;
uint32_t NData;//实际收到的数据长度
uint32_t NDataa;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);//系统时钟初始化
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void CAN1_Send_Stage(uint8_t Data)//主节点与上位机握手
{
TXHeader1.StdId=ID1;// 标准标识符为0
TXHeader1.ExtId=0x00; // 设置扩展标示符(29位)
TXHeader1.IDE=0; // 使用标准标识符
TXHeader1.RTR=0; // 消息类型为数据帧
TXHeader1.DLC=1;
HAL_CAN_AddTxMessage(&hcan1,&TXHeader1,&Data,&pTxMailbox);
while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan1)!=3);//3个发送邮箱都为空时跳出循环
}
void CAN1_Send_Msg(uint8_t* Data,uint8_t len)//连续取8个字节的地址
{
TXHeader1.StdId=ID1;// 标准标识符为0
TXHeader1.ExtId=0x00; // 设置扩展标示符(29位)
TXHeader1.IDE=0; // 使用标准标识符
TXHeader1.RTR=0; // 消息类型为数据帧
TXHeader1.DLC=len;
HAL_CAN_AddTxMessage(&hcan1,&TXHeader1,Data,&pTxMailbox);
while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan1)!=3);
}
void CAN1_Send_error(uint8_t Data1,uint8_t Data2)
{
uint8_t Data[4]; //定义一个长度为4的数组,用于存储要发送的CAN消息数据
Data[0]=Data1;
Data[1]=0x02;
Data[2]=(Data2>>8)&0xFF;//
Data[3]=Data2&0xFF;//
TXHeader1.StdId=ID1;// 标准标识符为0
TXHeader1.ExtId=0x00; // 设置扩展标示符(29位)
TXHeader1.IDE=0; // 使用标准标识符
TXHeader1.RTR=0; // 消息类型为数据帧
TXHeader1.DLC=4;
HAL_CAN_AddTxMessage(&hcan1,&TXHeader1,Data,&pTxMailbox);
while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan1)!=3);
}
void CAN2_Send_Msg(uint8_t* Data,uint8_t len,uint8_t IDX)
{
TXHeader2.StdId=IDX; // 标准标识符为0
TXHeader2.ExtId=0x00; // 设置扩展标示符(29位)
TXHeader2.IDE=0; // 使用标准标识符
TXHeader2.RTR=0; // 消息类型为数据帧
TXHeader2.DLC=len;
HAL_CAN_AddTxMessage(&hcan2,&TXHeader2,Data,&pTxMailbox);
while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan2)!=3);
}
void CAN2_Send_Stage(uint8_t Data,uint8_t IDX)
{
TXHeader2.StdId=IDX; // 标准标识符为0
TXHeader2.ExtId=0x00; // 设置扩展标示符(29位)
TXHeader2.IDE=0; // 使用标准标识符
TXHeader2.RTR=0; // 消息类型为数据帧
TXHeader2.DLC=1;
HAL_CAN_AddTxMessage(&hcan2,&TXHeader2,&Data,&pTxMailbox);
while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan2)!=3);
}
void find_max(uint32_t *numbers, int size) //算最大步数
{
fxmax = numbers[0];
for (i = 1; i < size; i++)
{
if (numbers[i] > fxmax)
{
fxmax = numbers[i];
}
}
}
//声明
void CAN2_HAND_CMD();
void CAN2_HAND_RESH();
void CAN2_HAND_HH();
void CAN2_STOP_CMD();
void CAN2_STOP_RESH();
void CAN2_STOP_HH();
void CAN2_RUNNING_CMD();
void CAN2_RUN_RR();
void CAN2_RUN_RESR();
void CAN2_RUN_RRR();
void CAN2_RUN_ASK();
void CAN2_RUN_EE();
void CAN2_RUNNING_END();
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) //来自子节点的消息
{
if(hcan->Instance==CAN2) //若寄存器基地址为CAN2
{
HAL_CAN_GetRxMessage(hcan,CAN_FILTER_FIFO1,&RXHeader2,RXmessage2);//获取数据
if(RXmessage2[0]==0x48) //"H"
{
n=RXHeader2.StdId;
if(H[n]=='D')
{
H[n]='H';
NE++;//子节点回的信号数
}
if(H[n]!='D'&&H[n]!='H')
{
H[n]='B';
}
if(NE==NH)
{
CAN2_HAND_HH();
}
}
if(RXmessage2[0]==0x53) //"S"
{
n=RXHeader2.StdId;
if(H[n]=='D')
{
H[n]='S';
NE++;//子节点回的信号数
}
if(H[n]!='D'&&H[n]!='S')
{
H[n]='B';
}
if(NE==NH)
{
CAN2_STOP_HH();
}
}
if(RXmessage2[0]==0x59) //"Y"
{
n=RXHeader2.StdId;
if(H[n]=='H')
{
H[n]='R';
NE++;
NEE++;
}
if(H[n]!='H'&&H[n]!='R')
{
H[n]='B';
}
if(NE==NH)
{
NE=0;
CAN2_RUN_RRR();
}
}
else if(RXmessage2[0]==0x45) //"E"
{
n=RXHeader2.StdId;
if(H[n]=='R')
{
H[n]='E';
NE++;
}
if(H[n]!='R'&&H[n]!='E')
{
H[n]='B';
}
if(NE==NH)
{
CAN2_RUNNING_END();
}
}
else if(RXmessage2[0]==0x54) //"T"
{
n=RXHeader2.StdId;
ZAND[0]=RXmessage2[0];
ZAND[1]=RXmessage2[1];
ZAND[2]=n;
CAN1_Send_Msg(ZAND,3);
}
else if(RXmessage2[0]==0x58) //"X"
{
n=RXHeader2.StdId;
ZAND[0]=RXmessage2[0];
ZAND[1]=RXmessage2[1];
ZAND[2]=n;
CAN1_Send_Msg(ZAND,3);
}
else if(RXmessage2[0]==0x4C) //"L"
{
if(NL==2)
{
NL=0;
n=RXHeader2.StdId;
ZAND[0]=RXmessage2[0];
ZAND[1]=RXmessage2[1];
ZAND[2]=n;
CAN1_Send_Msg(ZAND,3);
}
else
{
n=RXHeader2.StdId;
TX0[0]=0X44;
TX0[1]=DataH[1];
TX0[2]=b[0];
for(i=0;i<=7;i++)
{
TX1[i]=CAN_Rxdata_LZG[i+0+(n-1)*24];
TX2[i]=CAN_Rxdata_LZG[i+8+(n-1)*24];
TX3[i]=CAN_Rxdata_LZG[i+16+(n-1)*24];
}
crc=CRC_START;
mm=0;
for(mm=1+3*(n-1);mm<=3*n;mm++)
{
for(c=0;c<8;c++)
{
crc = crc^(CAN_Rxdata_LZG[c+8*(mm-1)]<<24) ;
for (i = 0; i < 8; i++)
{
if (crc & 0x80000000)
{
crc = (crc << 1)^poly;
}
else
{
crc <<= 1;
}
}
}
}
crc = crc^CRC_OVER;
for(i=3;i<7;i++) //将32位CRC码拆成4个8位的CRC码存入TX0[i]中
{
TX0[9-i] = (crc>>((i-3)*8))& 0xFF; //TX0[3]= 低8位,TX0[4]= 9-16位,TX0[5]= 17-24位,TX0[6]= 25-32位
}//CRC
CAN2_Send_Msg(TX0,7,n);
CAN2_Send_Msg(TX1,8,n);
CAN2_Send_Msg(TX2,8,n);
CAN2_Send_Msg(TX3,8,n);
RR[0]=0x52;
RR[1]=DataH[1];
CAN2_Send_Msg(RR,2,n);
NL++;
}
}
}
}
void CAN2_HAND_CMD(void) //主节点接收Check命令后,开始向子节点握手
{
YAND[0]=0x59;
YAND[1]=Data[1];
CAN1_Send_Msg(YAND,2);
HAND[0]=0x48;
HAND[1]=Data[1];
csq=combine_bytes(b[0],b[1],b[2],b[3],b[4]);
for(n=1;n<=NCell;n++)
{
switch((csq>>(NCell-n))&1) //修改NCell时此处必须更改!!!
{
case 1:
CAN2_Send_Msg(HAND,2,n);
H[n]='D';
NH++;
break;
}
if(n==NCell)
{
NT=0;
stage='C';
HAL_TIM_Base_Start_IT(&htim6);
NT=0; //也许可以,待测试
}
}
}
void CAN2_HAND_RESH(void)
{
HAL_TIM_Base_Stop_IT(&htim6);
NT=0;//测试
if(NE==NH||NQ==1)
{
NQ=0;
CAN2_HAND_HH();
}
else
{
for(n=1;n<=NCell;n++)
{
if(H[n]=='D')
{
// HAND[0]=0x55; //测试
CAN2_Send_Msg(HAND,2,n);
}
}
NQ++;
NT=0;
stage='C';
HAL_TIM_Base_Start_IT(&htim6);
NT=0; //也许可以,待测试
}
}
void CAN2_HAND_HH(void)
{
HAL_TIM_Base_Stop_IT(&htim6);
NT=0;//测试
for(n=1;n<=NCell;n++)
{
if(H[n]=='D'||H[n]=='B')
{
Data[0]=0x42;
Data[1]=HAND[1];
Data[2]=n;
Data[3]=2;
CAN1_Send_Msg(Data,4);
}
}
Data[0]=0x45;
Data[1]=HAND[1];
CAN1_Send_Msg(Data,2);
stageZ='O';
Data[0]=Data[1]=b[0]=b[1]=b[2]=b[3]=b[4]=0;
csq=0;
NE=NH=0;
NQ=0;
}
void CAN2_STOP_CMD(void) //主节点接收Stop命令后,开始向子节点Stop
{
YAND[0]=0x59;
YAND[1]=Data[1];
CAN1_Send_Msg(YAND,2);
HAND[0]=0x53;
HAND[1]=Data[1];
csq=combine_bytes(b[0],b[1],b[2],b[3],b[4]);
for(n=1;n<=NCell;n++)
{
switch((csq>>(NCell-n))&1) //修改NCell时此处必须更改!!!
{
case 1:
CAN2_Send_Msg(HAND,2,n);
H[n]='D';
NH++;
break;
}
if(n==NCell)
{
NT=0;
stage='S';
HAL_TIM_Base_Start_IT(&htim6);
NT=0; //也许可以,待测试
}
}
}
void CAN2_STOP_RESH(void)
{
HAL_TIM_Base_Stop_IT(&htim6);
NT=0;//测试
if(NE==NH||NQ==2)
{
NQ=0;
CAN2_STOP_HH();
}
else
{
for(n=1;n<=NCell;n++)
{
if(H[n]=='D')
{
CAN2_Send_Msg(HAND,2,n);
}
}
NQ++;
NT=0;
stage='S';
HAL_TIM_Base_Start_IT(&htim6);
NT=0; //也许可以,待测试
}
}
void CAN2_STOP_HH(void)
{
HAL_TIM_Base_Stop_IT(&htim6);
NT=0;//测试
for(n=1;n<=NCell;n++)
{
if(H[n]=='D'||H[n]=='B')
{
Data[0]=0x42;
Data[1]=HAND[1];
Data[2]=n;
Data[3]=2;
CAN1_Send_Msg(Data,4);
}
H[n]=0;
}
Data[0]=0x45;
Data[1]=HAND[1];
CAN1_Send_Msg(Data,2);
stageZ='O';
NE=NH=0;
NQ=0;
}
void CAN2_RUNNING_CMD(void) //主节点接收上位机发来的运转数据,并按需发给相应的子节点
{
//CRC校验→上位机通讯
num1 = b[1];
num2 = b[2];
num3 = b[3];
num4 = b[4];
result = (num1 << 24) | (num2 << 16) | (num3 << 8) | num4;
num=3*40; //修改NCell时此处必须更改, 3*3实际为3*(上位机有发送数据的子节点的总个数,未必是40)!!!!!!
crc=CRC_START;
mm=0;
for(mm=0;mm<num;mm++)
{
for(c=0;c<8;c++)
{
crc = crc^(CAN_Rxdata_LZG[c+8*mm]<<24) ;
for (i = 0; i < 8; i++)
{
if (crc & 0x80000000)
{
crc = (crc << 1)^poly;
}
else
{
crc <<= 1;
}
}
}
}
crc = crc^CRC_OVER;
if(crc!=result)
{
Data[0]=0x4C;//CRC校验出错会向上位机报"L"
Data[1]=DataH[1];
Data[2]=0;
Data[3]=0x02;//轴序号为两轴
CAN1_Send_Msg(Data,4);
YAND[0]=0x4C;
YAND[1]=NDataa;
CAN1_Send_Msg(YAND,2);
for (clearCAN_Rxdata_LZG = 0; clearCAN_Rxdata_LZG < 40*3*8*2; clearCAN_Rxdata_LZG++)
{
CAN_Rxdata_LZG[clearCAN_Rxdata_LZG] = 0;
}
NData=0;
NDataa=0;
}
else
//如果对
{
stageZ='R';
HAND[0]=0x59; //CRC校验通过,先回“Y”
HAND[1]=DataH[1];
CAN1_Send_Msg(HAND,2);
TX0[0]=0X44;
TX0[1]=DataH[1];
TX0[2]=b[0];
zxmax = 0;
pxmax = 0;
dmax = 0;
xmax = 0;
for(n=1;n<=NCell;n++)
{
for(i=0;i<=7;i++)
{
TX1[i]=CAN_Rxdata_LZG[i+0+(n-1)*24];
TX2[i]=CAN_Rxdata_LZG[i+8+(n-1)*24];
TX3[i]=CAN_Rxdata_LZG[i+16+(n-1)*24];
}
m = 0;
for(i=0;i<=7;i++)
{
if(TX1[i]!=0)
{
m=1;
}
}
for(i=0;i<=7;i++)
{
if(TX2[i]!=0)
{
m=1;
}
}
for(i=0;i<=7;i++)
{
if(TX3[i]!=0)
{
m=1;
}
}
if(m==1)
{
m=0;
crc=CRC_START;//CRC→发送给子节点
mm=0;
for(mm=1+3*(n-1);mm<=3*n;mm++)
{
for(c=0;c<8;c++)
{
crc = crc^(CAN_Rxdata_LZG[c+8*(mm-1)]<<24) ;
for (i = 0; i < 8; i++)
{
if (crc & 0x80000000)
{
crc = (crc << 1)^poly;
}
else
{
crc <<= 1;
}
}
}
}
crc = crc^CRC_OVER;
for(i=3;i<7;i++) //将32位CRC码拆成4个8位的CRC码存入TX0[i]中
{
TX0[9-i] = (crc>>((i-3)*8))& 0xFF; //TX0[3]= 低8位,TX0[4]= 9-16位,TX0[5]= 17-24位,TX0[6]= 25-32位
}
//判断是大单元还是小单元
if (TX2[0] == 0xFF&&TX2[1] == 0xFF&&TX2[2] == 0xFF&&TX2[3] == 0xFF)
{
for(c=1;c<2;c++) //算时间,适用于大单元
{
for (i = 0; i < 2; i++)
{
zxnumbers[0]=CAN_Rxdata_LZG[4*i+8*(n-1)+16*(n-1)]&0x3F;
zxnumbers[1]=CAN_Rxdata_LZG[4*i+1+8*(n-1)+16*(n-1)];
zxnumbers[2]=CAN_Rxdata_LZG[4*i+2+8*(n-1)+16*(n-1)]&0x80;
zxnumbers[2]=zxnumbers[2]>>7;
pxnumbers[0]=CAN_Rxdata_LZG[4*i+2+8*(n-1)+16*(n-1)]&0x7F;
pxnumbers[1]=CAN_Rxdata_LZG[4*i+3+8*(n-1)+16*(n-1)];
zzxnumbers[i]=(zxnumbers[0]*512+zxnumbers[1]*2+zxnumbers[2])*4;//2的10次方=1024,2的2次方=4
ppxnumbers[i]=(pxnumbers[0]*256+pxnumbers[1])*4;
}
zzzxnumbers[c]= zzxnumbers[0]+zzxnumbers[1];
pppxnumbers[c]= ppxnumbers[0]+ppxnumbers[1];
}
fxmax = zzzxnumbers[1];
if (zxmax < fxmax)
{
zxmax = fxmax;
}
fxmax = pppxnumbers[1];
if (pxmax < fxmax)
{
pxmax = fxmax;
}
zxmax = (zxmax*27/14336+5)/5 + 1;//得改
pxmax = (pxmax*36/18432+5)/5 + 1;//得改
if (zxmax <= pxmax )
{
dmax = pxmax;
}
else
{
dmax = zxmax;
}
}
else
{
for(c=1;c<4;c++) //算时间,适用于小单元
{
for (i = 0; i < 2; i++)
{
zxnumbers[0]=CAN_Rxdata_LZG[4*i+8*n*c-8]&0x3F;
zxnumbers[1]=CAN_Rxdata_LZG[4*i+1+8*n*c-8];
zxnumbers[2]=CAN_Rxdata_LZG[4*i+2+8*n*c-8]&0xC0;
zxnumbers[2]=zxnumbers[2]>>6;
pxnumbers[0]=CAN_Rxdata_LZG[4*i+2+8*n*c-8]&0x3F;
pxnumbers[1]=CAN_Rxdata_LZG[4*i+3+8*n*c-8];
zzxnumbers[i]=(zxnumbers[0]*1024+zxnumbers[1]*4+zxnumbers[2])*2;//2的10次方=1024,2的2次方=4
ppxnumbers[i]=pxnumbers[0]*256+pxnumbers[1];
}
zzzxnumbers[c]= zzxnumbers[0]+zzxnumbers[1];
pppxnumbers[c]= ppxnumbers[0]+ppxnumbers[1];
}
//调用函数
find_max(zzzxnumbers, size);
if (zxmax < fxmax)
{
zxmax = fxmax;
}
find_max(pppxnumbers, size);
if (pxmax < fxmax)
{
pxmax = fxmax;
}
zxmax = (zxmax*30/85729.13+5)/5 + 2; //10实验完要去掉
pxmax = (pxmax*30/32386.56+5)/5 + 2; //10实验完要去掉
if (zxmax <= pxmax )
{
xmax = pxmax;
}
else
{
xmax = zxmax;
}
}
CAN2_Send_Msg(TX0,7,n);//其中后四字节为CRC码
CAN2_Send_Msg(TX1,8,n);
CAN2_Send_Msg(TX2,8,n);
CAN2_Send_Msg(TX3,8,n);
}
if (dmax <= xmax )
{
max = xmax;
}
else
{
max = dmax;
}
}
CAN2_RUN_RR();
}
}
void CAN2_RUN_RR(void) //发送运转命令“R”
{
RR[0]=0x52;
RR[1]=DataH[1];
for(n=1;n<=NCell;n++)
{
for(i=0;i<=7;i++)
{
TX1[i]=CAN_Rxdata_LZG[i+0+(n-1)*24];
TX2[i]=CAN_Rxdata_LZG[i+8+(n-1)*24];
TX3[i]=CAN_Rxdata_LZG[i+16+(n-1)*24];
}
m = 0;
for(i=0;i<=7;i++)
{
if(TX1[i]!=0||TX2[i]!=0||TX3[i]!=0)
{
m=1;
}
}
if(m==1&&H[n]=='H')
{
CAN2_Send_Msg(RR,2,n);
NH++;
}
else
{
H[n]=0;
}
if(n==NCell)
{
NT=0;
stage='R';
HAL_TIM_Base_Start_IT(&htim6);
NT=0; //也许可以,待测试
}
}
if(NH==0) //针对一个需要发“R”的子节点都没有的情况
{
CAN2_RUNNING_END();
}
}
void CAN2_RUN_RESR(void) //重发运转命令“R”
{
HAL_TIM_Base_Stop_IT(&htim6);
NT=0;//测试
RR[0]=0x52;
RR[1]=DataH[1];
if(NE==NH||NQ==2)
{
NQ=0;
CAN2_RUN_RRR();
}
else
{
for(n=1;n<=NCell;n++)
{
if(H[n]=='H')
{
CAN2_Send_Msg(RR,2,n);
}
}
NQ++;
NT=0;
stage='R';
HAL_TIM_Base_Start_IT(&htim6);
NT=0; //也许可以,待测试
}
}
//void CAN2_RUN_RRR(void) //原版
//{
// HAL_TIM_Base_Stop_IT(&htim6);
// NT=0;//测试
// for(n=1;n<=NCell;n++)
// {
// if(H[n]=='H'||H[n]=='B')//对于回比发多和回与发数量相等但不一致的情况,直接向上位机报“B”
// {
// Data[0]=0x42;
// Data[1]=DataH[1];
// Data[2]=n;
// Data[3]=2;
// CAN1_Send_Msg(Data,4);
// }
// }
// CAN2_RUN_EE();
//}
void CAN2_RUN_RRR(void) //新版
{
HAL_TIM_Base_Stop_IT(&htim6);
NT=0;//测试
if(NEE!=0) //针对一个回“Y”的子节点都没有的情况
{
for(n=1;n<=NCell;n++)
{
if(H[n]=='H'||H[n]=='B')//对于回比发多和回与发数量相等但不一致的情况,直接向上位机报“B”
{
Data[0]=0x42;
Data[1]=DataH[1];
Data[2]=n;
Data[3]=2;
CAN1_Send_Msg(Data,4);
}
}
CAN2_RUN_EE();
}
else
{
CAN2_RUNNING_END();
}
}
void CAN2_RUN_EE(void) //给运转留max时间
{
NT=0;
stage='E';
HAL_TIM_Base_Start_IT(&htim6);
NT=0; //也许可以,待测试
NQ=0;
}
void CAN2_RUN_ASK(void)
{
HAL_TIM_Base_Stop_IT(&htim6);
NT=0;//测试
if(NE==NH||NQ==2)
{
NQ=0;
CAN2_RUNNING_END();
}
else
{
AS[0]=0x41;
AS[1]=RR[1];
AS[2]=0x52;
for(n=1;n<=NCell;n++)
{
if(H[n]=='R')
{
CAN2_Send_Msg(AS,3,n);
}
}
NQ++;
NT=0;
stage='A';
HAL_TIM_Base_Start_IT(&htim6);
NT=0; //也许可以,待测试
}
}
void CAN2_RUNNING_END(void) //检测子节点是否按所发数据运转完成
{
HAL_TIM_Base_Stop_IT(&htim6);
NT=0;//测试
for(n=1;n<=NCell;n++)
{
if(H[n]=='H'||H[n]=='R'||H[n]=='B')
{
Data[0]=0x42;
Data[1]=DataH[1];
Data[2]=n;
Data[3]=2;
CAN1_Send_Msg(Data,4);
H[n]='D';
}
else
{
H[n]='H';
}
}
Data[0]=0x45;
Data[1]=HAND[1];
CAN1_Send_Msg(Data,2);
stageZ='O';
crc=0;
result=0;
NData=0;
NDataa=0;
NEE=NE=NH=0;
NQ=0;
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) //实时监测:被迫进行下一步
{
NT++;
if(NT==2&&stage=='C')//&&是逻辑与
{
CAN2_HAND_RESH();
}
if(NT==2&&stage=='S')//&&是逻辑与
{
CAN2_STOP_RESH();
}
if(NT==1&&stage=='R')//&&是逻辑与
{
CAN2_RUN_RESR();
}
if(NT==max*2&&stage=='E')
{
CAN2_RUN_ASK();
}
if(NT==2&&stage=='A')
{
CAN2_RUN_ASK(); //一轮询问结束后
}
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_CAN1_Init();
MX_CAN2_Init();
MX_TIM6_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim6);
HAL_TIM_Base_Stop_IT(&htim6);
NT=0;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
while (1)
{
if(gu2SCIStatus==2)
{
gu2SCIStatus=0;
if(DataH[0]==0x48)
{
CAN1_Send_Msg(DataH,2);
}
if(DataH[0]==0x52)
{
if(stageZ=='S')
{
YAND[0]=0x58;
YAND[1]=0x53;
CAN1_Send_Msg(YAND,2);
}
if(stageZ=='C')
{
YAND[0]=0x58;
YAND[1]=0x43;
CAN1_Send_Msg(YAND,2);
}
if(stageZ=='R')
{
if(HAND[1]==DataH[1])
{
YAND[0]=0x59;
YAND[1]=DataH[1];
CAN1_Send_Msg(YAND,2);
}
else
{
YAND[0]=0x58;
YAND[1]=0x52;
CAN1_Send_Msg(YAND,2);
}
}
if(stageZ=='O')
{
if(HAND[1]==DataH[1])
{
YAND[0]=0x54;
YAND[1]=RR[1];
CAN1_Send_Msg(YAND,2);
}
else
{
CAN2_RUNNING_CMD();
}
}
}
}
else if(gu7SCIStatus==7)
{
NH=0; //子节点回的信号数
NE=0; //主节点发送子节点个数
switch(Data[0])
{
case 0x43:
gu7SCIStatus=0;
switch(stageZ)
{
case 'S':
YAND[0]=0x58;
YAND[1]=0x53;
CAN1_Send_Msg(YAND,2);
break;
case 'R':
YAND[0]=0x58;
YAND[1]=0x52;
CAN1_Send_Msg(YAND,2);
break;
case 'C':
if(Data[1]==HAND[1])
{
YAND[0]=0x59;
YAND[1]=HAND[1];
CAN1_Send_Msg(YAND,2);
}
else
{
YAND[0]=0x58;
YAND[1]=0x43;
CAN1_Send_Msg(YAND,2);
}
break;
case 'O':
stageZ='C';
CAN2_HAND_CMD();
break;
}
break;
case 0x53:
gu7SCIStatus=0;
switch(stageZ)
{
case 'C':
YAND[0]=0x58;
YAND[1]=0x43;
CAN1_Send_Msg(YAND,2);
break;
case 'R':
YAND[0]=0x58;
YAND[1]=0x52;
CAN1_Send_Msg(YAND,2);
break;
case 'S':
if(Data[1]==HAND[1])
{
YAND[0]=0x59;
YAND[1]=HAND[1];
CAN1_Send_Msg(YAND,2);
}
else
{
YAND[0]=0x58;
YAND[1]=0x53;
CAN1_Send_Msg(YAND,2);
}
break;
case 'O':
stageZ='S';
CAN2_STOP_CMD();
break;
}
break;
case 0x44:
gu7SCIStatus=0;
break;
}
}
else if(gu3SCIStatus==3)
{
gu3SCIStatus=0;
switch(DataA[0])
{
case 0x41:
switch(DataA[2])
{
case 0x43:
switch(stageZ)
{
case 'C':
if(DataA[1]==YAND[1])
{
YAND[0]=0x57;
YAND[1]=YAND[1];
CAN1_Send_Msg(YAND,2);
}
else
{
YAND[0]=0x54;
YAND[1]=YAND[1];
CAN1_Send_Msg(YAND,2);
}
break;
case 'O':
if(DataA[1]==YAND[1])
{
YAND[0]=0x45;
YAND[1]=YAND[1];
CAN1_Send_Msg(YAND,2);
}
else
{
YAND[0]=0x54;
YAND[1]=YAND[1];
CAN1_Send_Msg(YAND,2);
}
break;
default:
YAND[0]=0x54;
YAND[1]=YAND[1];
CAN1_Send_Msg(YAND,2);
break;
}
break;
case 0x53:
switch(stageZ)
{
case 'S':
if(DataA[1]==YAND[1])
{
YAND[0]=0x57;
YAND[1]=YAND[1];
CAN1_Send_Msg(YAND,2);
}
else
{
YAND[0]=0x54;
YAND[1]=YAND[1];
CAN1_Send_Msg(YAND,2);
}
break;
case 'O':
if(DataA[1]==YAND[1])
{
YAND[0]=0x45;
YAND[1]=YAND[1];
CAN1_Send_Msg(YAND,2);
}
else
{
YAND[0]=0x54;
YAND[1]=YAND[1];
CAN1_Send_Msg(YAND,2);
}
break;
default:
YAND[0]=0x54;
YAND[1]=YAND[1];
CAN1_Send_Msg(YAND,2);
break;
}
break;
case 0x52:
switch(stageZ)
{
case 'R':
if(DataA[1]==HAND[1])
{
YAND[0]=0x57;
YAND[1]=HAND[1];
CAN1_Send_Msg(YAND,2);
}
else
{
YAND[0]=0x54;
YAND[1]=HAND[1];
CAN1_Send_Msg(YAND,2);
}
break;
case 'O':
if(DataA[1]==HAND[1])
{
YAND[0]=0x45;
YAND[1]=HAND[1];
CAN1_Send_Msg(YAND,2);
}
else
{
YAND[0]=0x54;
YAND[1]=HAND[1];
CAN1_Send_Msg(YAND,2);
}
break;
default:
YAND[0]=0x54;
YAND[1]=HAND[1];
CAN1_Send_Msg(YAND,2);
break;
}
break;
}
}
}
}
}
/* USER CODE END 3 */
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_HSE;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8;
RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
/** Configure the Systick interrupt time
*/
__HAL_RCC_PLLI2S_ENABLE();
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file tim.c
* @brief This file provides code for the configuration
* of the TIM instances.
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "tim.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
TIM_HandleTypeDef htim6;
/* TIM6 init function */
void MX_TIM6_Init(void)
{
/* USER CODE BEGIN TIM6_Init 0 */
/* USER CODE END TIM6_Init 0 */
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM6_Init 1 */
/* USER CODE END TIM6_Init 1 */
htim6.Instance = TIM6;
htim6.Init.Prescaler = 63999; // 预分频器:64MHz/(63999+1)=1kHz
htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
htim6.Init.Period = 2500; //周期值:1kHz×2500=2500ms(2.5秒)
htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM6_Init 2 */
/* USER CODE END TIM6_Init 2 */
}
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{
if(tim_baseHandle->Instance==TIM6)
{
/* USER CODE BEGIN TIM6_MspInit 0 */
/* USER CODE END TIM6_MspInit 0 */
/* TIM6 clock enable */
__HAL_RCC_TIM6_CLK_ENABLE();
/* TIM6 interrupt Init */
HAL_NVIC_SetPriority(TIM6_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM6_IRQn);
/* USER CODE BEGIN TIM6_MspInit 1 */
HAL_NVIC_SetPriority(TIM6_IRQn,0, 0);
HAL_NVIC_EnableIRQ(TIM6_IRQn); //
/* USER CODE END TIM6_MspInit 1 */
}
}
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
{
if(tim_baseHandle->Instance==TIM6)
{
/* USER CODE BEGIN TIM6_MspDeInit 0 */
/* USER CODE END TIM6_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM6_CLK_DISABLE();
/* TIM6 interrupt Deinit */
HAL_NVIC_DisableIRQ(TIM6_IRQn);
/* USER CODE BEGIN TIM6_MspDeInit 1 */
/* USER CODE END TIM6_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
分析上述代码,对下面的问题给出解释:为什么在主函数里执行完 NT=0;
stage='R';
HAL_TIM_Base_Start_IT(&htim6);后会使NT直接跳变成1并且进入CAN2_RUN_RESR();中?
最新发布