查看: 815|回复: 0
打印 上一主题 下一主题

MODBUS程序,希望大家指正优点是着重

[复制链接]
跳转到指定楼层
沙发
发表于 2016-5-19 21:48:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
点击此处打开电路图ourdev_200557.pdf(文件大小:43K)

M64,14.7456M晶振
定时器中断时间为1s,如果发送间隔大于T1.5但小于T3.5的数据丢弃
与其他前辈的区别就是着重在时间上,其他的关于数据结构协议上的程序,参考论坛上的其他前辈的程序
如果参考其他前辈的程序冒犯了,请告之,我就删除

另外如果AMORK 和其他前辈同意并且确实有价值的话,我就将论坛上相关的整理成一个完整的程序给大家测试



SIGNAL(SIG_UART0_RECV)
{
        Com0_Receive_Data_Buffer[Com0_Receive_Cout]=UDR0;
        if(Com0_Receive_Cout<18)           Com0_Receive_Cout++;
    Uart_Fin = 5;
        Rcvflag = 2;
        Uart_Start = 1;
}
SIGNAL (SIG_UART0_TRANS)
{
         Com0_Send_Data_Pointer++;
        Com0_Send_Data_Bytes--;
        if(Com0_Send_Data_Bytes>0)
      UDR0=*Com0_Send_Data_Pointer;
        else
        UCSR0B|=( 1<<RXEN0 );
}
INTERRUPT(SIG_OVERFLOW0)
{
          TCNT0 = 240; //reload counter value
        flag1ms = 1;
}
void timeProc(void)
{
        wdt_reset();
        if(flag1ms == 1)
        {
                flag1ms = 0;
                if(Uart_Start == 1)//串口开始接收数据
                {
                        if(Rcvflag>0) Rcvflag--;//1.5T的变量
                        if(Uart_Fin>0) Uart_Fin--;3.5T的变量
                        if(Rcvflag == 0)//&Icirc;&acute;&frac12;á&Ecirc;&oslash;&para;&ordf;&AElig;ú//1.5T的时间到了,记录长度
                        {
                                Com0_Receive_Cout15 = Com0_Receive_Cout;
                        }
                        if((Uart_Fin == 0)&&(Uart_Send==0))//&frac12;á&Ecirc;&oslash;//3.5T的时间到
                        {
                                if(Com0_Receive_Data_Buffer[0]==Com0_Send_Data_Buffer[0])/////
                                {
                                        if(Com0_Receive_Cout15 == Com0_Receive_Cout)//判断接收的过程中有没有超过T1.5
                                        {
                                                Uart_End = 5;
                                                Uart_Send = 1;
                                        }        
                                        else
                                        {
                                                Com0_Receive_Cout = 0;
                                        }
                                }
                                else
                                {
                                        Com0_Receive_Cout = 0;
                                        Uart_Start =0;
                                }
                        }
                        if(Uart_End > 0)//一桢数据结束,延长>T3.5发送
                        {
                                Uart_End--;
                                if(Uart_End == 0)
                                {
                                        Com0_Receive_CRCcouter=Com0_Receive_Cout;
                                        Com0_Receive_Cout = 0;
                                        Com0_Communication( ) ;//该部分可参考论坛上的相关程序
                                        Uart_Start =0;
                                        Uart_Send = 0;
                                }
                        }
                }
        }
}
void main (void)
{
        unsigned char Sumad,kk;
        cli();
        initTimer();
        sei();
        while(1)
        {
                timeProc();
                                       
        }
}
void initTimer(void)
{
        TCCR0 = 0x00; //stop
        TCNT0 = 240; //set count
        TIMSK |=0X01;
        TCCR0 = 0x07; //start timer

}
void Com0_Communication(void)
{
        unsigned short crcresult;
        unsigned char   temp[2];
        crcresult= getCRC16(Com0_Receive_Data_Buffer,Com0_Receive_CRCcouter-2);
        temp[1]=crcresult & 0xff;
        temp[0]=(crcresult >> 8) & 0xff;
        if((Com0_Receive_Data_Buffer[Com0_Receive_CRCcouter-1]==temp[0])&&(Com0_Receive_Data_Buffer[Com0_Receive_CRCcouter-2]==temp[1]))
        {
        PORTB^=0x20;
                switch(Com0_Receive_Data_Buffer[1])
        {
            case 0x01:
                                                Modbus_Function_1();
                                                break;  
            case 0x03:
                        Modbus_Function_3();
                        break;  
            case 0x05:
                        Modbus_Function_5();
                        break;            
            case 0x02:
                        Modbus_Function_2();
                        break;
                        case 0x10:
                                                Modbus_Function_16();
                                                break;      
            default:
                                        {
                                                Com0_Send_Data_Buffer[1]=0xFF;
                                                Com0_Send_Data_Buffer[2]=2;
                                                Com0_Send_Data_Bytes=5;
                                                Com0_Send_Data_Buffer[3]=0x00;
                                                Com0_Send_Data_Buffer[4]=0x06;
                    }
        }
    }
    else
    {
        ////show   error!
        Com0_Send_Data_Buffer[1]=0xFF;
        Com0_Send_Data_Buffer[2]=2;
        Com0_Send_Data_Bytes=5;
        Com0_Send_Data_Buffer[3]=0x00;
        Com0_Send_Data_Buffer[4]=0x07;  
    }
   crcresult= getCRC16(Com0_Send_Data_Buffer,Com0_Send_Data_Bytes);
   Com0_Send_Data_Buffer[Com0_Send_Data_Bytes]=crcresult & 0xff;
   Com0_Send_Data_Buffer[Com0_Send_Data_Bytes+1]=(crcresult >> 8) & 0xff;
   Com0_Send_Data_Bytes=Com0_Send_Data_Bytes+2;
   Com0_Send_Data_Pointer=Com0_Send_Data_Buffer;
   UDR0=*Com0_Send_Data_Pointer;
}

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

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