找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9508|回复: 9
打印 上一主题 下一主题
收起左侧

STM32F1系列MODBUS RTU主站从站源码

  [复制链接]
跳转到指定楼层
楼主
ID:403544 发表于 2018-10-23 09:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
因为主站,从站分开两个工程,这里只能分开贴不然容易混淆
主站代码这里是用来控制16个灯的  
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)         
USHORT
usMBCRC16( UCHAR * pucFrame, USHORT usLen );  
unsigned char MBRTU_RX_BUFF[100];//读取区
unsigned short int MBRTU_TX_CNT=0;//发送长度
short int *Modbus_InputReg[20];
unsigned char MBRTU_Addr=1;
unsigned char MBRTU_TX_BUFF[100];//传送区
unsigned short int MBRTU_RX_CNT=0;//读取长度
unsigned char MBRTU_FrameFlag=0;
unsigned char Modbus_OutputIO[20];
unsigned char Modbus_InputIO[20];
u16 *Modbus_HoldReg[20];
u16 startRegAddr;
u16 RegNum;
u16 calCRC;
void    RTU_05 (void);

//输出GPIO配置
void Output_Init(void)
{
                GPIO_InitTypeDef GPIO_InitStructure;
        /* GPIOF Periph clock enable */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE); //启用时钟
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;//打开PIN端口
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//模式为推挽或者其他模式在这里配置
        GPIO_InitStructure.GPIO_Speed  = GPIO_Speed_10MHz;//设置频率
        GPIO_Init(GPIOA, &GPIO_InitStructure);//将&GPIO_InitStructure地址赋值给GPIOA,在这里的意思是 打开GPIOA的PIN端口
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_8|GPIO_Pin_10|
                                                                                                                                GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;;//打开PIN端口
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed  = GPIO_Speed_10MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);//将&GPIO_InitStructure地址赋值给GPIOB,在这里的意思是 打开GPIOA的PIN端口
}

void USART1_IRQHandler(void)//串口1中断服务程序
{         
       
        u8 res;

        if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
        {
                res=USART_ReceiveData(USART1); //读接收到的字节,同时相关标志自动清除

                        if((MBRTU_RX_CNT<100))//读取长度小于100则将读取值 取出
                        {
                               
                                        MBRTU_RX_BUFF[MBRTU_RX_CNT]=res;
                                        MBRTU_RX_CNT++;                                       
                                        TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除定时器溢出中断
                                        TIM_SetCounter(TIM3,0);//当接收到一个新的字节,将定时器7复位为0,重新计时(相当于喂狗)
                                        TIM_Cmd(TIM3,ENABLE);//开始计时
                       
                        }
        }
}



void MBRTURun(void)
{
        u16 recCRC;
        if(MBRTU_FrameFlag==1)
        {
                        if(MBRTU_RX_BUFF[0]==MBRTU_Addr && MBRTU_RX_CNT >= 5)
                        {
                                if((MBRTU_RX_BUFF[1]==01)||(MBRTU_RX_BUFF[1]==02)||(MBRTU_RX_BUFF[1]==03)||(MBRTU_RX_BUFF[1]==04)||(MBRTU_RX_BUFF[1]==05)||(MBRTU_RX_BUFF[1]==06)||(MBRTU_RX_BUFF[1]==15)||(MBRTU_RX_BUFF[1]==16))//?????
                                {
                                        startRegAddr=(((u16)MBRTU_RX_BUFF[2])<<8)|MBRTU_RX_BUFF[3];
                                        if(startRegAddr<1000)
                                        {
                                                calCRC=usMBCRC16(MBRTU_RX_BUFF,MBRTU_RX_CNT-2);
                                                recCRC=MBRTU_RX_BUFF[MBRTU_RX_CNT-2]|(((u16)MBRTU_RX_BUFF[MBRTU_RX_CNT-1])<<8);
                                                        if(calCRC==recCRC)
                                                {
                                                        switch(MBRTU_RX_BUFF[1])
                                                        {
                                                                        case 1:
                                                                        {
                                                                                                        Modbus_01_Solve();
                                                                                                        break;
                                                                        }
                                                                        case 2:
                                                                        {
                                                                                                        Modbus_02_Solve();
                                                                                                        break;
                                                                        }                                                                                                                       
                                                                       
                                                                        case 4:
                                                                        {
                                                                                                        Modbus_04_Solve();
                                                                                break;
                                                                        }       
                                                                        case 5:
                                                                        {
                                                                                                        Modbus_05_Solve();
                                                                                                        break;
                                                                        }
                                                                                                       
                                                                        case 15:
                                                                        {
                                                                                                        Modbus_15_Solve();
                                                                                                        break;
                                                                        }
                                                                                                       
                                                                        case 03:
                                                                        {
                                                                                                        Modbus_03_Solve();
                                                                                                        break;
                                                                        }
                                                                                                       
                                                                        case 06:
                                                                        {
                                                                                                        Modbus_06_Solve();
                                                                                                        break;
                                                                        }
                                                                                                       
                                                                        case 16:
                                                                        {
                                                                                                        Modbus_16_Solve();
                                                                                                        break;
                                                                        }
                                               
                                                                }                                               
                                        }                       
                                                }
                                                else
                                                {
                                                                                MBRTU_TX_BUFF[0]=MBRTU_RX_BUFF[0];
                                                                                MBRTU_TX_BUFF[1]=MBRTU_RX_BUFF[1]|0x80;
                                                                                MBRTU_TX_BUFF[2]=0x04; //???
                                                                                //RS485_Send_Data(MBRTU_TX_BUFF,3);
                                                }        
                                }
                                else
                                {
                                        MBRTU_TX_BUFF[0]=MBRTU_RX_BUFF[0];
                                        MBRTU_TX_BUFF[1]=MBRTU_RX_BUFF[1]|0x80;
                                        MBRTU_TX_BUFF[2]=0x02; //???
                                        //RS485_Send_Data(MBRTU_TX_BUFF,3);
                                }                                                
                        }
                        else
                        {
                                MBRTU_TX_BUFF[0]=MBRTU_RX_BUFF[0];
                                MBRTU_TX_BUFF[1]=MBRTU_RX_BUFF[1]|0x80;
                                MBRTU_TX_BUFF[2]=0x01;
                                //RS485_Send_Data(MBRTU_TX_BUFF,3);
                        }
                        MBRTU_FrameFlag=0;
                        MBRTU_RX_CNT=0;
                        RS485_TX_EN=0;  
                }
}  


void Modbus_CoilsRefresh(unsigned char *mbOuputs)
        //关联GPIO端口
{
        //output
        mbOuputs[15] == 0 ? GPIO_SetBits(GPIOA,GPIO_Pin_12):GPIO_ResetBits(GPIOA,GPIO_Pin_12);
        mbOuputs[14] == 0 ? GPIO_SetBits(GPIOA,GPIO_Pin_11):GPIO_ResetBits(GPIOA,GPIO_Pin_11);
        mbOuputs[13] == 0 ? GPIO_SetBits(GPIOA,GPIO_Pin_10) : GPIO_ResetBits(GPIOA,GPIO_Pin_10);
        mbOuputs[12] == 0 ? GPIO_SetBits(GPIOA,GPIO_Pin_9) :GPIO_ResetBits(GPIOA,GPIO_Pin_9);
        mbOuputs[11] == 0 ? GPIO_SetBits(GPIOA,GPIO_Pin_8): GPIO_ResetBits(GPIOA,GPIO_Pin_8);
        mbOuputs[10] == 0 ? GPIO_SetBits(GPIOB,GPIO_Pin_15) : GPIO_ResetBits(GPIOB,GPIO_Pin_15);
        mbOuputs[9] == 0 ? GPIO_SetBits(GPIOB,GPIO_Pin_14) : GPIO_ResetBits(GPIOB,GPIO_Pin_14);
       
  mbOuputs[8] == 0 ? GPIO_SetBits(GPIOB,GPIO_Pin_13) : GPIO_ResetBits(GPIOB,GPIO_Pin_13);
        mbOuputs[7] == 0 ? GPIO_SetBits(GPIOB,GPIO_Pin_12) : GPIO_ResetBits(GPIOB,GPIO_Pin_12);       
        mbOuputs[6] == 0 ? GPIO_SetBits(GPIOB,GPIO_Pin_11):GPIO_ResetBits(GPIOB,GPIO_Pin_11);
        mbOuputs[5] == 0 ? GPIO_SetBits(GPIOB,GPIO_Pin_10) : GPIO_ResetBits(GPIOB,GPIO_Pin_10);
        mbOuputs[4] == 0 ? GPIO_SetBits(GPIOB,GPIO_Pin_2) :GPIO_ResetBits(GPIOB,GPIO_Pin_2);
        mbOuputs[3] == 0 ? GPIO_SetBits(GPIOB,GPIO_Pin_1): GPIO_ResetBits(GPIOB,GPIO_Pin_1);
        mbOuputs[2] == 0 ? GPIO_SetBits(GPIOB,GPIO_Pin_0) : GPIO_ResetBits(GPIOB,GPIO_Pin_0);
        mbOuputs[1] == 0 ? GPIO_SetBits(GPIOA,GPIO_Pin_7) : GPIO_ResetBits(GPIOA,GPIO_Pin_7);
        mbOuputs[0] == 0 ? GPIO_SetBits(GPIOA,GPIO_Pin_6) : GPIO_ResetBits(GPIOA,GPIO_Pin_6);
       
}       


void TIM2_NVIC_Configuration(void)//中断参数配置
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;       
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;       
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;       
NVIC_Init(&NVIC_InitStructure);       
}

void TIM2_Init(void)//时间中断配置
{
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
        NVIC_InitTypeDef NVIC_InitStruct;
       
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
        TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseInitStruct.TIM_Period = 200-1;//300MS
        TIM_TimeBaseInitStruct.TIM_Prescaler = 7200-1;
        TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;         

        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
  TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
        NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
        NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStruct);  
  TIM_Cmd(TIM2, ENABLE);
        TIM2_NVIC_Configuration();
}

void TIM3_NVIC_Configuration(void)//中断参数配置
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;       
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;       
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;       
NVIC_Init(&NVIC_InitStructure);       
}

void TIM3_Init(void)//时间中断配置
{
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
        NVIC_InitTypeDef NVIC_InitStruct;
       
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
        TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseInitStruct.TIM_Period = 320-1;//32MS////////////此数值 用于 STM32主动发送时间  不可随意更改表标准值320
        TIM_TimeBaseInitStruct.TIM_Prescaler = 7200-1;
        TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV2;         

        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);
  TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
        NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;
        NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStruct);  
  TIM_Cmd(TIM3, ENABLE);
        TIM3_NVIC_Configuration();
}

void Modbus_02_Solve(void)
{
        u16 ByteNum;
        u16 i;
        RegNum= (((u16)MBRTU_RX_BUFF[4])<<8)|MBRTU_RX_BUFF[5];
        if((startRegAddr+RegNum)<100)
        {
                MBRTU_TX_BUFF[0]=MBRTU_RX_BUFF[0];
                MBRTU_TX_BUFF[1]=MBRTU_RX_BUFF[1];
                ByteNum=RegNum/8;
                if(RegNum%8) ByteNum+=1;
                MBRTU_TX_BUFF[2]=ByteNum;
                for(i=0;i<RegNum;i++)
                {
                        if(i%8==0) MBRTU_TX_BUFF[3+i/8]=0x00;
                        MBRTU_TX_BUFF[3+i/8]>>=1;
                        MBRTU_TX_BUFF[3+i/8]|=((Modbus_InputIO[startRegAddr+i])<<7)&0x80;
                        if(i==RegNum-1)
                        {
                                if(RegNum%8) MBRTU_TX_BUFF[3+i/8]>>=8-(RegNum%8);
                        }
                }
                calCRC=usMBCRC16(MBRTU_TX_BUFF,ByteNum+3);
                MBRTU_TX_BUFF[ByteNum+3]=calCRC&0xFF;
                MBRTU_TX_BUFF[ByteNum+4]=(calCRC>>8)&0xFF;
                RS485_Send_Data(MBRTU_TX_BUFF,ByteNum+5);
        }
        else
        {
                MBRTU_TX_BUFF[0]=MBRTU_RX_BUFF[0];
                MBRTU_TX_BUFF[1]=MBRTU_RX_BUFF[1]|0x80;
                MBRTU_TX_BUFF[2]=0x02;
               RS485_Send_Data(MBRTU_TX_BUFF,3);
        }
                                                                                                                       
                     
}




void Modbus_01_Solve(void)
{
                u16 ByteNum;
                u16 i;
                RegNum= (((u16)MBRTU_RX_BUFF[4])<<8)|MBRTU_RX_BUFF[5];
                if((startRegAddr+RegNum)<100)
                {
                                MBRTU_TX_BUFF[0]=MBRTU_RX_BUFF[0];
                                MBRTU_TX_BUFF[1]=MBRTU_RX_BUFF[1];
                                ByteNum=RegNum/8;
                                if(RegNum%8) ByteNum+=1;
                                MBRTU_TX_BUFF[2]=ByteNum;
                                for(i=0;i<RegNum;i++)
                                {
                                                                if(i%8==0) MBRTU_TX_BUFF[3+i/8]=0x00;
                                                                MBRTU_TX_BUFF[3+i/8]>>=1;
                                                                MBRTU_TX_BUFF[3+i/8]|=((Modbus_OutputIO[startRegAddr+i])<<7)&0x80;
                                                                if(i==RegNum-1)
                                                                {
                                                                                                if(RegNum%8) MBRTU_TX_BUFF[3+i/8]>>=8-(RegNum%8);
                                                                }
                                }
                                calCRC=usMBCRC16(MBRTU_TX_BUFF,ByteNum+3);
                                MBRTU_TX_BUFF[ByteNum+3]=calCRC&0xFF;
                                MBRTU_TX_BUFF[ByteNum+4]=(calCRC>>8)&0xFF;
                        RS485_Send_Data(MBRTU_TX_BUFF,ByteNum+5);
                }
                else
                {
                                MBRTU_TX_BUFF[0]=MBRTU_RX_BUFF[0];
                                MBRTU_TX_BUFF[1]=MBRTU_RX_BUFF[1]|0x80;
                                MBRTU_TX_BUFF[2]=0x02;
                                RS485_Send_Data(MBRTU_TX_BUFF,3);
                }
}



void Modbus_05_Solve(void)
{
                if(startRegAddr<100)
                {
                                if((MBRTU_RX_BUFF[4]==0xFF)||(MBRTU_RX_BUFF[5]==0xFF)) Modbus_OutputIO[startRegAddr]=0x01;
                                else Modbus_OutputIO[startRegAddr]=0x00;
                               
                                MBRTU_TX_BUFF[0]=MBRTU_RX_BUFF[0];
                                MBRTU_TX_BUFF[1]=MBRTU_RX_BUFF[1];
                                MBRTU_TX_BUFF[2]=MBRTU_RX_BUFF[2];
                                MBRTU_TX_BUFF[3]=MBRTU_RX_BUFF[3];
                                MBRTU_TX_BUFF[4]=MBRTU_RX_BUFF[4];
                                MBRTU_TX_BUFF[5]=MBRTU_RX_BUFF[5];
                               
                                calCRC=usMBCRC16(MBRTU_TX_BUFF,6);
                                MBRTU_TX_BUFF[6]=calCRC&0xFF;
                                MBRTU_TX_BUFF[7]=(calCRC>>8)&0xFF;
                                RS485_Send_Data(MBRTU_TX_BUFF,8);
                }
                else
                {
                                MBRTU_TX_BUFF[0]=MBRTU_RX_BUFF[0];
                                MBRTU_TX_BUFF[1]=MBRTU_RX_BUFF[1]|0x80;
                                MBRTU_TX_BUFF[2]=0x02; //???
                                RS485_Send_Data(MBRTU_TX_BUFF,3);
                }
}


void Modbus_15_Solve(void)
{
        u16 i;
        RegNum=(((u16)MBRTU_RX_BUFF[4])<<8)|MBRTU_RX_BUFF[5];
        if((startRegAddr+RegNum)<100)
        {        
                for(i=0;i<RegNum;i++)
                {
                        if(MBRTU_RX_BUFF[7+i/8]&0x01) Modbus_OutputIO[startRegAddr+i]=0x01;
                        else Modbus_OutputIO[startRegAddr+i]=0x00;
                        MBRTU_RX_BUFF[7+i/8]>>=1;
                }

                MBRTU_TX_BUFF[0]=MBRTU_RX_BUFF[0];
                MBRTU_TX_BUFF[1]=MBRTU_RX_BUFF[1];
                MBRTU_TX_BUFF[2]=MBRTU_RX_BUFF[2];
                MBRTU_TX_BUFF[3]=MBRTU_RX_BUFF[3];
                MBRTU_TX_BUFF[4]=MBRTU_RX_BUFF[4];
                MBRTU_TX_BUFF[5]=MBRTU_RX_BUFF[5];
                calCRC=usMBCRC16(MBRTU_TX_BUFF,6);
                MBRTU_TX_BUFF[6]=calCRC&0xFF;
                MBRTU_TX_BUFF[7]=(calCRC>>8)&0xFF;
                RS485_Send_Data(MBRTU_TX_BUFF,8);
        }
        else
        {
                MBRTU_TX_BUFF[0]=MBRTU_RX_BUFF[0];
                MBRTU_TX_BUFF[1]=MBRTU_RX_BUFF[1]|0x80;
                MBRTU_TX_BUFF[2]=0x02; //???
                RS485_Send_Data(MBRTU_TX_BUFF,3);
        }
}


void Modbus_03_Solve(void)
{
                u8 i;
                RegNum= (((u16)MBRTU_RX_BUFF[4])<<8)|MBRTU_RX_BUFF[5];//???????
                if((startRegAddr+RegNum)<1000)//?????+??????
                {
                                                MBRTU_TX_BUFF[0]=MBRTU_RX_BUFF[0];
                                                MBRTU_TX_BUFF[1]=MBRTU_RX_BUFF[1];
                                                MBRTU_TX_BUFF[2]=RegNum*2;
                                                for(i=0;i<RegNum;i++)
                                                {
                                                                                MBRTU_TX_BUFF[4+i*2]= *Modbus_HoldReg[startRegAddr+i]&0xFF;
                                                                                MBRTU_TX_BUFF[3+i*2]=(*Modbus_HoldReg[startRegAddr+i]>>8)&0xFF;
                                                }
                                                calCRC=usMBCRC16(MBRTU_TX_BUFF,RegNum*2+3);
                                                MBRTU_TX_BUFF[RegNum*2+3]=calCRC&0xFF;
                                                MBRTU_TX_BUFF[RegNum*2+4]=(calCRC>>8)&0xFF;
                                                RS485_Send_Data(MBRTU_TX_BUFF,RegNum*2+5);
                }
                else//?????+??????
                {
                                                MBRTU_TX_BUFF[0]=MBRTU_RX_BUFF[0];
                                                MBRTU_TX_BUFF[1]=MBRTU_RX_BUFF[1]|0x80;
                                                MBRTU_TX_BUFF[2]=0x02; //???
                                                RS485_Send_Data(MBRTU_TX_BUFF,3);
                }
}
void Modbus_04_Solve(void)
{
                u8 i;
                RegNum= (((u16)MBRTU_RX_BUFF[4])<<8)|MBRTU_RX_BUFF[5];//???????
                if((startRegAddr+RegNum)<1000)//?????+??????
                {
                                                MBRTU_TX_BUFF[0]=MBRTU_RX_BUFF[0];
                                                MBRTU_TX_BUFF[1]=MBRTU_RX_BUFF[1];
                                                MBRTU_TX_BUFF[2]=RegNum*2;
                                                for(i=0;i<RegNum;i++)
                                                {
                                                                                MBRTU_TX_BUFF[4+i*2]=*Modbus_InputReg[startRegAddr+i]&0xFF;
                                                                                MBRTU_TX_BUFF[3+i*2]=(*Modbus_InputReg[startRegAddr+i]>>8)&0xFF;
                                                }
                                                calCRC=usMBCRC16(MBRTU_TX_BUFF,RegNum*2+3);
                                                MBRTU_TX_BUFF[RegNum*2+3]=calCRC&0xFF;
                                                MBRTU_TX_BUFF[RegNum*2+4]=(calCRC>>8)&0xFF;
                                                RS485_Send_Data(MBRTU_TX_BUFF,RegNum*2+5);
                }
                else
                {
                                                MBRTU_TX_BUFF[0]=MBRTU_RX_BUFF[0];
                                                MBRTU_TX_BUFF[1]=MBRTU_RX_BUFF[1]|0x80;
                                                MBRTU_TX_BUFF[2]=0x02; //???
                                                RS485_Send_Data(MBRTU_TX_BUFF,3);
                }
}

void Modbus_06_Solve(void)
{
        *Modbus_HoldReg[startRegAddr]=MBRTU_RX_BUFF[5];//?????
        *Modbus_HoldReg[startRegAddr]|=((u16)MBRTU_RX_BUFF[4])<<8;//?????

        MBRTU_TX_BUFF[0]=MBRTU_RX_BUFF[0];
        MBRTU_TX_BUFF[1]=MBRTU_RX_BUFF[1];
        MBRTU_TX_BUFF[2]=MBRTU_RX_BUFF[2];
        MBRTU_TX_BUFF[3]=MBRTU_RX_BUFF[3];
        MBRTU_TX_BUFF[4]=MBRTU_RX_BUFF[4];
        MBRTU_TX_BUFF[5]=MBRTU_RX_BUFF[5];

        calCRC=usMBCRC16(MBRTU_TX_BUFF,6);
        MBRTU_TX_BUFF[6]=calCRC&0xFF;
        MBRTU_TX_BUFF[7]=(calCRC>>8)&0xFF;
        RS485_Send_Data(MBRTU_TX_BUFF,8);
}


void Modbus_16_Solve(void)
{
        u8 i;
        RegNum= (((u16)MBRTU_RX_BUFF[4])<<8)|MBRTU_RX_BUFF[5];//???????
        if((startRegAddr+RegNum)<1000)//?????+??????
        {
                for(i=0;i<RegNum;i++)
                {
                        *Modbus_HoldReg[startRegAddr+i]=MBRTU_RX_BUFF[7+i*2]; //?????
                        *Modbus_HoldReg[startRegAddr+i]|=((u16)MBRTU_RX_BUFF[8+i*2])<<8; //?????
                }

                MBRTU_TX_BUFF[0]=MBRTU_RX_BUFF[0];
                MBRTU_TX_BUFF[1]=MBRTU_RX_BUFF[1];
                MBRTU_TX_BUFF[2]=MBRTU_RX_BUFF[2];
                MBRTU_TX_BUFF[3]=MBRTU_RX_BUFF[3];
                MBRTU_TX_BUFF[4]=MBRTU_RX_BUFF[4];
                MBRTU_TX_BUFF[5]=MBRTU_RX_BUFF[5];

                calCRC=usMBCRC16(MBRTU_TX_BUFF,6);
                MBRTU_TX_BUFF[6]=calCRC&0xFF;
                MBRTU_TX_BUFF[7]=(calCRC>>8)&0xFF;
                RS485_Send_Data(MBRTU_TX_BUFF,8);
        }
        else
        {
                MBRTU_TX_BUFF[0]=MBRTU_RX_BUFF[0];
                MBRTU_TX_BUFF[1]=MBRTU_RX_BUFF[1]|0x80;
                MBRTU_TX_BUFF[2]=0x02; //???
                RS485_Send_Data(MBRTU_TX_BUFF,3);
        }
}




void TIM3_IRQHandler(void)////定时3中断启用
{      
        if(TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)
  {               
          RTU_05 (); //主站主动发送函数
                TIM_ClearITPendingBit(TIM3, TIM_IT_Update);               
                MBRTU_FrameFlag=1;//定时中断启用RTU中间量
        }
}
u8 RS485_TX_BUFF[12];//发送缓冲区
char set[11]={01,15,00,00,00,16,02,00,00,00,00};//存放15个灯代码
u16 shuzuB[16];//用来存放计算出的15个值
u16 c,x[16];
char A[8]={1,0,0,1,1,1,1,1};//低位16-24
char B[8]={0,0,1,1,1,1,1,1};//高位25-31  前八个

void RTU_05 (void)//主站主动发送函数       
{                
          
        //if(A[0]==1||A[01]==1||A[2]==1||A[3]==1||A[4]==1||A[5]==1||A[6]==1||A[7]==01)
       
        {               
                        shuzuB[15] = A[7]*128; //0000  0001   01  1
                  shuzuB[14] = A[6]*64; //0000  0010                02        2      7-----------0
                        shuzuB[13] = A[5]*32; //0000  0100                04        3
                        shuzuB[12] = A[4]*16; //0000  1000                08         4               
                        shuzuB[11] = A[3]*8;  //0001  0000                10        5
                        shuzuB[10] = A[2]*4;  //0010  0000                20        6
                        shuzuB[9]  = A[1]*2;   //0100  0000                40        7       
                        shuzuB[8]  = A[0] *1;  //1000  0000                80        8       
           set[7] = shuzuB[8]+shuzuB[9]+shuzuB[10]+shuzuB[11]+shuzuB[12]+shuzuB[13]+shuzuB[14]+shuzuB[15];
        }
//if(B[0]==1||B[01]==1||B[2]==1||B[3]==1||B[4]==1||B[5]==1||B[6]==1||B[7]==01)
        {
                        shuzuB[7] = B[7]*128;  //0000  0001   01  1
                  shuzuB[6] = B[6]*64;  //0000  0010                02        2
                        shuzuB[5] = B[5]*32;  //0000  0100                04        3
                        shuzuB[4] = B[4]*16;  //0000  1000                08         4    低位  7------------0               
                        shuzuB[3] = B[3]*8;   //0001  0000                10        5
                        shuzuB[2] = B[2]*4;   //0010  0000                20        6
                        shuzuB[1] = B[1]*2;   //0100  0000                40        7       
                        shuzuB[0] = B[0]*1;   //1000  0000                80        8                               
                        set[8] =shuzuB[0]+shuzuB[1]+shuzuB[2]+shuzuB[3]+shuzuB[4]+shuzuB[5]+shuzuB[6]+shuzuB[7];                          
        }
                                RS485_TX_BUFF[0]=set[0];
        RS485_TX_BUFF[1]=set[1];
        RS485_TX_BUFF[2]=set[2];
        RS485_TX_BUFF[3]=set[3];
        RS485_TX_BUFF[4]=set[4];
                                RS485_TX_BUFF[5]=set[5];
        RS485_TX_BUFF[6]=set[6];
                                RS485_TX_BUFF[7]= set[7];//
        RS485_TX_BUFF[8]= set[8];    //  
                                calCRC=usMBCRC16(RS485_TX_BUFF,9);
                                RS485_TX_BUFF[9]=calCRC&0xFF;
                                RS485_TX_BUFF[10]=(calCRC>>8)&0xFF;
                                RS485_Send_Data(RS485_TX_BUFF,11);
}
void view32(void)
        {
        view[15] == 0 ? GPIO_SetBits(GPIOA,GPIO_Pin_12):GPIO_ResetBits(GPIOA,GPIO_Pin_12);
        view[14] == 0 ? GPIO_SetBits(GPIOA,GPIO_Pin_11):GPIO_ResetBits(GPIOA,GPIO_Pin_11);
        view[13] == 0 ? GPIO_SetBits(GPIOA,GPIO_Pin_10) : GPIO_ResetBits(GPIOA,GPIO_Pin_10);
        view[12] == 0 ? GPIO_SetBits(GPIOA,GPIO_Pin_9) :GPIO_ResetBits(GPIOA,GPIO_Pin_9);
        view[11] == 0 ? GPIO_SetBits(GPIOA,GPIO_Pin_8): GPIO_ResetBits(GPIOA,GPIO_Pin_8);
        view[10] == 0 ? GPIO_SetBits(GPIOB,GPIO_Pin_15) : GPIO_ResetBits(GPIOB,GPIO_Pin_15);
        view[9] == 0 ? GPIO_SetBits(GPIOB,GPIO_Pin_14) : GPIO_ResetBits(GPIOB,GPIO_Pin_14);
       
  view[8] == 0 ? GPIO_SetBits(GPIOB,GPIO_Pin_13) : GPIO_ResetBits(GPIOB,GPIO_Pin_13);
        view[7] == 0 ? GPIO_SetBits(GPIOB,GPIO_Pin_12) : GPIO_ResetBits(GPIOB,GPIO_Pin_12);       
        view[6] == 0 ? GPIO_SetBits(GPIOB,GPIO_Pin_11):GPIO_ResetBits(GPIOB,GPIO_Pin_11);
        view[5] == 0 ? GPIO_SetBits(GPIOB,GPIO_Pin_10) : GPIO_ResetBits(GPIOB,GPIO_Pin_10);
        view[4] == 0 ? GPIO_SetBits(GPIOB,GPIO_Pin_2) :GPIO_ResetBits(GPIOB,GPIO_Pin_2);
        view[3] == 0 ? GPIO_SetBits(GPIOB,GPIO_Pin_1): GPIO_ResetBits(GPIOB,GPIO_Pin_1);
        view[2] == 0 ? GPIO_SetBits(GPIOB,GPIO_Pin_0) : GPIO_ResetBits(GPIOB,GPIO_Pin_0);
        view[1] == 0 ? GPIO_SetBits(GPIOA,GPIO_Pin_7) : GPIO_ResetBits(GPIOA,GPIO_Pin_7);
        view[0] == 0 ? GPIO_SetBits(GPIOA,GPIO_Pin_6) : GPIO_ResetBits(GPIOA,GPIO_Pin_6);
       
        }
//////////////////////////////////////////////////////////////////////////////////         
/*RS485驱动 代码*/
//////////////////////////////////////////////////////////////////////////////////

//485初始化
  void RS485_Config(u32 bound)
{
                 USART_InitTypeDef usart;
        GPIO_InitTypeDef usart1;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//启用时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);

        GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);
        usart1.GPIO_Pin=GPIO_Pin_6;                           //PB6端口配置TX
        usart1.GPIO_Speed=GPIO_Speed_50MHz;
        usart1.GPIO_Mode=GPIO_Mode_AF_PP;
        GPIO_Init(GPIOB, &usart1);

        usart1.GPIO_Pin=GPIO_Pin_7;
        usart1.GPIO_Speed=GPIO_Speed_50MHz;//PB7//PB7端口配置RX
        usart1.GPIO_Mode=GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOB, &usart1);

        usart.USART_BaudRate= bound;                                 //波特率
        usart.USART_WordLength=USART_WordLength_8b;//8位数据长度设置
        usart.USART_StopBits = USART_StopBits_1;//一位停止位
        usart.USART_Parity =USART_Parity_No;//校验位
        usart.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//无硬件数据流
        usart.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//收发模式
       
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;               //选择串口1中断
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //响应式中断优先级设置为2级
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;//先占优先级为2级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         
        NVIC_Init(&NVIC_InitStructure);//根据NVICInitStructure制定参数初始化NVIC寄存器

        USART_Init(USART1, &usart);//初始化串口
        USART_Cmd(USART1, ENABLE);//使能串口
        USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);        // //开启中断
        RS485_TX_EN=0;//默认为接收模式
       
}
//发送n个字节数据
//buff:发送区首地址
//len:发送的字节数
void  RS485_Send_Data(u8 *buf,u8 len) //modbus发送数据函数
{
          RS485_TX_EN=1;//切换为发送模式
                while(len--)
                {
                        while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//等待发送区为空
                        USART_SendData(USART1,*(buf++));
                        while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);                                       
                        //等待发送完成     
                }
                  RS485_TX_EN=0;//切换为接收模式
}
static const UCHAR aucCRCHi[] = {
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40
};

static const UCHAR aucCRCLo[] = {
    0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
    0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
    0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
    0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
    0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
    0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
    0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
    0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
    0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
    0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
    0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
    0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
    0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
    0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
    0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
    0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
    0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
    0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
    0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
    0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
    0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
    0x41, 0x81, 0x80, 0x40
};


USHORT
usMBCRC16( UCHAR * pucFrame, USHORT usLen )
{
    UCHAR           ucCRCHi = 0xFF;
    UCHAR           ucCRCLo = 0xFF;
    int             iIndex;

    while( usLen-- )
    {
        iIndex = ucCRCLo ^ *( pucFrame++ );
        ucCRCLo = ( UCHAR )( ucCRCHi ^ aucCRCHi[iIndex] );
        ucCRCHi = aucCRCLo[iIndex];
    }
    return ( USHORT )( ucCRCHi << 8 | ucCRCLo );
}










分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1 发表于 2018-10-23 15:55 | 只看该作者
楼主能分享下工程包吗?
回复

使用道具 举报

板凳
ID:403544 发表于 2018-10-24 09:47 | 只看该作者
admin 发表于 2018-10-23 15:55
楼主能分享下工程包吗?

我找了半天没有找到添加的地方我再看看
回复

使用道具 举报

地板
ID:188720 发表于 2018-10-24 10:54 | 只看该作者
请问有没有51单片机做主站的代码?
回复

使用道具 举报

5#
ID:403544 发表于 2018-10-24 16:34 | 只看该作者
红烧鱼头 发表于 2018-10-24 10:54
请问有没有51单片机做主站的代码?

有的 第一段就是主站  我这里有主站和从站的都可以直接用
回复

使用道具 举报

6#
ID:245836 发表于 2018-11-16 15:03 | 只看该作者
好,收藏了
回复

使用道具 举报

7#
ID:413674 发表于 2019-1-17 09:24 | 只看该作者
楼主有stm32的从站modbus协议吗,发我一份看看,谢谢!邮箱:591166140@qq.com
回复

使用道具 举报

8#
ID:448641 发表于 2019-1-24 10:58 | 只看该作者
没有下载地址
回复

使用道具 举报

9#
ID:719420 发表于 2020-3-31 11:56 | 只看该作者
楼主,你好,可以分享这个工程吗?
回复

使用道具 举报

10#
ID:111310 发表于 2021-8-27 01:06 | 只看该作者
有工程包最好
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表