|
本帖最后由 qaya 于 2018-10-24 09:29 编辑
系统采用485通讯,主机发起询问,子机回复。主机收到子机的回复后调用CRC校验程序检验子机的回复是否正确。主机连接了一块迪文串口屏。
错误现象是快速点击主机的屏幕引发频繁的主从机通讯,就会引起主机死机。DEBUG发现死机时进入了 HardFault_Handler() 的while(1)里。
然后在此while(1)循环设置断点,程序停在此处时在“Call Stack + Locals”对话框右键Show Caller Code,看到进入HardFault_Handler() 调用的是CRC校验程序。看了看校验程序,似乎也没什么问题,很疑惑。
以下是校验程序:
#define POLY 0x1021
unsigned int CRC16(unsigned char *addr, int num, unsigned int crc)
{
int i=0;
for (; num > 0; num--) /* Step through bytes in memory */
{
crc = crc ^ (*addr++ << 8); /* Fetch byte from memory, XOR into CRC top byte*/
for (i = 0; i < 8; i++) /* Prepare to rotate 8 bits */
{
if (crc & 0x8000) /* b15 is set... */
crc = (crc << 1) ^ POLY; /* rotate and XOR with polynomic */
else /* b15 is clear... */
crc <<= 1; /* just rotate */
} /* Loop for 8 bits */
crc &= 0xFFFF; /* Ensure CRC remains 16-bit value */
} /* Loop until num=0 */
return(crc); /* Return updated CRC */
}
/*************************************以下增加程序相关主要部分*********************************************************************/
unsigned char MasterToSlaveReceiveBuff[400];
void SysTick_Handler(void)
{
...
if(SysTick_50ms_1Second==0)//系统嘀嗒设置为50ms一次
{
SysTick_50ms_1Second=20;
SysTick_SecondFlag=1;
}
}
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){
...
if(接收到完整的子机回复){
...
MasterToSlaveReceive_VirtualLength=(MasterToSlaveReceiveBuff[2]<<8)+MasterToSlaveReceiveBuff[3];
MasterToSlaveReceive_ReceiveStatus=MasterToSlaveReceive_ReceiveStatus_Complete;
...
}
...
}
}
void HandShakeAllSlaveScan(void)
{
unsigned int VVre,VVcrc;
switch(HandShakeAllSlaveScanStatus){
case HandShakeAllSlaveScanStatus_Star:
... //主机发起发送
break;
case HandShakeAllSlaveScanStatus_WaitReceive:
//等待从机回应,从机回应则计算校验是否正确
...
VVcrc=CRC16(MasterToSlaveReceiveBuff,MasterToSlaveReceive_VirtualLength+2,0xffff);
VVre=(MasterToSlaveReceiveBuff[MasterToSlaveReceive_VirtualLength+2]<<8)+MasterToSlaveReceiveBuff[MasterToSlaveReceive_VirtualLength+3];
if(VVcrc==VVre) {
//校验正确
...
}else{
//校验错误
...
}
break;
...
}
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//抢占优先级0~1,响应优先级0~7
/* Enable the UART5 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the USART4 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;//响应优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the USART3 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 6;//响应优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the USART2 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the USART1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the TIM2 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
int main(void)
{
...
NVIC_Configuration();
...
while (1)
{
...
if(HandShakeAllSlaveScanStatus!=HandShakeAllSlaveScanStatus_Free){
HandShakeAllSlaveScan();
}
...
if(SysTick_SecondFlag)//1秒间隔
{
...
//发起一次对所有子机的询问
if(HandShakeAllSlaveScanStatus==HandShakeAllSlaveScanStatus_Free){
MasterToSlave_CurrentComSlaveID=1;
HandShakeAllSlaveScanStatus=HandShakeAllSlaveScanStatus_Star;
MasterToSlave_ComCounter=0;
}
...
}
}
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!
|