实验2-2 长度修饰符l和修饰符h的使用

本文通过实验探讨了在C语言中,长度修饰符'l'和'h'对整型变量(如long、short)在printf和scanf函数中的影响。实验表明,使用不匹配的长度修饰符会导致数据丢失或扩充,输出值可能与原始值不同。同时,未赋值的变量在某些编译器中可能会显示预设的存储状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 实验目的:

用printf函数正确输出整型变量的值时需要使用与变量类型相适应的格式字符串,如有符号数用%d、无符号数用%u,此外还需根据变量所标识存储单元的长度选用适当的修饰符。一般而言,short型用长度修饰符h,long型用长度修饰符l,int型不加。如果不匹配时会出现什么情况呢?这是本次实验需要解决的问题之一。长度修饰符对scanf函数有何影响是本次实验需要解决的另一个问题。

实验步骤:

1.分析下面程序的输出

#include <stdio.h>

void main()

{    

       long i, j, k;

       i = 0x80000001;

       j = 0x80008001;

       k = 0x00008001;

       printf("%ld,%ld,%ld\n", i, j, k);  

       printf("%hd,%hd,%hd\n", i, j, k);

}

long型变量

i

j

k

初始值为

0x80000001

/* 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,22次方=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,22次方=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();中?
最新发布
08-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值