ورود به حساب ثبت نام جدید فراموشی کلمه عبور
برای ورود به حساب کاربری خود، نام کاربری و کلمه عبورتان را در زیر وارد کرده و روی «ورود به سایت» کلیک کنید.





اگر فرم ثبت نام برای شما نمایش داده نمی‌شود، اینجا را کلیک کنید.









اگر فرم بازیابی کلمه عبور برای شما نمایش داده نمی‌شود، اینجا را کلیک کنید.





صفحه 2 از 2 نخست 12
  1. #11
    2012/04/13
    249
    4

    پاسخ : کار با وقفه USART

    نقل قول نوشته اصلی توسط aghel110
    سلام
    ایا با ورود به روتین وقفه سریال، تایمر از کار می افته ؟
    سلام
    واحد تایمر کانتر یه واحد مجزاست و به محض راه اندازی کار خودش رو انجام میده و بقیه قسمت های میکرو تاخیری تو کار تایمر ایجاد نمی کنن
    ولی اگه از وقفه تایمر استفاده میکنی، ممکنه تداخل وقفه ها باعث به هم ریختن محاسباتت بشه
    در کل سعی کن تو زیربرنامه های وقفه تعداد خطوط برنامت خیلی کم باشه، مثلا یه متغیر رو اضافه کن بعد تو برنامه اصلی از مقادیرش استفاده کن

    نقل قول نوشته اصلی توسط aghel110
    سلام

    ایا با ورود به وقفه سریال تایمرها از کار می افتند؟
    یه برنامه داریم که با توجه به دستوری که از پورت سریال میگیره کارهای مختلفی انجام میده. وقتی دستور سرعت میاد باید موتور دی سی با توجه به سرعت ارسالی (یک عدد بین -100 تا +100) بچرخد. عدد دریافتی رو در OCR1A قرار میدم و تایمر در مد PWM به خوبی کار میکنه.
    اما وقتی اطلاعات جدید میاد با رفتن میکرو به روتین وقفه دریافت سریال موتور می ایستد. ظاهرا تایمرها از کار می افتند. ایا حدسم درسته؟ برای رفع مشکل چه باید کرد؟

    هدف از برنامه:
    دریافت دستورات از سریال و اجرا کردن انهاست.

    تشکر از راهنمایی
    نه تایمر میکرو نمی ایسته! احتمالا اشتباهی تو نوشتن دستورات داری!

    نقل قول نوشته اصلی توسط ahmp
    ممنون از اینکه وقتتون رو برای من گذاشتید.
    اما من می خوام adc رو به عنوان یک عدد بخونم و به میکروی دیگه ارسال کنم و اون میکرو در ال سی دی نشون بده.البته ایده شما هم جالب بود.
    بازم ممنون
    با احترام به جواب های خوب Abbas Sarami ، نظر من استفاده از هدر USART هست!
  2. #12
    2005/07/30
    پايتخت فرهنگي جهان اسلام
    79
    0

    پاسخ : کار با وقفه USART

    کد:
    #include <mega88pa.h>
    #include <delay.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    
    #define LED_on PORTB.0=0 
    #define LED_off PORTB.0=1
    
    #define MaxSpeed 25
    #define MinSpeed -25
    
    signed char vel_l,vel_r;
    
    void initAVR(void);
    void Speed2(void);
    
    //===================================== Forward Moving for Right Motor
    void RForward(unsigned char REnable)
    {
     PORTB.5=1;
     PORTB.4=0;
     OCR1AL=REnable;
    }
    
    //===================================== Backward Moving for Right Motor
    void RBackward(unsigned char REnable)
    {
     PORTB.5=0 ;
     PORTB.4=1;
     OCR1AL=REnable;
    }
    
    //===================================== Forward Moving for Left Motor
    void LForward(unsigned char LEnable)
    {
     PORTD.6=1;
     PORTD.7=0;
     OCR1BL=LEnable;
    }
                                    
    //===================================== Backward Moving for Left Motor
    void LBackward(unsigned char LEnable)
    {
     PORTD.6=0;
     PORTD.7=1;
     OCR1BL=LEnable;
     } 
     //===================================== OFF the Motors
     void OFF()
     {
     PORTB.4=0;
     PORTB.5=0;
     OCR1AL=0;
     PORTD.6=0;
     PORTD.7=0;
     OCR1BL=0;
     } 
    //===================================== 
    int Char2int(char c)
    {
      switch(c)
      {
        case '1': return(1);
        case '2': return(2);
        case '3': return(3);
        case '4': return(4);
        case '5': return(5);
        case '6': return(6);
        case '7': return(7);
        case '8': return(8);
        case '9': return(9);
        case '0': return(0);
      }
    }
    //===================================== 
    #define ADC_VREF_TYPE 0x40
    
    // Read the AD conversion result
    unsigned int read_adc(unsigned char adc_input)
    {
    ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
    // Delay needed for the stabilization of the ADC input voltage
    delay_us(10);
    // Start the AD conversion
    ADCSRA|=0x40;
    // Wait for the AD conversion to complete
    while ((ADCSRA & 0x10)==0);
    ADCSRA|=0x10;
    return ADCW;
    }
    
    //===================================== 
    
    #ifndef RXB8
    #define RXB8 1
    #endif
    
    #ifndef TXB8
    #define TXB8 0
    #endif
    
    #ifndef UPE
    #define UPE 2
    #endif
    
    #ifndef DOR
    #define DOR 3
    #endif
    
    #ifndef FE
    #define FE 4
    #endif
    
    #ifndef UDRE
    #define UDRE 5
    #endif
    
    #ifndef RXC
    #define RXC 7
    #endif
    
    #define FRAMING_ERROR (1<<FE)
    #define PARITY_ERROR (1<<UPE)
    #define DATA_OVERRUN (1<<DOR)
    #define DATA_REGISTER_EMPTY (1<<UDRE)
    #define RX_COMPLETE (1<<RXC)
    
    // USART Receiver buffer
    #define RX_BUFFER_SIZE0 15
    char rx_buffer0[RX_BUFFER_SIZE0];
    char buffer[RX_BUFFER_SIZE0];
    
    #if RX_BUFFER_SIZE0 <= 256
    unsigned char rx_wr_index0,rx_rd_index0,rx_counter0;
    #else
    unsigned int rx_wr_index0,rx_rd_index0,rx_counter0;
    #endif
    
    // This flag is set on USART Receiver buffer overflow
    bit rx_buffer_overflow0;
    
    // USART Receiver interrupt service routine
    interrupt [USART_RXC] void usart_rx_isr(void)
    {
    char status,data;
    status=UCSR0A;
    data=UDR0;
    if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
      {
      if (data=='$')            rx_wr_index0=0; 
      if ((rx_wr_index0==1) && (data=='P')) rx_wr_index0=1; 
       
      if (rx_wr_index0==2 && data=='W') rx_wr_index0=2; 
      
      if (rx_wr_index0==3 && data=='M') rx_wr_index0=3; 
      
                    
      =if (rx_wr_index0==4 && data=='=') rx_wr_index0==4;          //$PWM=            
        
      rx_buffer0[rx_wr_index0++]=data;
       
      #if RX_BUFFER_SIZE0 == 256
      // special case for receiver buffer size=256
      if (++rx_counter0 == 0) rx_buffer_overflow0=1;
    #else
      if (rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0;
      if (++rx_counter0 == RX_BUFFER_SIZE0)
       {
       rx_counter0=0;
       rx_buffer_overflow0=1;
       }
       
    #endif
      }
      
    }
    
    #ifndef _DEBUG_TERMINAL_IO_
    // Get a character from the USART Receiver buffer
    #define _ALTERNATE_GETCHAR_
    #pragma used+
    char getchar(void)
    {
    char data;
    while (rx_counter0==0);
    data=rx_buffer0[rx_rd_index0++];
    #if RX_BUFFER_SIZE0 != 256
    if (rx_rd_index0 == RX_BUFFER_SIZE0) rx_rd_index0=0;
    #endif
    #asm("cli")
    --rx_counter0;
    #asm("sei")
    return data;
    }
    #pragma used-
    #endif
    
    
    
    void main(void)
    {
    
    initAVR();
    
    LED_on;
    delay_ms(500);
    LED_off;
    printf("Salam...\r");
    
    #asm("sei");
    
    while(1)
      {
      if (rx_buffer0[0]=='$' && rx_buffer0[1]=='P' && rx_buffer0[2]=='W' && rx_buffer0[3]=='M'&& rx_buffer0[4]=='=' ) 
      {  
         #asm("cli");
         if(rx_buffer0[rx_wr_index0-3]=='*')
         {  
          rx_counter0=0;
          rx_wr_index0=0;
          rx_buffer0[3]='0'; // to reset buffer
          Speed2();
         }     
         #asm("sei");
      }        
       
      }
    
    }//End Main
    //============================================================================
    void Speed2()
    {
      char i;
      
      i=5;
        
      if (rx_buffer0[i]=='-')      
      {
        i++; //6
        if(rx_buffer0[i+1]==',') 
        {
        vel_l = -(Char2int(rx_buffer0[i])) ;
        }
        else
        {  
          vel_l = -((Char2int(rx_buffer0[i])*10)+ Char2int(rx_buffer0[i+1])) ;  //i=7
          i++;
        }
      }
      else 
      {
        if(rx_buffer0[i+1]==',') vel_l = Char2int(rx_buffer0[i]) ;  
        else 
        {  
          vel_l = ((Char2int(rx_buffer0[i])*10)+ Char2int(rx_buffer0[i+1]));
          i++;
        }
      }  
      
      i++;
      i++; // ','
        
      if (rx_buffer0[i]=='-')      
      { 
        i++;
        if(rx_buffer0[i+1]=='*') vel_r = -Char2int(rx_buffer0[i]) ;  
        else
        {
        vel_r = -((Char2int(rx_buffer0[i])*10)+ Char2int(rx_buffer0[i+1])) ;
        i++; 
        }
      }
      else 
      {
        if(rx_buffer0[i+1]=='*') vel_r = Char2int(rx_buffer0[i]) ;  
        else
        {
          vel_r = ((Char2int(rx_buffer0[i])*10)+ Char2int(rx_buffer0[i+1])) ;
          i++;
        }  
      }
        
      
      if(vel_l>MaxSpeed)  vel_l=MaxSpeed;
      if(vel_l<MinSpeed)  vel_l=MinSpeed;
      if(vel_r>MaxSpeed)  vel_r=MaxSpeed;
      if(vel_r<MinSpeed)  vel_r=MinSpeed;
      
      if(vel_l>0)  LForward((unsigned char)vel_l);
      else      LBackward(cabs(vel_l));
      if(vel_r>0)  RForward((unsigned char)vel_r);
      else      RBackward(cabs(vel_r));
    
    }
    //=========================
    
     void initAVR(void)
     {
    // Crystal Oscillator division factor: 1
    #pragma optsize-
    CLKPR=0x80;
    CLKPR=0x00;
    #ifdef _OPTIMIZE_SIZE_
    #pragma optsize+
    #endif
    
     // Input/Output Ports initialization
    // Port B initialization
    // Func7=In Func6=In Func5=Out Func4=Out Func3=In Func2=Out Func1=Out Func0=Out 
    // State7=T State6=T State5=0 State4=0 State3=T State2=0 State1=0 State0=0 
    PORTB=0x00;
    DDRB=0x37;
    
    // Port D initialization
    // Func7=Out Func6=Out Func5=In Func4=In Func3=In Func2=In Func1=Out Func0=In 
    // State7=0 State6=0 State5=T State4=T State3=T State2=T State1=0 State0=T 
    PORTD=0x00;
    DDRD=0xC0;
    
    // Timer/Counter 0 initialization
    // Clock source: T0 pin Falling Edge
    // Mode: Normal top=0xFF
    // OC0A output: Disconnected
    // OC0B output: Disconnected
    TCCR0A=0x00;
    TCCR0B=0x06;
    TCNT0=0x00;
    OCR0A=0x00;
    OCR0B=0x00;
    
    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: 7.813 kHz
    // Mode: Fast PWM top=0x00FF
    // OC1A output: Non-Inv.
    // OC1B output: Non-Inv.
    // Noise Canceler: On
    // Input Capture on Falling Edge
    // Timer1 Overflow Interrupt: Off
    // Input Capture Interrupt: Off
    // Compare A Match Interrupt: Off
    // Compare B Match Interrupt: Off
    TCCR1A=0xA1;
    TCCR1B=0x8D;
    TCNT1H=0x00;
    TCNT1L=0x00;
    ICR1H=0x00;
    ICR1L=0x00;
    OCR1AH=0x00;
    OCR1AL=0x00;
    OCR1BH=0x00;
    OCR1BL=0x00;
    
    // Timer/Counter 2 initialization
    // Clock source: Ext. clk. on TOSC1 pin
    // Clock value: PCK2
    // Mode: Normal top=0xFF
    // OC2A output: Disconnected
    // OC2B output: Disconnected
    ASSR=0x60;
    TCCR2A=0x00;
    TCCR2B=0x01;
    TCNT2=0x00;
    OCR2A=0x00;
    OCR2B=0x00;
    
    // USART initialization
    // Communication Parameters: 8 Data, 1 Stop, No Parity
    // USART Receiver: On
    // USART Transmitter: On
    // USART0 Mode: Asynchronous
    // USART Baud Rate: 9600
    UCSR0A=0x00;
    UCSR0B=0x98;
    UCSR0C=0x06;
    UBRR0H=0x00;
    UBRR0L=0x33;
    
    // Analog Comparator initialization
    // Analog Comparator: Off
    // Analog Comparator Input Capture by Timer/Counter 1: Off
    ACSR=0x80;
    ADCSRB=0x00;
    DIDR1=0x00;
    
    // ADC initialization
    // ADC Clock frequency: 62.500 kHz
    // ADC Voltage Reference: AVCC pin
    // ADC Auto Trigger Source: ADC Stopped
    // Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On
    // ADC4: On, ADC5: On
    DIDR0=0x00;
    ADMUX=ADC_VREF_TYPE & 0xff;
    ADCSRA=0x87;
    
    }
    میشه اشکال زدایی بشه ؟
    دستور ارسال سرعت برای موتور سمت چپ و راست از طریق سریال انجام میشه که به فرمت زیر است:
    کد:
    $PWM=[2,2]*
    $PWM=[10,24]*
    $PWM=[-12,-3]*
    $PWM=[-20,3]*
    یکی از حالتهای فوق دریافت میشود البته اعداد یا یک رقمی است یا دو رقمی. که باید عدد دریافتی تشخیص داده شود و به موتورها اعمال شوند که این کار توسط تابع Speed2 انجام میشه.(البته شاید خوب نوشته نشده باشه ولی جواب میده !)
    مشکل:
    وقتی با هیپر ترمینال به فرمت ذکر شده دستور ارسال میکنم موتورها شروع به چرخش میکنند اما به محض اینکه کاراکتری جدید ارسال میکنم موتورها متوقف میشوند(ظاهرا تایمر یک که برای تولید PWM می باشد از کار می افته!!) و تا زمان فشردن اینتر ظاهرا در روتین وقفه میماند و اگر مقدار جدیدی به فرمت ذکر شده ارسال نشود موتورها همچنان متوقف می مانند.

    >>>>> اللهم عجل لولیک الفرج <<<



    لطفا براي تشكر از امتياز مثبت استفاده بفرماييد
  3. #13
    2015/09/29
    7
    1

    پاسخ : کار با وقفه USART

    نقل قول نوشته اصلی توسط sadeghmojtabaei

    مهمان عزیز شما حق دیدن لینک ها را ندارید

    عضویت

    وقفه دریافت یا ارسال؟

    برای وقفه دریافت:
    اون کد ها برای دریافت چندین بایت هست. اگر خیلی کار خاصی نیست همه اون کد های اضافی را پاک کنید و فقط وقفه را خالی بگذارید بعد یه متغیر از نوع char را به صورت عمومی تعریف کنید و مقدار اون را در وقفه برابر UDR قرار بدید.

    برای وقفه ارسال فکر نمی کنم چیز خاصی تولید بشه.
    سلام
    مهندس وقتی که میخوام با اینتراپت وقفه کار کنم، خوب جواب میده و دریافت میکنه(ارتباط میکرو با میکرو)
    مشکلی که دارم اینه که وقتی از پورت سریال استفاده میکنم برای ارسال کد، در برنامهِ میکرو اگر با اینتراپت دریافت کنم، اصلا میکرو چیزی رو دریافت نمیکنه!! و اصلا داخل اینتراپت نمیره (امتحان کردم)
    اما اگه بدون اینتراپت باشه، خوب دریافت میکنه
    ارسال کد از طریق پایتون انجام میشه
    ممنون میشم
صفحه 2 از 2 نخست 12
نمایش نتایج: از 11 به 13 از 13

موضوعات مشابه

  1. دریافت کاراکتر از وقفه usart و ارسال ش با وقفه spi
    توسط davoud.arabee در انجمن برنامه نویسی و اینترفیس
    پاسخ: 5
    آخرين نوشته: 2016/04/01, 22:42
  2. مشکل در وقفه usart
    توسط vahidabedi در انجمن میکروکنترلرهای AVR
    پاسخ: 13
    آخرين نوشته: 2015/09/24, 22:34
  3. رجیستر وقفه ترانسمیت در usart
    توسط mehdi_24 در انجمن میکروکنترلرهای AVR
    پاسخ: 1
    آخرين نوشته: 2015/02/25, 10:20
  4. سوال درباره وقفه usart در کدویژن
    توسط minefield در انجمن میکروکنترلرهای AVR
    پاسخ: 4
    آخرين نوشته: 2013/07/22, 08:24
  5. وقفه در تبادل سریال usart
    توسط dizgah در انجمن میکروکنترلرهای AVR
    پاسخ: 4
    آخرين نوشته: 2010/08/14, 09:34

علاقه مندي ها (Bookmarks)

علاقه مندي ها (Bookmarks)

مجوز های ارسال و ویرایش

  • شما نمیتوانید موضوع جدیدی ارسال کنید
  • شما امکان ارسال پاسخ را ندارید
  • شما نمیتوانید فایل پیوست کنید.
  • شما نمیتوانید پست های خود را ویرایش کنید
  •