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条回答
翱翔云端的鸟
2019-07-26 06:22
无符号16bit读应答函数--功能码03(可以一次性读多个)
[mw_shl_code=c,true]/********************************************************************************
** 功能:MODBUS数据帧16位无符号数读寄存器应答函数
** 参数:u16 index , u16 *p , u16 datanu
** 参数说明:index   起始数组下标
                         *p       数组缓冲区
                         datanum  返回的数据个数
** 说明:
** 发送格式: 01   03     00   00      00  01     84 0A
            从址 功能号 起始地址高低  数量高低    CRC校验低 高
** 响应格式: 01   03     02        00  00         B8 44
                        从址 功能号 数据字节数  数量高低    CRC校验低 高
***************************************************************************************/
void Read_Answer(u16 index,u16 *p,u16 datanum)
{
        u16 crcDataLo,crcDataHi;
        u8 i;
        sendnum = 5+(ReceBuf[4] * 256 + ReceBuf[5])*2;//回发的字节数
        usDataLen = sendnum - 2;
        SendBuf[0] = ReceBuf[0];//设备地址
        SendBuf[1] = ReceBuf[1];//功能号
        SendBuf[2] = sendnum - 5;//返回数据的字节数
        for(i = 3;(i < (2*datanum+3)); i = i+2)
        {
                SendBuf = (*(p+index))/256;//高8位   *(p+i) = MYW_Buf
                SendBuf[i+1] = (*(p+index))%256;//低8位
                index++;
        }
        crcData = crc16(SendBuf,usDataLen);
        crcDataLo = crcData/256; //高
        crcDataHi = crcData%256; //低
        SendBuf[sendnum - 2] = crcDataLo;//CRC校验低
        SendBuf[sendnum - 1] = crcDataHi;//CRC校验高
        for(i = 0;i < sendnum+1;i++)
        {
                USART_SendData(USART1,SendBuf);
                while(!(USART1->SR & USART_FLAG_TXE));//等待发送完成
        }
        sendnum = 0;       
}[/mw_shl_code]


无符号16bit写应答---对应10(可以一次性写多个)
[mw_shl_code=c,true]/**************************************************************************************
** 功能:      Modbus16位无符号数据帧写寄存器应答函数
** 参数:      void
** 返回值:    void
** 说明:      MODBUS数据帧发送响应如下   
** 发送格式: 01   10     00   00      00  01    02     00   0F        E6  54
            从址 功能号 起始地址高低  数量高低 字节数   数据高低    CRC校验低 高
** 响应格式: 01   10     00   00     00    01    01  C9
                        从址 功能号 起始地址高低  数量高低   CRC校验低 高
***************************************************************************************/
void WriteAnswer(void)
{
        u16 crcDataLo,crcDataHi;//CRC低位 和CRC高位
        u8 i;
        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];
        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;
}[/mw_shl_code]


无符号32bit读应答函数
[mw_shl_code=c,true]/********************************************************************************
** 功能:MODBUS数据帧32位无符号数读寄存器应答函数
** 参数:u16 index1 , u32 *p1 , u16 datanum1,
** 参数说明:index1    起始数组下标
                         *p1       数组缓冲区
                         datanum1  返回的数据个数
** 说明:32位DoubleWord的发送接收格式为 低十六位在前,高十六位在后,与16位数据传输不同
                 例如 32位十进制数  542954855  的十六进制位  20 5C D5 67
         实际发送接收位    D5 67 20 5C
********************************************************************************/
void Double_Word_Read_Answer(u16 index1,u32 *p1,u16 datanum1)
{
        u16 crcDataLo,crcDataHi;
        u8 i;
        sendnum = 5+(ReceBuf[4] * 256 + ReceBuf[5])*4;//回发的字节数
        usDataLen = sendnum - 2;
        SendBuf[0] = ReceBuf[0];//设备地址
        SendBuf[1] = ReceBuf[1];//功能号
        SendBuf[2] = sendnum - 5;//返回数据的字节数
        for(i=3;(i < (4*datanum1+3));i = i+4)
        {
                SendBuf = ((*(p1+index1))%65536)/256 ;//A 对65535取模得到低十六位  然后除256得低十六位中的高8位
            SendBuf[i+1] = ((*(p1+index1))%65536)%256;//B
            SendBuf[i+2] = ((*(p1+index1))/65536)/256;//C
            SendBuf[i+3] = ((*(p1+index1))/65536)%256;//D
                index1++;
        }
        crcData = crc16(SendBuf,usDataLen);
        crcDataLo = crcData/256; //高
        crcDataHi = crcData%256; //低
        SendBuf[sendnum - 2] = crcDataLo;//CRC校验低
        SendBuf[sendnum - 1] = crcDataHi;//CRC校验高
        for(i = 0;i < sendnum+1;i++)
        {
                USART_SendData(USART1,SendBuf);
                while(!(USART1->SR & USART_FLAG_TXE));//等待发送完成
        }
        sendnum = 0;
}[/mw_shl_code]

一周热门 更多>