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