- 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;”这一行。但是其他几个串口也使用了类似的函数都没有问题,实在找不到问题出在哪里了
而且还不是每次都会出现,可能隔几个小时就会出现一次