STM32 跟触摸屏modbus-rtu通信问题(485)

2019-07-20 12:27发布

[mw_shl_code=c,true]void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)//判断是否发生TIM2更新中断 { TIM_Cmd(TIM2,DISABLE); //关掉定时器2 TIM_SetCounter(TIM2, 0);//重新设初值0 if(recenum >= 8) { Uart1_rev_flag = 1;//接收完毕一帧,置位标志位,通知主函数调用接收处理函数 USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);//失能串口1接收中断 } recenum = 0; GPIO_SetBits(GPIOF,GPIO_Pin_13);//485发送使能 TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//清除TIM2的中断待处理位 TIM_ClearFlag(TIM2, TIM_FLAG_Update);//清除TIM2待处理标志位 } } void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)//接收中断 { USART_ClearITPendingBit(USART1,USART_IT_RXNE);//清除USART1中断待处理位RXNE(RXNE=0) if(Uart1_rev_flag != 1) { if(recenum < 12)//接收分8字节数据 和11字节数据 { ReceBuf[recenum] = USART1->DR; recenum++; TIM_Cmd(TIM2, ENABLE); TIM_SetCounter(TIM2, 0); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); } } } /*if(USART_GetITStatus(USART1,USART_IT_TXE)!=RESET) { USART_ClearITPendingBit(USART1,USART_IT_TXE);//清除USART1中断待处理位RXNE(RXNE=0) USART_SendData(USART1,ReceBuf[sendnum]); sendnum++; if(sendnum == 8) { LED4(ON); sendnum = 0; USART_ITConfig(USART1,USART_IT_TXE,DISABLE); //USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//打开接收中断使能 //GPIO_ResetBits(GPIOF,GPIO_Pin_13);//485使能接收 } }*/ //溢出-如果发生溢出需要先清空SR的溢出位,再读DR寄存器 则可清除不断入中断的问题 if(USART_GetFlagStatus(USART1,USART_FLAG_ORE)!=RESET) { USART_ClearFlag(USART1,USART_FLAG_ORE); //清溢出位 USART_ReceiveData(USART1); //读DR } }[/mw_shl_code] 这是我中断函数,为什么我接收到的第一个数据不是设备地址0x01,但是我用串口监控,看到的是01 03 00 00 00 01 84 0A,但是接收之后就不行了
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
49条回答
chenyh85
1楼-- · 2019-07-24 01:21
 精彩回答 2  元偷偷看……
心染红尘
2楼-- · 2019-07-24 04:35
 精彩回答 2  元偷偷看……
翱翔云端的鸟
3楼-- · 2019-07-24 06:25
回复【33楼】心染红尘:
---------------------------------
对,收到一帧后会进中断,在中断中将一个标志置1,然后在main函数的while循环里  不停的读这个标志,只要标志为1,就对这帧数据进行解析 得到数据  然后在还原继续接收
心染红尘
4楼-- · 2019-07-24 09:02
[mw_shl_code=c,true]void ParseRecieve(void) //数据帧解析 { u8 crcDataHi; u8 crcDataLo; if(ReceBuf[0] == 0x01) //设备地址是否匹配 { crcData = crc16(ReceBuf,usDataLen);//从接收到的数据帧中获取CRC crcDataLo = crcData/256; // 132 84 crc低 crcDataHi = crcData%256; // 10 0A crc高 if(usDataLen == 6) { if((crcDataHi == ReceBuf[7])&&(crcDataLo == ReceBuf[6]) )//校验 { if(ReceBuf[1] == 0x03)//功能号0x03 { start_addr = ReceBuf[3] | (ReceBuf[2] << 8); if(ReceBuf[5] == 0x30)//掉电保存按钮 { /*---------------------------------------------------------------------*/ if(usDataLen == 9) //功能号0x10 { if((crcDataHi == ReceBuf[10])&&(crcDataLo == ReceBuf[9])) { if(ReceBuf[1] == 0x10) { switch(start_addr) //判断寄存器起始地址 { case 0x0000://从第一个数值输入窗口开始 sendnum = 8;//回发的字节数 usDataLen = sendnum - 2; SendBuf[0] = ReceBuf[0];//设备地址 SendBuf[1] = ReceBuf[1];//功能号 SendBuf[2] = ReceBuf[2];//返回数据的字节数 SendBuf[3] = ReceBuf[3]; SendBuf[4] = ReceBuf[4]; SendBuf[5] = ReceBuf[5]; /*for(count = 3;ReceBuf[5] > 0;ReceBuf[5]--) { SendBuf[count] = XBuf[count - 3]/256;//回发数据高8位 SendBuf[count+1] = XBuf[count - 3]%256;//回发数据低8位 count = count + 2; }*/ crcData = crc16(SendBuf,usDataLen); crcDataLo = crcData/256; //低 crcDataHi = crcData%256; //高 SendBuf[sendnum - 2] = crcDataLo;//CRC低位F8 SendBuf[sendnum - 1] = crcDataHi;//CRC高位40 for(i = 0;i < 9;i++) { USART_SendData(USART1,SendBuf); while(!(USART1->SR & USART_FLAG_TXE));//等待发送完成 } sendnum = 0; break; } } } } } } } } } }[/mw_shl_code] [mw_shl_code=c,true][/mw_shl_code] [mw_shl_code=c,true]楼主,crcData = crc16(ReceBuf,usDataLen); 这个函数的usDataLen值在哪赋给的 [/mw_shl_code]
翱翔云端的鸟
5楼-- · 2019-07-24 11:51
 精彩回答 2  元偷偷看……
458081109
6楼-- · 2019-07-24 16:28
 精彩回答 2  元偷偷看……

一周热门 更多>