|
楼主 |
发表于 2012-12-6 23:22:38
|
显示全部楼层
本帖最后由 281229961 于 2012-12-6 23:29 编辑
代码如下- void USART1_IRQHandler(void) //串口1中断服务程序
- {
- u8 Res;
- if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
- {
- Res =USART_ReceiveData(USART1);//(USART1->DR); //读取接收到的数据
- if(Res==addr&USART_RX_STA==0) //接收到起始信号
- {
- USART_RX_BUF[USART_RX_STA]=Res;
- USART_RX_STA=1;
- }
- else if (USART_RX_STA!=0)
- {
- USART_RX_BUF[USART_RX_STA]=Res;
- USART_RX_STA++;
- }
- }
- if ( USART_RX_STA>7)
- checkComm0Modbus();
- }
- void readRegisters(void)
- {
- unsigned int regaddr,byteCount,i;
- unsigned int num;
- unsigned int Data;
- regaddr=USART_RX_BUF[3]+(USART_RX_BUF[2]<<8);//要读取的寄存器起始地址
- num=USART_RX_BUF[5]+(USART_RX_BUF[4]<<8);//要读取的寄存器数量
- USART_TX_BUF[0]=addr;
- USART_TX_BUF[1]=0x03;
- USART_TX_BUF[2]=2*num; //字节数=寄存器数量*2
- for(i=0;i<num;i++)
- {
- USART_TX_BUF[3+i*2]=buf[regaddr+i+1]>>8;
- USART_TX_BUF[4+i*2]=buf[regaddr+i+1];
- //addr+1+i: 解释如下
- //由于上位机读写没有0号地址 上位机读写的起始地址为 读写4WB0001对应于下位机的0号地址
- //为了便于上下位机读写地址对应, 所以下位机地址在收发的时候加 1
- // 比如上位机 读写4WB0001->00 16位读写
- // 则下位机 反馈 buf[1] 16位数组
- // 这样的话 读写4WB0001->buf[1] 读写4WB0002->buf[2] 。。。。。
- // (buf[0]就再也用不到了)
- //否则不加 1 的 话 读写4WB0001->buf[0] 读写4WB0002->buf[1] 。。。。。
- //纯属个人习惯!!!
- }
- byteCount=3+2*num;//CRC校验的字节数
- Data = CRCC16(USART_TX_BUF,byteCount);
- USART_TX_BUF[num*2+3]=Data>>8;
- USART_TX_BUF[num*2+4]=Data&0xff;
- Uart_send_n(USART_TX_BUF,byteCount+2);
- // IOWR_ALTERA_AVALON_UART_CONTROL(UART_0_BASE, 0x80);//接收中断使能
- }
- void presetMultipleRegisters(void)//多寄存器设置
- {
- unsigned int regaddr,num,i;
- unsigned int crcData;
- //unsigned int tempData;
- regaddr=USART_RX_BUF[3]+(USART_RX_BUF[2]<<8);
- num=USART_RX_BUF[5]+(USART_RX_BUF[4]<<8);
- for(i=0;i<num;i++)
- {
- buf[regaddr+1+i]=USART_RX_BUF[8+i*2]+(USART_RX_BUF[7+i*2]<<8);
- //addr+1+i: 解释如下
- //由于上位机读写没有0号地址 上位机读写的起始地址为 读写4WB0001对应于下位机的0号地址
- //为了便于上下位机读写地址对应, 所以下位机地址在收发的时候加 1
- // 比如上位机 读写4WB0001->00 16位读写
- // 则下位机 反馈 buf[1] 16位数组
- // 这样的话 读写4WB0001->buf[1] 读写4WB0002->buf[2] 。。。。。
- // (buf[0]就再也用不到了)
- //否则不加 1 的 话 读写4WB0001->buf[0] 读写4WB0002->buf[1] 。。。。。
- //纯属个人习惯!!!
- }
- USART_TX_BUF[0]=addr;
- USART_TX_BUF[1]=0x10;
- USART_TX_BUF[2]=USART_RX_BUF[2];
- USART_TX_BUF[3]=USART_RX_BUF[3];
- USART_TX_BUF[4]=USART_RX_BUF[4];
- USART_TX_BUF[5]=USART_RX_BUF[5];
- crcData = CRCC16(USART_RX_BUF,6);
- USART_TX_BUF[6]=crcData>>8;
- USART_TX_BUF[7]=crcData;
- Uart_send_n(USART_TX_BUF,8);
- // Recover();
- // IOWR_ALTERA_AVALON_UART_CONTROL(UART_0_BASE, 0x80);//接收中断使能
- }
- void checkComm0Modbus(void)
- {
- unsigned int crcData;
- unsigned int tempData;//数据个数
- if(USART_RX_STA > 4)
- {switch(USART_RX_BUF[1])
- {
- case 3://读取保持寄存器(一个或多个)
- if(USART_RX_STA >= 8)
- {//接收完成一组数据
- //应该关闭接收中断
- // IOWR_ALTERA_AVALON_UART_CONTROL(UART_0_BASE, 0x0);//关闭接收中断
- if(USART_RX_BUF[0]==addr) // && checkoutError==0)
- {
- crcData = CRCC16(USART_RX_BUF,6);
- if(crcData == USART_RX_BUF[7]+(USART_RX_BUF[6]<<8))
- {//校验正确
- if(USART_RX_BUF[1] == 3)
- {//读取保持寄存器(一个或多个)
- readRegisters();
- }
- }
- }
- USART_RX_STA = 0;
- // checkoutError = 0;
- } break;
- case 16://设置多个寄存器
- tempData = (USART_RX_BUF[4]<<8) + USART_RX_BUF[5];
- tempData = tempData * 2; //数据个数计算=寄存器数*2+9
- tempData += 9; //数据个数
- if(USART_RX_STA >= tempData)
- { // IOWR_ALTERA_AVALON_UART_CONTROL(UART_0_BASE, 0x0);//关闭接收中断
- if(USART_RX_BUF[0]==addr)
- {
- crcData = CRCC16(USART_RX_BUF,tempData-2);
- if(crcData == (USART_RX_BUF[tempData-2]<<8)+ USART_RX_BUF[tempData-1])
- {
- presetMultipleRegisters();
- }
- }
- USART_RX_STA = 0;
- }
- break;
-
- default:
- break;
- }
- }
- }
复制代码 |
|