اطلاعیه

Collapse
No announcement yet.

RS485

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

    RS485

    سلام
    بچه ها یه پروژه RS485 دارم کار میکنم ک با لطف کتاب مهندس پرتوئی فر به یه جاهایی رسوندمش ولی تو برنامه SLAVE وقتی به تابع ارسال میرسم وارد تابع میشه ولی توحلقه FOR نمیره نمیدونم مشکل مال بافره یا مال مقادیره I یا... توروخداکمک کنید.
    اینم سورس برنامه
    #include <mega32.h>
    #include <delay.h>
    #include <stdio.h>
    #include <stdlib.h>
    #asm
    .equ __lcd_port=0x18;
    #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_EMPEY (1<<UDRE)
    #define RX_COMPLETE (1<<RXC)
    #define RT PORTD.2
    #define Slave_Address 11
    #define TRUE 1
    #define FALSE 0

    #define XTAL 11059200

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

    char Error,Msg_Rec;
    char buffer[20],receive_buf[20],send_buff[20]={5,'A','L','E',&#03 9;Y','K'},send_buff2[20]={5,'A','L','E',&#03 9;Y','K'};
    unsigned int cou;

    interrupt [USART_RXC]void usart_rxc_isr(void)
    {
    USART_Slave_Receive (receive_buf);
    }


    void main(){
    unsigned int i,len;
    DDRD=0x04;
    DDRA=0xff;
    RT=0; //tanzime paye control adm485 dar jahate voroudi
    Msg_Rec=FALSE;
    Error=FALSE;
    lcd_init(16);
    USART_Slave_Init(9600,0);
    #asm("sei&quot

    while(1)
    {
    if(Error){
    lcd_clear();
    sprintf(buffer,"error"
    lcd_puts(buffer);
    }

    if(Msg_Rec){
    Msg_Rec=FALSE;
    len=receive_buf[0];
    for(i=1; i <= len; i++){
    lcd_clear();
    sprintf(buffer,"data=%c",receive_buf[i]);
    lcd_puts(buffer);
    delay_ms(300);
    }
    delay_ms(1);
    USART_Slave_Send(send_buff);
    }
    }
    }

    void USART_Slave_Init(unsigned int baud,char u2x)
    {
    unsigned int BudeRate;
    UCSRA=0x01;
    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_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++)
    { PORTA=~PORTA;
    while(!(UCSRA &(1<<UDRE)));
    UCSRB &= ~(1 << TXB8);
    UDR=data[i];
    }
    RT=0;
    }

    void USART_Slave_Receive(unsigned char *data)
    {
    unsigned char input,status;
    status=UCSRA;
    if((status & (FRAMING_ERROR |PARITY_ERROR |DATA_OVERRUN))==0){
    Error=FALSE;
    input=UDR;
    if(UCSRA &0x01){
    if(input==Slave_Address){
    UCSRA&=0XFE;
    cou=0;
    }
    }
    else{
    data[cou]=input;
    if((cou++==data[0])){
    UCSRA |=0x01;
    Msg_Rec=TRUE;
    }
    }
    }else Error=TRUE;
    }

    #2
    پاسخ : RS485

    درست متوجه اشکال نشدم ولی یه سوال برام پیش اومد .
    چرا در شرط حلقه for جلوی متغییر unsigned char ای که در واقع data هست شما از اندیس صفر استفاده کردی ؟ منظور چیه؟ شاید من اشتباه می کنم .

    در هر صورت من فکر می کنم متغییر data[0] شما مقداری برابر صفر داره که حلقه اجرا نمیشه .

    موفق باشید
    - به دنبال فرصت عمری تباه کردم ! فرصت جوانی ام بود من اشتباه کردم .

    دیدگاه


      #3
      پاسخ : RS485

      نوشته اصلی توسط Mania59
      درست متوجه اشکال نشدم ولی یه سوال برام پیش اومد .
      چرا در شرط حلقه for جلوی متغییر unsigned char ای که در واقع data هست شما از اندیس صفر استفاده کردی ؟ منظور چیه؟ شاید من اشتباه می کنم .

      در هر صورت من فکر می کنم متغییر data[0] شما مقداری برابر صفر داره که حلقه اجرا نمیشه .

      موفق باشید
      ممنون مهندس
      اون data[0] که نوشتم اندیس اول send buff[20] که طول ارایه ارسال ودرحقیقت تعداد دفعات تکرار حلقه for رامشخص میکنه.
      حالا مشکل من اینه که این مقدار متناظربا این متغیر 5 هست ولی یجورایی برنامه اونو 5 تشخیص نمیده وفکرکنم حتی صفرم تشخیص نمیده چون اصلا وارداین حلقه نمیشه.
      ممنون از همتون توروخداکمک کنید پروژه رو باید زود تحویل بدم. :nice:

      دیدگاه


        #4
        پاسخ : RS485

        آیا امتحان کردی یه بار عدد 5 رو بزاری تو برنامه ببینی اصلا انجام میشه یا نه ؟
        بعد از کجا متوجه میشید که داخل حلقه FOR نمی ره ؟
        - به دنبال فرصت عمری تباه کردم ! فرصت جوانی ام بود من اشتباه کردم .

        دیدگاه


          #5
          پاسخ : RS485

          5روگذاشتم بازم نرفت
          یدونه پورت a اول حلقه معرفی کردم که با هربارورود به حلق یه چشمک میزنه

          دیدگاه


            #6
            پاسخ : RS485

            خوب شما مطمئن هستی که برنامه اطلا به قبل از حلقه for می رسه شاید توی while قبلش گیر میکنه ؟

            در ضمن من هیچ وقت از این روشی که شما استفاده کردید برای برای انتقال مقدار بافر به داخل تابع که اومدید ابتدا یه بافر ساختین و بعد ازطریق یک کاراکتر اشاره گر اونو بردید به داخل حلقه استفاده نکرده بودم . نمی دونم آیا واقعا کار می کنه ؟ :surprised:
            - به دنبال فرصت عمری تباه کردم ! فرصت جوانی ام بود من اشتباه کردم .

            دیدگاه


              #7
              پاسخ : RS485

              نوشته اصلی توسط Mania59
              خوب شما مطمئن هستی که برنامه اطلا به قبل از حلقه for می رسه شاید توی while قبلش گیر میکنه ؟

              در ضمن من هیچ وقت از این روشی که شما استفاده کردید برای برای انتقال مقدار بافر به داخل تابع که اومدید ابتدا یه بافر ساختین و بعد ازطریق یک کاراکتر اشاره گر اونو بردید به داخل حلقه استفاده نکرده بودم . نمی دونم آیا واقعا کار می کنه ؟ :surprised:
              ممنون از وقتی که گذاشتید
              درجواب سوال اول بگم که برنامه رو با همین پورت a خط به خط چک کردم تا دقیقا سر for جواب میده بعد اونم جواب میده ولی داخل اون نه.
              ودرادامه میخاستم ببینم شما که از این روش استفاده نکردید چه روشی پیشنهاد میدید که بتونم جواب بگیرم.باتشکر.

              دیدگاه


                #8
                پاسخ : RS485

                خوب شما متغییر بافر رو بصورت public تعریف کردید . پس مستقیم می تونید اونو داخل حلقه for ازش استفاده کنید اصلا چه نیازی هست که بخواهید با پارامتر داخل تابع send ببریدش و بعد هم for . مستقیم بجای data با اندیس صفر خود بافر با اندیس صفر رو قرار بدید .

                مثلا این طوری
                کد:
                void USART_Slave_Send()
                 {   
                 unsigned char i;
                
                 RT=1; 
                 while(!(UCSRA &(1<<UDRE)));
                 UCSRB &=~(1<<TXB8);
                 UDR=Slave_Address;  
                 for(i=0; i <= send_buff[0]; i++)
                 { 
                	PORTA=~PORTA;    
                	while(!(UCSRA &(1<<UDRE))); 
                	UCSRB &= ~(1 << TXB8);
                	UDR=data;
                 } 
                  RT=0;
                 }
                - به دنبال فرصت عمری تباه کردم ! فرصت جوانی ام بود من اشتباه کردم .

                دیدگاه


                  #9
                  پاسخ : RS485

                  سلام.اقا مشکل بالا حل شد.ممنون.
                  اما من میخاستم باrs-485 دوتا میکرو رو باهم مستر اسلیو کنم.برنامه هردوتارونوشتم مستر به اسلیو یه عبارت میفرسته درپاسخ اسلیوباید یه عبارت به مستر بدد وروی ال سی دی نشون بدند.اتفاق اولی می افته ولی اسلیو ی عبارت برا مستر میفرسته که تابع دریافت مستر خطاهای ucsra رومیگیره.لطفاکمک کنید.
                  کد مستر و اسلیو به ترتیب میذارم
                  #include <mega32.h>
                  #include <delay.h>
                  #include <stdio.h>
                  #asm
                  .equ __lcd_port=0x18; // lcd 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_EMPEY (1<<UDRE)
                  #define RX_COMPLETE (1<<RXC)
                  #define RT PORTD.2
                  #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],send_buf1[20]={5,'S','A','L',&#03 9;A','M'},send_buf2[20]={5,'M','e','h',&#03 9;d','i'},send_buf3[20]={5,'p','A','r',&#03 9;s','z'},send_buf[20]={5,'S','a','l',&#03 9;a','r'};
                  unsigned int cou;

                  interrupt [USART_RXC]void usart_rxc_isr(void)
                  {
                  USART_Master_Receive (receive_buf);
                  }


                  void main(){
                  unsigned int i;
                  DDRD=0x04;
                  DDRA=0xFF;
                  RT=0; //tanzime paye control adm485 dar jahate voroudi
                  Msg_Rec=FALSE;
                  Error=FALSE;
                  lcd_init(16);
                  USART_Master_Init(9600,0);
                  #asm("sei&quot
                  USART_Master_Send(send_buf1,11);
                  while(1)
                  {

                  // USART_Master_Send(send_buf2,22);
                  // USART_Master_Send(send_buf3,33);

                  if(Error)
                  PORTA=0xf0;
                  if(Msg_Rec){
                  Msg_Rec=FALSE;PORTA=0xff;
                  for(i=2;i<= receive_buf[1]+1;i++){
                  lcd_clear();
                  sprintf(buffer,"data=%c",receive_buf[i]);
                  lcd_puts(buffer);
                  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;
                  UCSRA=0x00;
                  UCSRB=0x9C;
                  UCSRC=0x86;
                  if(u2x)
                  BudeRate=XTAL/8/baud-1;
                  else
                  BudeRate=XTAL/16/9600-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;//delay_us(11111);
                  }

                  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;
                  }




                  اینم اسلیو
                  #include <mega32.h>
                  #include <delay.h>
                  #include <stdio.h>
                  #include <stdlib.h>
                  #asm
                  .equ __lcd_port=0x18;
                  #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_EMPEY (1<<UDRE)
                  #define RX_COMPLETE (1<<RXC)
                  #define RT PORTD.2
                  #define Slave_Address 11
                  #define TRUE 1
                  #define FALSE 0

                  #define XTAL 11059200

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

                  char Error,Msg_Rec ;
                  char buffer[20],receive_buf[20],send_buff[20]={5,'A','L','E',&#03 9;Y','K'},send_buff2[20]={5,'A','L','E',&#03 9;Y','K'},send_buf1[20]={5,'S','A','L',&#03 9;A','M'};
                  unsigned int cou;

                  interrupt [USART_RXC]void usart_rxc_isr(void)
                  {
                  USART_Slave_Receive (receive_buf);
                  }


                  void main(){
                  unsigned int i,len;
                  DDRD=0x04;
                  DDRA=0xff;
                  RT=0; //tanzime paye control adm485 dar jahate voroudi
                  Msg_Rec=FALSE;
                  Error=FALSE;
                  lcd_init(16);
                  USART_Slave_Init(9600,0);
                  #asm("sei&quot

                  while(1)
                  {
                  if(Error){
                  lcd_clear();
                  sprintf(buffer,"error"
                  lcd_puts(buffer);
                  }

                  if(Msg_Rec){
                  Msg_Rec=FALSE;
                  len=receive_buf[0];
                  for(i=1; i <= len; i++){
                  lcd_clear();
                  sprintf(buffer,"data=%c",receive_buf[i]);
                  lcd_puts(buffer);
                  delay_ms(300);
                  }
                  delay_ms(1);
                  USART_Slave_Send(send_buf1);
                  }
                  }
                  }

                  void USART_Slave_Init(unsigned int baud,char u2x)
                  {
                  unsigned int BudeRate;
                  UCSRA=0x01;
                  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_Send(unsigned char *data)
                  {//char dade[];
                  unsigned char i;
                  //unsigned int code;
                  //char n[1];
                  RT=1;
                  while(!(UCSRA &(1<<UDRE)));
                  UCSRB &=~(1<<TXB8);
                  UDR=Slave_Address;
                  /*n[0]=data[0];
                  code=atoi(n);
                  lcd_clear();
                  sprintf(dade,"%i",code);
                  lcd_puts(dade);*/
                  for(i=0;i <= data[0]; i++){
                  while(!(UCSRA &(1<<UDRE)));
                  UCSRB &=~(1 << TXB8);
                  UDR=data[i];
                  }
                  RT=0;
                  }

                  void USART_Slave_Receive(unsigned char *data)
                  {
                  unsigned char input,status;
                  status=UCSRA;
                  if((status & (FRAMING_ERROR |PARITY_ERROR |DATA_OVERRUN))==0){
                  Error=FALSE;
                  input=UDR;
                  if(UCSRA &0x01){
                  if(input==Slave_Address){
                  UCSRA&=0XFE;
                  cou=0;
                  }
                  }
                  else{
                  data[cou]=input;
                  if((cou++==data[0])){
                  UCSRA |=0x01;
                  Msg_Rec=TRUE;
                  }
                  }
                  }else Error=TRUE;
                  }

                  دیدگاه

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