اطلاعیه

Collapse
No announcement yet.

مشکل در راه اندازی سون سگمنت مالتی پلکس با AVR

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

    مشکل در راه اندازی سون سگمنت مالتی پلکس با AVR

    باسلام.
    مدتی هست آموزش AVR رو با فیلم های مهندس کی نژاد شروع کردم و در پیاده سازی پروژه سون سگمنت و کیبورد با AVR به مشکلی خوردم که به هر دری زدم نتونستم جواب بگیرم(البته در پروتیوس تست میکنم و کار نمیکنه).
    مشکل اینه که در کد زیر به طرز عجیبی سون سگمنت های 2 و 4 رفرش نمیشن و فقط سون سگمنت های 1 و 3 رفرش میشن ،همچنین کیبورد هم به درستی اسکن نمیشه.
    البته بعد ازدیدن قسمت مربوطه شروع به پیاده سازی کد از صفر کردم و کد تغییراتی هم داشت از جمله سون سگمنت استفاده شده در آموزش از نوع کاتد مشترک بود و من بر اساس سون سگمنت آند مشترک برنامه رو نوشتم و کیبورد استفاده شده از 4 در 3 به 3 در 4 تغییر یافت.

    /*
    * Keyboard_7segment.c
    *
    * Created: 7/12/2021 11:39:10 PM
    * Author :
    * Chip : ATmega32
    D0 D1 D3
    --|--|--|--D4
    --|--|--|--D5
    --|--|--|--D6
    --|--|--|--D7

    PORTA0 -> a
    PORTA1 -> b
    PORTA2 -> c
    PORTA3 -> d
    PORTA4 -> e
    PORTA5 -> f
    PORTA6 -> g
    PORTA7 -> dp

    PORTB0 -> 7seg0
    PORTB1 -> 7seg1
    PORTB2 -> 7seg2
    PORTB3 -> 7seg3
    */


    #define F_CPU 1000000UL
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/pgmspace.h>
    #include <avr/interrupt.h>
    #define TRUE 1
    #define FALSE 0
    #define NO_KEY_CODE 12


    //Global Variables
    unsigned const char seg_table[] = {0xF9, 0xA4, 0xB0, 0x99, 0x92,
    0x82, 0xF8, 0x80, 0x90, 0xC0,
    0xFF, 0xBF};
    unsigned const char key_table[] = {0x76, 0x75, 0x73,
    0x6E, 0x6D, 0x6B,
    0x5E, 0x5D, 0x5B,
    0x3E, 0x3D, 0x3B};
    volatile unsigned char disp_data[] = {11, 11, 11, 11};//Display initialize (- - - -)
    volatile unsigned char key_code=NO_KEY_CODE;


    int main(void)
    {
    //Variables
    unsigned char old_key_code = NO_KEY_CODE,temp_key_code;
    unsigned char i = 4;
    //7 segment port configuration
    DDRA |= (1 << DDA0) | (1 << DDA1) | (1 << DDA2) | (1 << DDA3) | (1 << DDA4) | (1 << DDA5) | (1 << DDA6) | (1 << DDA7);
    DDRB |= (1 << DDB0) | (1 << DDB1) | (1 << DDB2) | (1 << DDB3);
    //Timer/Counter configuration
    OCR0 = 124;
    TIMSK = (1 << OCIE0);//Enable compare match interrupt
    TCCR0 = (1 << WGM01) | (1 << CS01) ;//Timer clock:fclk_io/8 ; mode:CTC
    sei();
    while (1)
    {
    temp_key_code = key_code;
    if(temp_key_code != old_key_code){
    old_key_code = temp_key_code;
    if(temp_key_code != NO_KEY_CODE){
    disp_data[i] = temp_key_code;
    if (--i == 0xFF) i=4;
    }
    }
    }
    }


    ISR(TIMER0_COMP_vect){
    static unsigned char x20 = 0;
    static unsigned char pointer = 0;
    unsigned char temp, i;
    //7 segment refresh routine
    PORTB = 0;//Turn off all segments
    PORTA = seg_table[disp_data[pointer]];
    PORTB = (1 << pointer);
    if(++pointer == 4) pointer = 0;
    //Keyboard scan routine
    if (++x20 == 20){
    x20 = 0;
    DDRD = (1 << DDD3) | (1 << DDD4) | (1 << DDD5) | (1 << DDD6);
    PORTD = (1 << PD0) | (1 << PD1) | (1 << PD2);
    _delay_us(5);//signal stabilization
    temp = (PIND & 0x07);
    DDRD = (1 << DDD0) | (1 << DDD1) | (1 << DDD2);
    PORTD = (1 << PD3) | (1 << PD4) | (1 << PD5) | (1 << PD6);
    _delay_us(5);
    temp |= (PIND & 0x78);
    for(i=0;i<12;i++){
    if(temp == key_table[i]){
    key_code = i;
    break;
    }
    else key_code = NO_KEY_CODE;
    }
    }
    همچنین وقتی متغیرpointer شرط صفر شدن اون به 3 تغییر پیدا میکنه ،سون سگمنت های یک و دو و سه به طور منظم رفرش میشن.
    حتی از سعی کردم از دیباگر atmel studio هم استفاده کنم که در اونجا متوجه شدوم متغیر ها به صورت درست تغییر میکنند ولی در عمل به صورت صحیح برنامه اجرا نمیشود.
    باتشکر.

    #2
    پاسخ : مشکل در راه اندازی سون سگمنت مالتی پلکس با AVR

    دوستان کسی نظری نداره؟
    من خودم 50 بار کد رو زیر و رو کردم ولی مشکلی پیدا نمیکنم.خواهشا اگه تجربه ای در این زمینه دارید ارائه بدید.
    باتشکر

    دیدگاه


      #3
      پاسخ : مشکل در راه اندازی سون سگمنت مالتی پلکس با AVR

      نوشته اصلی توسط A.I.E نمایش پست ها
      باسلام.
      مدتی هست آموزش AVR رو با فیلم های مهندس کی نژاد شروع کردم و در پیاده سازی پروژه سون سگمنت و کیبورد با AVR به مشکلی خوردم که به هر دری زدم نتونستم جواب بگیرم(البته در پروتیوس تست میکنم و کار نمیکنه).
      مشکل اینه که در کد زیر به طرز عجیبی سون سگمنت های 2 و 4 رفرش نمیشن و فقط سون سگمنت های 1 و 3 رفرش میشن ،همچنین کیبورد هم به درستی اسکن نمیشه.
      البته بعد ازدیدن قسمت مربوطه شروع به پیاده سازی کد از صفر کردم و کد تغییراتی هم داشت از جمله سون سگمنت استفاده شده در آموزش از نوع کاتد مشترک بود و من بر اساس سون سگمنت آند مشترک برنامه رو نوشتم و کیبورد استفاده شده از 4 در 3 به 3 در 4 تغییر یافت.

      /*
      * Keyboard_7segment.c
      *
      * Created: 7/12/2021 11:39:10 PM
      * Author :
      * Chip : ATmega32
      D0 D1 D3
      --|--|--|--D4
      --|--|--|--D5
      --|--|--|--D6
      --|--|--|--D7

      PORTA0 -> a
      PORTA1 -> b
      PORTA2 -> c
      PORTA3 -> d
      PORTA4 -> e
      PORTA5 -> f
      PORTA6 -> g
      PORTA7 -> dp

      PORTB0 -> 7seg0
      PORTB1 -> 7seg1
      PORTB2 -> 7seg2
      PORTB3 -> 7seg3
      */


      #define F_CPU 1000000UL
      #include <avr/io.h>
      #include <util/delay.h>
      #include <avr/pgmspace.h>
      #include <avr/interrupt.h>
      #define TRUE 1
      #define FALSE 0
      #define NO_KEY_CODE 12


      //Global Variables
      unsigned const char seg_table[] = {0xF9, 0xA4, 0xB0, 0x99, 0x92,
      0x82, 0xF8, 0x80, 0x90, 0xC0,
      0xFF, 0xBF};
      unsigned const char key_table[] = {0x76, 0x75, 0x73,
      0x6E, 0x6D, 0x6B,
      0x5E, 0x5D, 0x5B,
      0x3E, 0x3D, 0x3B};
      volatile unsigned char disp_data[] = {11, 11, 11, 11};//Display initialize (- - - -)
      volatile unsigned char key_code=NO_KEY_CODE;


      int main(void)
      {
      //Variables
      unsigned char old_key_code = NO_KEY_CODE,temp_key_code;
      unsigned char i = 4;
      //7 segment port configuration
      DDRA |= (1 << DDA0) | (1 << DDA1) | (1 << DDA2) | (1 << DDA3) | (1 << DDA4) | (1 << DDA5) | (1 << DDA6) | (1 << DDA7);
      DDRB |= (1 << DDB0) | (1 << DDB1) | (1 << DDB2) | (1 << DDB3);
      //Timer/Counter configuration
      OCR0 = 124;
      TIMSK = (1 << OCIE0);//Enable compare match interrupt
      TCCR0 = (1 << WGM01) | (1 << CS01) ;//Timer clock:fclk_io/8 ; mode:CTC
      sei();
      while (1)
      {
      temp_key_code = key_code;
      if(temp_key_code != old_key_code){
      old_key_code = temp_key_code;
      if(temp_key_code != NO_KEY_CODE){
      disp_data[i] = temp_key_code;
      if (--i == 0xFF) i=4;
      }
      }
      }
      }


      ISR(TIMER0_COMP_vect){
      static unsigned char x20 = 0;
      static unsigned char pointer = 0;
      unsigned char temp, i;
      //7 segment refresh routine
      PORTB = 0;//Turn off all segments
      PORTA = seg_table[disp_data[pointer]];
      PORTB = (1 << pointer);
      if(++pointer == 4) pointer = 0;
      //Keyboard scan routine
      if (++x20 == 20){
      x20 = 0;
      DDRD = (1 << DDD3) | (1 << DDD4) | (1 << DDD5) | (1 << DDD6);
      PORTD = (1 << PD0) | (1 << PD1) | (1 << PD2);
      _delay_us(5);//signal stabilization
      temp = (PIND & 0x07);
      DDRD = (1 << DDD0) | (1 << DDD1) | (1 << DDD2);
      PORTD = (1 << PD3) | (1 << PD4) | (1 << PD5) | (1 << PD6);
      _delay_us(5);
      temp |= (PIND & 0x78);
      for(i=0;i<12;i++){
      if(temp == key_table[i]){
      key_code = i;
      break;
      }
      else key_code = NO_KEY_CODE;
      }
      }
      همچنین وقتی متغیرpointer شرط صفر شدن اون به 3 تغییر پیدا میکنه ،سون سگمنت های یک و دو و سه به طور منظم رفرش میشن.
      حتی از سعی کردم از دیباگر atmel studio هم استفاده کنم که در اونجا متوجه شدوم متغیر ها به صورت درست تغییر میکنند ولی در عمل به صورت صحیح برنامه اجرا نمیشود.
      باتشکر.

      سلام من زیاد از اتمل استودیو سر در نمیارم ولی مشکل شما با دیلی هست . برای گرفتن دیتا از کیپد و نمایش روی سون سگمنت حداقل دیلی 5 میلی ثانیه نیاز دارین نه که 5 میکرو ثانیه

      دیدگاه


        #4
        پاسخ : مشکل در راه اندازی سون سگمنت مالتی پلکس با AVR

        باتشکر از مشارکت شما.
        ببینید وقفه ایجاد شده کلا ۱ میلی ثانیه هست در نتیجه اگه داخل چنین وقفه ای ۵ میلی ثانیه تاخیر ایجاد کنیم ،رفرش سون سگمنت ها به درستی اجرا نمیشود و پرپر میزند.

        دیدگاه


          #5
          پاسخ : مشکل در راه اندازی سون سگمنت مالتی پلکس با AVR

          نوشته اصلی توسط A.I.E نمایش پست ها
          باتشکر از مشارکت شما.
          ببینید وقفه ایجاد شده کلا ۱ میلی ثانیه هست در نتیجه اگه داخل چنین وقفه ای ۵ میلی ثانیه تاخیر ایجاد کنیم ،رفرش سون سگمنت ها به درستی اجرا نمیشود و پرپر میزند.
          با سلام
          مطلبی که دوستمون در پست بالایی گفتن نکته مهمی میباشد. 1ms زمان کمی برای روشن نگه داشتن هر سگمنت است. میتوانید یک متغیر کمکی به برنامه اضافه کنید و با هربار اجرای وقفه یک واحد به آن اضافه نمایید. پس از انکه به عدد مناسب (مثلا 5) رسید مقدار متغیر pointer را یکی اضافه کنید و متغیر کمکی را صفر نمایید.

          دیدگاه


            #6
            پاسخ : مشکل در راه اندازی سون سگمنت مالتی پلکس با AVR

            نوشته اصلی توسط evergreen نمایش پست ها
            با سلام
            مطلبی که دوستمون در پست بالایی گفتن نکته مهمی میباشد. 1ms زمان کمی برای روشن نگه داشتن هر سگمنت است. میتوانید یک متغیر کمکی به برنامه اضافه کنید و با هربار اجرای وقفه یک واحد به آن اضافه نمایید. پس از انکه به عدد مناسب (مثلا 5) رسید مقدار متغیر pointer را یکی اضافه کنید و متغیر کمکی را صفر نمایید.
            باتشکر از مشارکت شما.
            طبق گفته شما در روتین سرویس وقفه متغیری به صورت استاتیک تعریف شد و کل روتین رفرش سون سگمنت در صورت رسیدن مقدار این متغیر به پنج اجرا خواهد شد.اما تغییری در عملکرد دیده نمیشود.

            /*
            * Keyboard_7segment.c
            *
            * Created: 7/12/2021 11:39:10 PM
            * Author :
            * Chip : ATmega32
            D0 D1 D3
            --|--|--|--D4
            --|--|--|--D5
            --|--|--|--D6
            --|--|--|--D7

            PORTA0 -> a
            PORTA1 -> b
            PORTA2 -> c
            PORTA3 -> d
            PORTA4 -> e
            PORTA5 -> f
            PORTA6 -> g
            PORTA7 -> dp

            PORTB0 -> 7seg0
            PORTB1 -> 7seg1
            PORTB2 -> 7seg2
            PORTB3 -> 7seg3
            */


            #define F_CPU 1000000UL
            #include <avr/io.h>
            #include <util/delay.h>
            #include <avr/pgmspace.h>
            #include <avr/interrupt.h>
            #define TRUE 1
            #define FALSE 0
            #define NO_KEY_CODE 12


            //Global Variables
            unsigned const char seg_table[] = {0xF9, 0xA4, 0xB0, 0x99, 0x92,
            0x82, 0xF8, 0x80, 0x90, 0xC0,
            0xFF, 0xBF};
            unsigned const char key_table[] = {0x76, 0x75, 0x73,
            0x6E, 0x6D, 0x6B,
            0x5E, 0x5D, 0x5B,
            0x3E, 0x3D, 0x3B};
            volatile unsigned char disp_data[] = {11, 11, 11, 11};//Display initialize (- - - -)
            volatile unsigned char key_code=NO_KEY_CODE;


            int main(void)
            {
            //Variables
            unsigned char old_key_code = NO_KEY_CODE,temp_key_code;
            unsigned char i = 4;
            //7 segment port configuration
            DDRA |= (1 << DDA0) | (1 << DDA1) | (1 << DDA2) | (1 << DDA3) | (1 << DDA4) | (1 << DDA5) | (1 << DDA6) | (1 << DDA7);
            DDRB |= (1 << DDB0) | (1 << DDB1) | (1 << DDB2) | (1 << DDB3);
            //Timer/Counter configuration
            OCR0 = 124;
            TIMSK = (1 << OCIE0);//Enable compare match interrupt
            TCCR0 = (1 << WGM01) | (1 << CS01) ;//Timer clock:fclk_io/8 ; mode:CTC
            sei();
            while (1)
            {
            temp_key_code = key_code;
            if(temp_key_code != old_key_code){
            old_key_code = temp_key_code;
            if(temp_key_code != NO_KEY_CODE){
            disp_data[i] = temp_key_code;
            if (--i == 0xFF) i=4;
            }
            }
            }
            }


            ISR(TIMER0_COMP_vect){
            static unsigned char x20 = 0;
            static unsigned char x5 = 0;
            static unsigned char pointer = 0;
            unsigned char temp, i;
            //7 segment refresh routine
            if(++x5 == 5){
            x5 = 0;
            PORTB = 0;//Turn off all segments
            PORTA = seg_table[disp_data[pointer]];
            PORTB = (1 << pointer);
            if(++pointer == 4) pointer = 0;
            }
            //Keyboard scan routine
            if (++x20 == 20){
            x20 = 0;
            DDRD = (1 << DDD3) | (1 << DDD4) | (1 << DDD5) | (1 << DDD6);
            PORTD = (1 << PD0) | (1 << PD1) | (1 << PD2);
            _delay_us(5);//signal stabilization
            temp = (PIND & 0x07);
            DDRD = (1 << DDD0) | (1 << DDD1) | (1 << DDD2);
            PORTD = (1 << PD3) | (1 << PD4) | (1 << PD5) | (1 << PD6);
            _delay_us(5);
            temp |= (PIND & 0x78);
            for(i=0;i<12;i++){
            if(temp == key_table[i]){
            key_code = i;
            break;
            }
            else key_code = NO_KEY_CODE;
            }
            }
            }
            [FONT=Yekan][/FONT]

            دیدگاه


              #7
              پاسخ : مشکل در راه اندازی سون سگمنت مالتی پلکس با AVR

              باسلام.
              به صورت اتفاقی متوجه شدم که کیپد 3 در 4 آماده موجود در پروتیوس دارای ایراد بوده و بخاطر همین کار نمیکرده که با عوض کردن کیپد با پوش باتن مشکل حل شد.
              باتشکر از دوستانی که کمک کردند.

              دیدگاه

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