r123h

  • 2024-05-09
  • 回复了主题帖: 程序在运行时进入HardFault_Handler中

    littleshrimp 发表于 2024-5-9 12:48 bufferRec只有30个字节,如果串口接收长度大于30就可能溢出 我将获取串口数据的程序改成了动态分配内存的目前还没有进到HardFault_Handler中,我再测一段时间试试

  • 回复了主题帖: 程序在运行时进入HardFault_Handler中

    同样是对天平操作的代码,读取天平的重量和其他部分的运行,因为数量很多所以采用了递归的方法 void ProcessSamples(int samplePositions[],u16 num,int totalSamples,u32 *Weightbuffer) { if (num >= totalSamples) { return; } ProcessSample(samplePositions[num],Weightbuffer); ProcessSamples(samplePositions, num + 1, totalSamples,Weightbuffer); } void ProcessSample(u16 Samplenum,u32 *Weightbuffer) { if(StartWorkFlag==false) return; SamplefromTurnTable(Samplenum); ArriveBalance(); delay_ms(100); u32 Recordweight=Weightbuffer[Samplenum-1]; while(readBalancebyUart(&Weightbuffer[Samplenum-1])==false) { delay_sec(2); } TaskParabuffer.CurSampleWeight=Weightbuffer[Samplenum-1]; ReturnTurntable(Samplenum); u32 differnum = abs(Weightbuffer[Samplenum-1]-Recordweight); if(differnum<=PCSetTaskPara.Balanceerronum) { Recordweight=0; PCSetTaskPara.bufferTask[Samplenum-1]=0; Weightbuffer[Samplenum-1]=0; } else{ Recordweight=0; } } bool readBalancebyUart(u32 *weight) { float data=0; u8 buffer[3] = {0}; buffer[0]=0x53; buffer[1]=0x0D; buffer[2]=0x0A; for(int i=0;i<3;i++) { while(USART_GetFlagStatus(UART5, USART_FLAG_TC) == RESET){}; USART_SendData(UART5,buffer[i]); } while(USART_GetFlagStatus(UART5, USART_FLAG_TC) == RESET){}; delay_ms(50); u8 bufferRec[30] = {0}; int recLen = 0; getUart5RecData(bufferRec,&recLen); if((bufferRec[0] == 0x53)&&(bufferRec[2] == 0x53)&&(bufferRec[8] == 0x2E)&& recLen == 0x12) { u8 dataAddr[9]= {0}; for(int i = 0;i<9;i++) { dataAddr[i] = bufferRec[5+i]; } data = atof((char*)dataAddr); if(data>150) { return false; } *weight=(u32)floor(data*100000); } else { return false; } return true; } 但是运行到ProcessSample的 while(readBalancebyUart(&Weightbuffer[Samplenum-1])==false)   {         delay_sec(2);   }时程序又进入到HardFault_Handler,然后通过调用堆栈窗口发现在程序运行到   ProcessSample函数的   u32 Recordweight=Weightbuffer[Samplenum-1];之前Samplenum和Weightbuffer的数值和地址是正常的,进入到while(readBalancebyUart(&Weightbuffer[Samplenum-1])==false)   {         delay_sec(2);   }后,Samplenum和Weightbuffer的地址就全不对了,原本Samplenum的值为3变为0x2036,Weightbuffer的地址从0x200043E0变为0x2000430A

  • 2024-05-08
  • 发表了主题帖: 程序在运行时进入HardFault_Handler中

    本帖最后由 r123h 于 2024-5-8 17:56 编辑 stm32f103zet6写了一个通过uart5控制梅特勒托利多的天平的程序。uart5的配置和中断函数如下 void Uart5InitFor485(void) { USART_InitTypeDef USART_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE); USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(UART5, &USART_InitStructure); USART_ITConfig(UART5, USART_IT_RXNE, ENABLE); USART_Cmd(UART5, ENABLE); USART_ClearFlag(UART5,USART_FLAG_TC); } NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USART5_Rx_Buffer.buffer = (u8*)malloc(USART5_RX_BUFFER_SIZE); memset(USART5_Rx_Buffer.buffer,0,USART5_RX_BUFFER_SIZE); USART5_Rx_Buffer.index = 0; USART5_Rx_Buffer.maxSize = USART5_RX_BUFFER_SIZE; void UART5_IRQHandler(void) { u8 res; if(USART_GetFlagStatus(UART5,USART_FLAG_ORE)==SET) { USART_ClearFlag(UART5,USART_FLAG_ORE); //¶ÁSRÆäʵ¾ÍÊÇÇå³ý±êÖ¾ res = USART_ReceiveData(UART5); if(USART5_Rx_Buffer.index < USART5_Rx_Buffer.maxSize) { USART5_Rx_Buffer.buffer[USART5_Rx_Buffer.index] = res; USART5_Rx_Buffer.index ++; } } if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET) { res =USART_ReceiveData(UART5); if(USART5_Rx_Buffer.index < USART5_Rx_Buffer.maxSize) { USART5_Rx_Buffer.buffer[USART5_Rx_Buffer.index] = res; USART5_Rx_Buffer.index ++; } } if(USART_GetITStatus(UART5, USART_FLAG_TC) != RESET) { return ; } } 其中一个对天平进行清零的程序(采用的梅特勒自己的通信协议发送“Z\r\n”,返回“Z A\r\n”为清零任务完成且成功)代码如下 bool ZeroBalancebyUart(void) { u32 buffer[3] = {0}; buffer[0]=0x5A; buffer[1]=0x0D; buffer[2]=0x0A; for(int i=0;i<3;i++) { while(USART_GetFlagStatus(UART5, USART_FLAG_TC) == RESET){}; USART_SendData(UART5,buffer[i]); } while(USART_GetFlagStatus(UART5, USART_FLAG_TC) == RESET){}; delay_ms(50); u8 bufferRec[30] = {0}; int recLen = 0; getUart5RecData(bufferRec,&recLen); if((bufferRec[0] == 0x5A) && (bufferRec[2] == 0x41) && recLen==5) { return true; } else { return false; } } void getUart5RecData(u8 *data,int* len) { *len = USART5_Rx_Buffer.index; memcpy(data,USART5_Rx_Buffer.buffer,USART5_Rx_Buffer.index); USART5_Rx_Buffer.index = 0; memset(USART5_Rx_Buffer.buffer,0,sizeof(USART5_Rx_Buffer.buffer)); } 但是在清零任务的时候程序进入HardFault_Handler,调用堆栈窗口第二行只有0x00000000 寄存器那边R14(LR)=0xFFFFFFFD,所以又去找了PSP,最后定位在了getUart5RecData()函数里面的“ USART5_Rx_Buffer.index = 0;”这一行。但是其他几个串口也使用了类似的函数都没有问题,实在找不到问题出在哪里了 而且还不是每次都会出现,可能隔几个小时就会出现一次

最近访客

现在还没有访客

< 1/0 >

统计信息

已有--人来访过

  • 芯积分:25
  • 好友:--
  • 主题:2
  • 回复:2

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言