[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,但是接收之后就不行了
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
[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]
一周热门 更多>