اطلاعیه

Collapse
No announcement yet.

ارتباط 2 میکرو با RS485

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    ارتباط 2 میکرو با RS485

    سلام دوستان
    من می خوام بین 2 میکرو با RS485 ارتباط برقرار کنم . روش کار به اینصورت هست که باید هر دو میکرو هر لحظه که data واسشون ارسال شد دریافت کنن به این معنی که وقتی میکرو کار دیگه ای انجام می ده اگه data برایش ارسال شد دریافت کند . هر 2 میکرو این قابلیتو باید داشته باشند. خودم برنامه نوشتم که با interrupt هست و اولی master و دومی slave هست ولی عددها که بزگ میشن نمی فرسته و یا وقتی برنامه MASTER را تو برنامه اصلی اضافه می کنم مشکل پیدا می کنه. می می خوام 400 تا عدد integer رو از master به slave بفرستم و برعکس.ممنون میشم اگه کسی راهنماییم کنه یا یک برنامه ساده واسم بزاره .برنامه خودمم گذاشتم

    برنامه master
    #include <mega32.h>
    #include <stdio.h>
    #include <delay.h>


    #define RXB8 1
    #define TXB8 0
    #define UPE 2
    #define OVR 3
    #define FE 4
    #define UDRE 5
    #define RXC 7

    #define FRAMING_ERROR (1<<FE)
    #define PARITY_ERROR (1<<UPE)
    #define DATA_OVERRUN (1<<OVR)
    #define DATA_REGISTER_EMPTY (1<<UDRE)
    #define RX_COMPLETE (1<<RXC)

    #define RT PORTB.0
    #define TRUE 1
    #define FALSE 0

    #define XTAL 11059200


    void USART_Master_Init(unsigned int baud,char u2x);
    void USART_Master_Receive(unsigned char *data);
    void USART_Master_Send(unsigned char *data,unsigned char address);

    char Error,Msg_Rec;
    char buffer[20],receive_buf[20];
    unsigned int cou;
    int send_buf[20];

    //-----------------------------------------
    // USART Receiver interrupt service routine
    interrupt [USART_RXC] void usart_rx_isr(void)
    {
    USART_Master_Receive(receive_buf);
    }
    //-----------------------------------------
    void main(){
    unsigned int i;
    DDRB=0x01;
    RT=0;
    Msg_Rec=FALSE;
    Error=FALSE;
    USART_Master_Init(115200,1);
    for(i=0;i<20;i++)
    send_buf[i]=20000+2*i;
    #asm("sei&quot
    while (1)
    {

    USART_Master_Send(send_buf,45);
    //USART_Master_Send(send_buf,42);
    if (Msg_Rec) {
    Msg_Rec=FALSE;
    for (i = 2; i <= receive_buf[1]+1;i++){

    sprintf(buffer,"data=%c",receive_buf[i]);

    delay_ms(300);
    }
    delay_ms(1);
    USART_Master_Send(send_buf,receive_buf[0]);
    }
    };
    }
    //------------------------
    void USART_Master_Init(unsigned int baud,char u2x)
    {
    unsigned int BudeRate;
    // USART initialization
    // Communication Parameters: 8 Data, 1 Stop, No Parity
    // USART Receiver: On
    // USART Transmitter: On
    // USART Mode: Asynchronous
    UCSRA=0x00;
    UCSRB=0x9C;
    UCSRC=0x86;
    if(u2x)
    BudeRate = XTAL / 8 / baud - 1;
    else
    BudeRate = XTAL / 16 / baud - 1;
    UBRRH = (unsigned char)(BudeRate >> 8);
    UBRRL = (unsigned char)BudeRate;

    }
    //---------------------------
    void USART_Master_Send(unsigned char *data, unsigned char address)
    {
    unsigned char i;
    RT=1;
    while(!(UCSRA & (1<<UDRE)));
    UCSRB |= (1 << TXB8);
    UDR=address;
    for(i=0;i <= data[0];i++)
    {
    while(!(UCSRA & (1<<UDRE)));
    UCSRB &= ~(1 << TXB8);
    UDR=data[i];
    }
    RT=0;
    }
    //------------------------
    void USART_Master_Receive(unsigned char *data)
    {
    unsigned char input,status;
    status=UCSRA;
    if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
    {
    Error=FALSE;
    input=UDR;
    data[cou] = input;
    if(cou++==data[1]+1)
    {
    Msg_Rec=TRUE;
    cou=0;
    }

    }
    else Error=TRUE;
    }



    برنامه slave

    #include <mega32.h>
    #include <stdio.h>
    #include <delay.h>
    #asm
    .equ __lcd_port=0x18 ;PORTB
    #endasm
    #include <lcd.h>

    #define RXB8 1
    #define TXB8 0
    #define UPE 2
    #define OVR 3
    #define FE 4
    #define UDRE 5
    #define RXC 7

    #define FRAMING_ERROR (1<<FE)
    #define PARITY_ERROR (1<<UPE)
    #define DATA_OVERRUN (1<<OVR)
    #define DATA_REGISTER_EMPTY (1<<UDRE)
    #define RX_COMPLETE (1<<RXC)

    #define RT PORTD.2
    #define Slave_Address 45
    #define XTAL 11059200

    #define TRUE 1
    #define FALSE 0
    char chek;
    char buffer[20];//,receive_buf[20],send_buf[20]={5,'S','l','a',&#03 9;v','e'};
    int receive_buf[20],send_buf[20];
    char Error,Msg_Rec;
    unsigned int cou;

    void USART_slave_Init(unsigned int baud,char u2x);
    void USART_Slave_Receive(unsigned char *data);
    void USART_Slave_Send(unsigned char *data);


    //-------------------------------------
    // USART Receiver interrupt service routine
    interrupt [USART_RXC] void usart_rx_isr(void)
    {
    USART_Slave_Receive(receive_buf);
    }
    //----------------------------------------
    void main(){
    unsigned int i,len;
    DDRD=0x04;
    RT=0;
    lcd_init(16);
    lcd_clear();
    USART_slave_Init(115200,1);
    Msg_Rec=FALSE;
    Error=FALSE;
    send_buf[0]=16;
    send_buf[1]=255;
    #asm("sei&quot
    while (1){

    if (Msg_Rec) {
    Msg_Rec=FALSE;
    len=receive_buf[0];
    for (i = 1; i <= len;i++){
    lcd_clear();
    sprintf(buffer,"data=%d",receive_buf[i]);
    lcd_puts(buffer);
    delay_ms(300);
    }
    delay_ms(1);
    USART_Slave_Send(send_buf);
    }
    if(receive_buf[19]==255)
    {
    USART_Slave_Send(send_buf);
    break;
    }
    };
    }
    //------------------------
    void USART_slave_Init(unsigned int baud,char u2x)
    {
    unsigned int BudeRate;
    // USART initialization
    // Communication Parameters: 8 Data, 1 Stop, No Parity
    // USART Receiver: On
    // USART Transmitter: On
    // USART Mode: Asynchronous
    UCSRA=0x01; // Bit MPCM=1
    UCSRB=0x9c;
    UCSRC=0x86;
    if(u2x)
    BudeRate = XTAL / 8 / baud - 1;
    else
    BudeRate = XTAL / 16 / baud - 1;

    UBRRH = (unsigned char)(BudeRate >> 8);
    UBRRL = (unsigned char)BudeRate;

    }
    //------------------------
    void USART_Slave_Receive(unsigned char *data)
    {
    unsigned char input,status;
    chek=1;
    status=UCSRA;
    if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0){
    Error=FALSE;
    input=UDR;
    if(UCSRA & 0x01){
    if(input == Slave_Address){
    UCSRA &= 0xFE; // Bit MPCM=0
    cou=0;
    }
    }else{

    data[cou] = input;
    if(cou++==data[0]){
    UCSRA |= 0x01; // Bit MPCM=1
    Msg_Rec=TRUE;
    }
    }
    }else Error=TRUE;
    }
    //------------------------

    void USART_Slave_Send(unsigned char *data)
    {

    unsigned char i;
    RT=1;
    while(!(UCSRA & (1<<UDRE)));
    UCSRB &= ~(1 << TXB8);
    UDR=Slave_Address;
    for(i=0;i <= data[0];i++)
    {
    while(!(UCSRA & (1<<UDRE)));
    UCSRB &= ~(1 << TXB8);
    UDR=data[i];
    }
    RT=0;
    }


    به دنبال مرگ مي گشتم ... شهر به شهر، كوي به كوي، خانه به خانه و صاحب خانه اي خوابم را با نهيبش آشفته كرد ... كه چه نشستي كه اكنون بر مقبره ات سنگ مي كوبند گفتم چه خوب كه بعد از اين، طعم زندگي بس شيرين است و گوارا
    اي تو ... اي بذر نهال هستي ... اگر زنده اي دعاي خيرت را بدرقه راهم ساز ... اگر هم مردگي را تجربه مي كني، بيا با هم زنده شويم كه گويند زندگي زيباست

    #2
    پاسخ : ارتباط 2 میکرو با RS485

    کسی نمی تونست کمکی بکنه ؟ آقا اگه با RS232 هم کسی تونسته کاری که می خوام بکنم کمکم کنه ممنون میشمو من می خوام با ارتباط سریال 300 تا عدد integer رو به یک میکرو دیگه بفرستم بطوریکه میکرو اولی همیشه آماده دریافت باشه. ترتیب اعداد واسم مهمه
    به دنبال مرگ مي گشتم ... شهر به شهر، كوي به كوي، خانه به خانه و صاحب خانه اي خوابم را با نهيبش آشفته كرد ... كه چه نشستي كه اكنون بر مقبره ات سنگ مي كوبند گفتم چه خوب كه بعد از اين، طعم زندگي بس شيرين است و گوارا
    اي تو ... اي بذر نهال هستي ... اگر زنده اي دعاي خيرت را بدرقه راهم ساز ... اگر هم مردگي را تجربه مي كني، بيا با هم زنده شويم كه گويند زندگي زيباست

    دیدگاه


      #3
      پاسخ : ارتباط 2 میکرو با RS485

      سلام
      من هم میخوام همین کار رو با بسکام انجام بدم
      از وقفه استفاده کردم
      که در حالت عادی هر دو میکرو کار خودشون رو انجام بدن
      فقط یه چیزی بافر برای ارسال و دریافت از نوع بایت هست شما چطور می خوان این کا و انجام بدین
      و این تعداد کد رو (300) تا رو ردوبدل کنین
      لطف میکنین منو رو هم راهنمایی کنین

      دیدگاه


        #4
        پاسخ : ارتباط 2 میکرو با RS485

        فکر کنم r485 نیمه هست
        یعنی در یک لحظه فقط می تونینه بگیره یا بفرسته
        نمی تونه در ان واحد هردو کار بکنه
        هرچه سعی کنیم لایه های نرم افزاری زیاد کرده و از سخت افزار دور کنیم مشکلات(باگ ها) کمتر خواهد شد(امنیت بیشتری خواهید داشت)
        بهترین جواب دهنده برای سوال شما، خود شما هستید البته بعد تلاش،پشتکار و مطالعه بیشتر
        میدونی مشکل ما کجاست؟سرمایه و مغز ها رو نمیتونیم یکجا جمع کنیم...

        تعدادی ماژول GPS GP5MX1513F1 با بالاتریت حساسیت -170db به قیمت خرید بفروش میرسد

        دیدگاه


          #5
          پاسخ : ارتباط 2 میکرو با RS485

          من این کارو تقریبا انجام دادم ، توضیح میدم ببین اگه اینو میخوای کلشو بگم :

          من تقریبا 10 تا گره توشبکم داشتم هر گره ای هم برای خودش هم ارسال داشت هم دریافت بعضیا میفرستادن بعضیا میگرفتن بعضیام هر دوتاش . با یدونه 485 این کارو انجام میدادم باس همیشه منتظر دریافت بود فقط وقتی میخواست بفرسته میرفت تو مد ارسال . اگه اینو میخوای کاملتر توضیح بدم.
          A-Hosseini

          دیدگاه


            #6
            پاسخ : ارتباط 2 میکرو با RS485

            نوشته اصلی توسط behrooz_elec
            سلام دوستان
            من می خوام بین 2 میکرو با RS485 ارتباط برقرار کنم . روش کار به اینصورت هست که باید هر دو میکرو هر لحظه که data واسشون ارسال شد دریافت کنن به این معنی که وقتی میکرو کار دیگه ای انجام می ده اگه data برایش ارسال شد دریافت کند . هر 2 میکرو این قابلیتو باید داشته باشند. خودم برنامه نوشتم که با interrupt هست و اولی master و دومی slave هست ولی عددها که بزگ میشن نمی فرسته و یا وقتی برنامه MASTER را تو برنامه اصلی اضافه می کنم مشکل پیدا می کنه. می می خوام 400 تا عدد integer رو از master به slave بفرستم و برعکس.ممنون میشم اگه کسی راهنماییم کنه یا یک برنامه ساده واسم بزاره .برنامه خودمم گذاشتم

            برنامه master
            #include <mega32.h>
            #include <stdio.h>
            #include <delay.h>


            #define RXB8 1
            #define TXB8 0
            #define UPE 2
            #define OVR 3
            #define FE 4
            #define UDRE 5
            #define RXC 7

            #define FRAMING_ERROR (1<<FE)
            #define PARITY_ERROR (1<<UPE)
            #define DATA_OVERRUN (1<<OVR)
            #define DATA_REGISTER_EMPTY (1<<UDRE)
            #define RX_COMPLETE (1<<RXC)

            #define RT PORTB.0
            #define TRUE 1
            #define FALSE 0

            #define XTAL 11059200


            void USART_Master_Init(unsigned int baud,char u2x);
            void USART_Master_Receive(unsigned char *data);
            void USART_Master_Send(unsigned char *data,unsigned char address);

            char Error,Msg_Rec;
            char buffer[20],receive_buf[20];
            unsigned int cou;
            int send_buf[20];

            //-----------------------------------------
            // USART Receiver interrupt service routine
            interrupt [USART_RXC] void usart_rx_isr(void)
            {
            USART_Master_Receive(receive_buf);
            }
            //-----------------------------------------
            void main(){
            unsigned int i;
            DDRB=0x01;
            RT=0;
            Msg_Rec=FALSE;
            Error=FALSE;
            USART_Master_Init(115200,1);
            for(i=0;i<20;i++)
            send_buf[i]=20000+2*i;
            #asm("sei&quot
            while (1)
            {

            USART_Master_Send(send_buf,45);
            //USART_Master_Send(send_buf,42);
            if (Msg_Rec) {
            Msg_Rec=FALSE;
            for (i = 2; i <= receive_buf[1]+1;i++){

            sprintf(buffer,"data=%c",receive_buf[i]);

            delay_ms(300);
            }
            delay_ms(1);
            USART_Master_Send(send_buf,receive_buf[0]);
            }
            };
            }
            //------------------------
            void USART_Master_Init(unsigned int baud,char u2x)
            {
            unsigned int BudeRate;
            // USART initialization
            // Communication Parameters: 8 Data, 1 Stop, No Parity
            // USART Receiver: On
            // USART Transmitter: On
            // USART Mode: Asynchronous
            UCSRA=0x00;
            UCSRB=0x9C;
            UCSRC=0x86;
            if(u2x)
            BudeRate = XTAL / 8 / baud - 1;
            else
            BudeRate = XTAL / 16 / baud - 1;
            UBRRH = (unsigned char)(BudeRate >> 8);
            UBRRL = (unsigned char)BudeRate;

            }
            //---------------------------
            void USART_Master_Send(unsigned char *data, unsigned char address)
            {
            unsigned char i;
            RT=1;
            while(!(UCSRA & (1<<UDRE)));
            UCSRB |= (1 << TXB8);
            UDR=address;
            for(i=0;i <= data[0];i++)
            {
            while(!(UCSRA & (1<<UDRE)));
            UCSRB &= ~(1 << TXB8);
            UDR=data[i];
            }
            RT=0;
            }
            //------------------------
            void USART_Master_Receive(unsigned char *data)
            {
            unsigned char input,status;
            status=UCSRA;
            if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
            {
            Error=FALSE;
            input=UDR;
            data[cou] = input;
            if(cou++==data[1]+1)
            {
            Msg_Rec=TRUE;
            cou=0;
            }

            }
            else Error=TRUE;
            }



            برنامه slave

            #include <mega32.h>
            #include <stdio.h>
            #include <delay.h>
            #asm
            .equ __lcd_port=0x18 ;PORTB
            #endasm
            #include <lcd.h>

            #define RXB8 1
            #define TXB8 0
            #define UPE 2
            #define OVR 3
            #define FE 4
            #define UDRE 5
            #define RXC 7

            #define FRAMING_ERROR (1<<FE)
            #define PARITY_ERROR (1<<UPE)
            #define DATA_OVERRUN (1<<OVR)
            #define DATA_REGISTER_EMPTY (1<<UDRE)
            #define RX_COMPLETE (1<<RXC)

            #define RT PORTD.2
            #define Slave_Address 45
            #define XTAL 11059200

            #define TRUE 1
            #define FALSE 0
            char chek;
            char buffer[20];//,receive_buf[20],send_buf[20]={5,'S','l','a',&#03 9;v','e'};
            int receive_buf[20],send_buf[20];
            char Error,Msg_Rec;
            unsigned int cou;

            void USART_slave_Init(unsigned int baud,char u2x);
            void USART_Slave_Receive(unsigned char *data);
            void USART_Slave_Send(unsigned char *data);


            //-------------------------------------
            // USART Receiver interrupt service routine
            interrupt [USART_RXC] void usart_rx_isr(void)
            {
            USART_Slave_Receive(receive_buf);
            }
            //----------------------------------------
            void main(){
            unsigned int i,len;
            DDRD=0x04;
            RT=0;
            lcd_init(16);
            lcd_clear();
            USART_slave_Init(115200,1);
            Msg_Rec=FALSE;
            Error=FALSE;
            send_buf[0]=16;
            send_buf[1]=255;
            #asm("sei&quot
            while (1){

            if (Msg_Rec) {
            Msg_Rec=FALSE;
            len=receive_buf[0];
            for (i = 1; i <= len;i++){
            lcd_clear();
            sprintf(buffer,"data=%d",receive_buf[i]);
            lcd_puts(buffer);
            delay_ms(300);
            }
            delay_ms(1);
            USART_Slave_Send(send_buf);
            }
            if(receive_buf[19]==255)
            {
            USART_Slave_Send(send_buf);
            break;
            }
            };
            }
            //------------------------
            void USART_slave_Init(unsigned int baud,char u2x)
            {
            unsigned int BudeRate;
            // USART initialization
            // Communication Parameters: 8 Data, 1 Stop, No Parity
            // USART Receiver: On
            // USART Transmitter: On
            // USART Mode: Asynchronous
            UCSRA=0x01; // Bit MPCM=1
            UCSRB=0x9c;
            UCSRC=0x86;
            if(u2x)
            BudeRate = XTAL / 8 / baud - 1;
            else
            BudeRate = XTAL / 16 / baud - 1;

            UBRRH = (unsigned char)(BudeRate >> 8);
            UBRRL = (unsigned char)BudeRate;

            }
            //------------------------
            void USART_Slave_Receive(unsigned char *data)
            {
            unsigned char input,status;
            chek=1;
            status=UCSRA;
            if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0){
            Error=FALSE;
            input=UDR;
            if(UCSRA & 0x01){
            if(input == Slave_Address){
            UCSRA &= 0xFE; // Bit MPCM=0
            cou=0;
            }
            }else{

            data[cou] = input;
            if(cou++==data[0]){
            UCSRA |= 0x01; // Bit MPCM=1
            Msg_Rec=TRUE;
            }
            }
            }else Error=TRUE;
            }
            //------------------------

            void USART_Slave_Send(unsigned char *data)
            {

            unsigned char i;
            RT=1;
            while(!(UCSRA & (1<<UDRE)));
            UCSRB &= ~(1 << TXB8);
            UDR=Slave_Address;
            for(i=0;i <= data[0];i++)
            {
            while(!(UCSRA & (1<<UDRE)));
            UCSRB &= ~(1 << TXB8);
            UDR=data[i];
            }
            RT=0;
            }


            با سلام
            من هم بین دو میکرو با ADM485 ارتباط بر قرار کردم ولی موقع تغییر جهت ADM485 بعضی مواقع دیتا درست دریافت نمی شه خلاصه ارتباط چندان مورد اطمینان نیست توی زمان بندی بین ارسال و دریافت مشکل دارم
            من میخوام میکروی اولی هر موقع یک کد شناسایی داد میکرو دوم متوجه بشه و یک ack بفرسته و بعد دیتا رو بگیره و.....

            کسی از دوستان نمونه ای از یک برنامه مشابه داره؟؟؟؟

            دیدگاه

            لطفا صبر کنید...
            X