اطلاعیه

Collapse
No announcement yet.

مشکل دریافت رشته توسط ارتباط spi

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

    مشکل دریافت رشته توسط ارتباط spi

    سلام من پروژه ای دارم که باید 3 تا میکرو با هم در ارتباط باشن به این صورت که یک میکرو توسط ارتباط spi عدد سنسور دما رو به میکرو M1 میفرسته و میکروی دیگری عدد سنسور دمای دیگری رو با ارتباط twi به همون میکرو میفرسته و اون میکرو M1 با ارتباط یوزارت دو عدد رو به کامپیوتر میفرسته.
    من ابتدا هر پروتکل ارتباطی رو در برنامه های جداگانه نوشتم و درست دریافت و به کامپیوتر ارسال میکرد اما وقتی برنامه رو با 3 میکرو مینویسم و تلفیق میکنم توی دریافت عدد یک پروتکل دچار مشکل میشه یکی دو بار دریافت میگیره ولی دیگه نمیگیره و حتی عدد82 رو برای بار دوم به بعد 882 نشون میده.
    با این کد ارسال میکنم در ارتباط spi
    char l=strlen(str)+1;
    int i;
    for(i=0;i<l;i++){
    SPDR=str[i];
    while((SPSR&0x80)==0x00);
    delay_ms(10);

    و با این کد توی M1 دریافت میکنم
    for(i=0;i<5;i++){
    while((SPSR&0x80)==0x00);
    strspi[i]=SPDR;
    }

    نمی دونم چرا درست دریافت نمیکنه؟؟کسی در این مورد اطلاعاتی داره؟

    #2
    پاسخ : مشکل دریافت رشته توسط ارتباط spi

    نوشته اصلی توسط ftmthri نمایش پست ها
    سلام من پروژه ای دارم که باید 3 تا میکرو با هم در ارتباط باشن به این صورت که یک میکرو توسط ارتباط spi عدد سنسور دما رو به میکرو M1 میفرسته و میکروی دیگری عدد سنسور دمای دیگری رو با ارتباط twi به همون میکرو میفرسته و اون میکرو M1 با ارتباط یوزارت دو عدد رو به کامپیوتر میفرسته.
    من ابتدا هر پروتکل ارتباطی رو در برنامه های جداگانه نوشتم و درست دریافت و به کامپیوتر ارسال میکرد اما وقتی برنامه رو با 3 میکرو مینویسم و تلفیق میکنم توی دریافت عدد یک پروتکل دچار مشکل میشه یکی دو بار دریافت میگیره ولی دیگه نمیگیره و حتی عدد82 رو برای بار دوم به بعد 882 نشون میده.
    با این کد ارسال میکنم در ارتباط spi
    char l=strlen(str)+1;
    int i;
    for(i=0;i<l;i++){
    SPDR=str[i];
    while((SPSR&0x80)==0x00);
    delay_ms(10);

    و با این کد توی M1 دریافت میکنم
    for(i=0;i<5;i++){
    while((SPSR&0x80)==0x00);
    strspi[i]=SPDR;
    }

    نمی دونم چرا درست دریافت نمیکنه؟؟کسی در این مورد اطلاعاتی داره؟
    سلام
    چندتا سوال دارم. چرا برای هر دوی میکروکنترلرها از یک پروتکل استفاده نمیکنید؟ خوب میشه از طریق SPI یا TWI بین چند دستگاه ارتباط برقرار کرد.
    وضعیت میکروکنترلرها از نظر مستر و اسلیو بودن به چه شکلیه؟
    ضمنا برای قرار دادن کد حتما و حتما از تگ CPP استفاده کنید. توی نوار بالایی ویرایشگر متن انجمن تگ ها رو میبینید.

    دیدگاه


      #3
      پاسخ : مشکل دریافت رشته توسط ارتباط spi

      نوشته اصلی توسط hossein.m98 نمایش پست ها
      سلام
      چندتا سوال دارم. چرا برای هر دوی میکروکنترلرها از یک پروتکل استفاده نمیکنید؟ خوب میشه از طریق SPI یا TWI بین چند دستگاه ارتباط برقرار کرد.
      وضعیت میکروکنترلرها از نظر مستر و اسلیو بودن به چه شکلیه؟
      ضمنا برای قرار دادن کد حتما و حتما از تگ CPP استفاده کنید. توی نوار بالایی ویرایشگر متن انجمن تگ ها رو میبینید.
      خب صورت پروژه اینطور تعریف شده و باید با دو ارتباط بفرستم... دوتایی ک مقدار سنسور رو میخونن مستر و اون میکرو M1 اسلیو هر دوتاس.
      اگ نیاز هست تا کد 3تا میکرو رو بفرستم؟
      جدیدترین ویرایش توسط ftmthri; ۰۴:۳۶ ۱۳۹۹/۰۲/۱۷.

      دیدگاه


        #4
        پاسخ : مشکل دریافت رشته توسط ارتباط spi

        نوشته اصلی توسط ftmthri نمایش پست ها
        خب صورت پروژه اینطور تعریف شده و باید با دو ارتباط بفرستم... دوتایی ک مقدار سنسور رو میخونن مستر و اون میکرو M1 اسلیو هر دوتاس.
        اگ نیاز هست تا کد 3تا میکرو رو بفرستم؟
        در مورد مستر و اسلیو بودن هم اجباری وجود داره؟ به نظر من بهتره اون میکروکنترلری که رأس کار قرار داره مستر باشه. اینطوری کنترل ارتباطات راحتتر میشه.
        ظاهرا ارتباط SPI به مشکل خورده، نه؟ SPI میکروکنترلر AVR در حالت slave به طوریه که اگر یک بار میکروکنترلر توسط پایه ss در ارتباط قرار بگیره و بعد ss یک بشه (یعنی میکروکنترلر از ارتباط خارج بشه)، سخت افزار SPI به حالت پیش فرض بر میگرده و باید برای ارتباط بعدی دوباره پیکر بندی بشه. به این نکته توجه کردید توی کدتوت؟

        دیدگاه


          #5
          پاسخ : مشکل دریافت رشته توسط ارتباط spi

          نوشته اصلی توسط hossein.m98 نمایش پست ها
          در مورد مستر و اسلیو بودن هم اجباری وجود داره؟ به نظر من بهتره اون میکروکنترلری که رأس کار قرار داره مستر باشه. اینطوری کنترل ارتباطات راحتتر میشه.
          ظاهرا ارتباط SPI به مشکل خورده، نه؟ SPI میکروکنترلر AVR در حالت slave به طوریه که اگر یک بار میکروکنترلر توسط پایه ss در ارتباط قرار بگیره و بعد ss یک بشه (یعنی میکروکنترلر از ارتباط خارج بشه)، سخت افزار SPI به حالت پیش فرض بر میگرده و باید برای ارتباط بعدی دوباره پیکر بندی بشه. به این نکته توجه کردید توی کدتوت؟
          این برنامه میکرویی که با spi داده ارسال میکنه:
            u[FONT=Yekan]nsigned int read_adc(unsigned char adc_input)[/FONT]{
          ADMUX=adc_input | (0x40&0xff);
          delay_ms(10);
          ADCSRA|=0x40;
          while ((ADCSRA & 0x10)==0);
          ADCSRA|=0x10;
          return ADCW;
          }


          void spi(unsigned char str[]){
          char l=strlen(str)+1;
          int i;
          for(i=0;i<l;i++){
          SPDR=str[i];
          while((SPSR&0x80)==0x00);
          delay_ms(10);
          }
          }
          void main(void)
          {
          float Temp=0;


          ADMUX=0x40&0xff;
          ADCSRA=0x87;


          DDRA.0=0;


          DDRB=0xB0;
          PORTB=0;
          SPCR=0x51;
          SPSR=0x00;


          #asm("sei")
          lcd_init(16);


          while (1)
          {
          Temp= read_adc(0);
          Temp=(Temp*5)/1023;
          Temp=Temp*100;
          ftoa(Temp,1,str);
          [FONT=Yekan] [/FONT]
          PORTB.4=0;
          spi(str);
          PORTB.4=1;
          delay_ms(500);

          }
          }





          اینم برنامه میکروM1:
            [FONT=Yekan]//spi
          [/FONT]unsigned char strspi[6];
          int i=0;


          void spi(void){

          for(i=0;i<5;i++){
          while((SPSR&0x80)==0x00);
          strspi[i]=SPDR;
          }
          delay_ms(500);
          [FONT=Yekan]}[/FONT]


          //twi
          unsigned char strtwi[6];
          int j=0;


          void twi_init (void)
          {
          TWCR=0x04; //enable twi
          TWAR=0xC2; //slave address
          TWCR=0xC4; //set TWINT, TWEN, TWEA ///TWCR=0xC5
          }

          void twi_wait (void)
          {
          while ((TWCR&0x80) == 0);
          }

          void twi (void)
          {


          for(j=0;j<5;j++)
          {
          if(j==4)
          TWCR=0x84;
          else
          TWCR=0xC4;
          twi_wait();
          strtwi[j]=TWDR;
          }
          TWCR=0x84;
          delay_ms(500);
          [FONT=Yekan] }[/FONT]







          void main(void)
          {
          //spi
          DDRB=0x40;
          SPCR=0x41;
          SPSR=0x00;




          //usart
          UCSRA=0x00;
          UCSRB=0x08;
          UCSRC=0x86;
          UBRRH=0x00;
          UBRRL=0x33;


          twi_init();
          lcd_init(16);


          while (1)
          {

          //twi
          twi();
          puts(strtwi);


          //spi
          spi();
          puts(strspi);


          delay_ms(1000);


          }
          [FONT=Yekan]}[/FONT]


          اینم برنامه میکرویی که باTWI داده میفرسته:
            [FONT=Yekan]unsigned char str[];[/FONT]

          unsigned int read_adc(unsigned char adc_input)
          {
          ADMUX=adc_input | (0x40&0xff);
          delay_ms(10);
          ADCSRA|=0x40;
          while ((ADCSRA & 0x10)==0);
          ADCSRA|=0x10;
          return ADCW;
          }
          /////////////////////////////////////
          void twi_init(void){
          TWSR=0x00;
          TWBR=0xC0;
          TWCR=0x04;
          }
          /////////////////////////////////////
          void start(void){
          TWCR |= 0xA0;
          while((TWCR&0x80)==0);
          }
          /////////////////////////////////////
          void twi_write(unsigned char str[]){
          char l=strlen(str)+1;
          char i;
          for(i=0;i<l;i++){
          TWDR=str[i];
          TWCR |= 0x80;
          while((TWCR&0x80)==0);
          delay_ms(10);
          }
          }
          /////////////////////////////////////
          void twi_write_ads(char data){
          TWDR=data;
          TWCR |= 0x80;
          while((TWCR&0x80)==0);
          }
          /////////////////////////////////////
          void stop(void){
          TWCR |= 0x90;
          TWCR &= 0xD4;
          }
          /////////////////////////////////////
          char ADDR;
          void main(void)
          {
          float T=0;
          ADMUX=0x40&0xff;
          ADCSRA=0x87;


          DDRB.0=0;
          ADDR=0xC2;


          twi_init();


          #asm("sei")
          lcd_init(16);


          while (1)
          {

          start();
          twi_write_ads(ADDR|0x00);
          delay_ms(1);
          T= read_adc(0);
          T=T/4;
          ftoa(T,1,str);


          lcd_clear();
          lcd_puts(str);
          delay_ms(100);


          twi_write(str);
          stop();
          delay_ms(500);
          }
          [FONT=Yekan]}[/FONT]

          دیدگاه


            #6
            پاسخ : مشکل دریافت رشته توسط ارتباط spi

            نوشته اصلی توسط hossein.m98 نمایش پست ها
            در مورد مستر و اسلیو بودن هم اجباری وجود داره؟ به نظر من بهتره اون میکروکنترلری که رأس کار قرار داره مستر باشه. اینطوری کنترل ارتباطات راحتتر میشه.
            ظاهرا ارتباط SPI به مشکل خورده، نه؟ SPI میکروکنترلر AVR در حالت slave به طوریه که اگر یک بار میکروکنترلر توسط پایه ss در ارتباط قرار بگیره و بعد ss یک بشه (یعنی میکروکنترلر از ارتباط خارج بشه)، سخت افزار SPI به حالت پیش فرض بر میگرده و باید برای ارتباط بعدی دوباره پیکر بندی بشه. به این نکته توجه کردید توی کدتوت؟
            چطور میشه میکرو M1 مشتر باشه وقتی داره دریافت میکنه؟ و اون دوتا اسلیو باشه وقتی دارن داده ارسال میکنن؟
            توی صورت پروژه اینطوره که میکرو M1 حتما داده ها رو از اون دوتا دریافت کنه و به کامپیوتر بفرسته با یوزارت.
            اینم صورت پروژه هست

            دیدگاه


              #7
              پاسخ : مشکل دریافت رشته توسط ارتباط spi

              نوشته اصلی توسط ftmthri نمایش پست ها
              چطور میشه میکرو M1 مشتر باشه وقتی داره دریافت میکنه؟ و اون دوتا اسلیو باشه وقتی دارن داده ارسال میکنن؟
              توی صورت پروژه اینطوره که میکرو M1 حتما داده ها رو از اون دوتا دریافت کنه و به کامپیوتر بفرسته با یوزارت.
              اینم صورت پروژه هست
              http://drive.google.com/file/d/1O6ug...ew?usp=sharing
              ربطی به ارسال و دریافت نداره! تنها فرق مستر با اسلیو اینه که مستر شروع کننده ارتباط هستش و کلاک همزمان سازی ارتباط رو تولید میکنه. توی سمت اسلیو کافیه داده رو داخل رجیستر داده قرار بدید، با شروع ارتباط داده منتقل میشه و مستر دریافت میکنه. توی ارتباط SPI، همزمان داده های دو طرف با هم مبادله میشه. یعنی داده رجیستر مستر به رجیستر اسلیو منتقل میشه، و داده رجیستر اسلیو به رجیستر مستر.
              البته تبادل داده در TWI یا همون I2C کمی فرق داره و همزمان ارسال و دریافت نداریم.

              دیدگاه


                #8
                پاسخ : مشکل دریافت رشته توسط ارتباط spi

                نوشته اصلی توسط hossein.m98 نمایش پست ها
                ربطی به ارسال و دریافت نداره! تنها فرق مستر با اسلیو اینه که مستر شروع کننده ارتباط هستش و کلاک همزمان سازی ارتباط رو تولید میکنه. توی سمت اسلیو کافیه داده رو داخل رجیستر داده قرار بدید، با شروع ارتباط داده منتقل میشه و مستر دریافت میکنه. توی ارتباط SPI، همزمان داده های دو طرف با هم مبادله میشه. یعنی داده رجیستر مستر به رجیستر اسلیو منتقل میشه، و داده رجیستر اسلیو به رجیستر مستر.
                البته تبادل داده در TWI یا همون I2C کمی فرق داره و همزمان ارسال و دریافت نداریم.
                خب یعنی توی تعریف رجیسترا وثباتاش اگ جای اسلیو و مستر رو برای spi جابجا کنم بنظرتون مکشلم حل میشه؟ کد ها رو دیدید؟ توی نحوه ارسال و دریافت مشکلی نیست؟

                دیدگاه


                  #9
                  پاسخ : مشکل دریافت رشته توسط ارتباط spi

                  نوشته اصلی توسط ftmthri نمایش پست ها
                  خب یعنی توی تعریف رجیسترا وثباتاش اگ جای اسلیو و مستر رو برای spi جابجا کنم بنظرتون مکشلم حل میشه؟ کد ها رو دیدید؟ توی نحوه ارسال و دریافت مشکلی نیست؟
                  نحوه ارسال که به نظر میاد مشکلی نداره، فقط اون موردی که درباره ی پایه SS گفتم در نظر گرفته نشده. این عین نوشته دیتاشیت هستش، برای میکروکنترلری که در مد slave کار میکنه:
                  .Note that the SPI logic will be reset once the SS pin is driven high
                  شما باید بعد از اینکه ارتباط تموم شد و SS میکروکنترلر slave یک شد، یک بار دیگه دوباره SPI رو تنظیم کنید.

                  دیدگاه


                    #10
                    پاسخ : مشکل دریافت رشته توسط ارتباط spi

                    نوشته اصلی توسط hossein.m98 نمایش پست ها
                    نحوه ارسال که به نظر میاد مشکلی نداره، فقط اون موردی که درباره ی پایه SS گفتم در نظر گرفته نشده. این عین نوشته دیتاشیت هستش، برای میکروکنترلری که در مد slave کار میکنه:
                    .Note that the SPI logic will be reset once the SS pin is driven high
                    شما باید بعد از اینکه ارتباط تموم شد و SS میکروکنترلر slave یک شد، یک بار دیگه دوباره SPI رو تنظیم کنید.
                    ببخشید چطور باید این کار رو بکنم؟ و مد رو چطور باید تغییر بدم؟
                    فقط یه چیز رو متوجه نشدم اینکه اگر توی میکروی spi وقتی قرار نیست فرستنده باشه چجوری رشته رو کاراکتر به کاراکتر توی ثبات spdr قرار بدیم؟؟

                    دیدگاه


                      #11
                      پاسخ : مشکل دریافت رشته توسط ارتباط spi

                      نوشته اصلی توسط ftmthri نمایش پست ها
                      ببخشید چطور باید این کار رو بکنم؟ و مد رو چطور باید تغییر بدم؟
                      فقط یه چیز رو متوجه نشدم اینکه اگر توی میکروی spi وقتی قرار نیست فرستنده باشه چجوری رشته رو کاراکتر به کاراکتر توی ثبات spdr قرار بدیم؟؟
                      فعلا اون قضیه کی master باشه و کی slave رو بذارید کنار!
                      ببنید وقتی توی SPI، دستگاه master بخواد با یک slave داده رد و بد کنه، پایه SS اون slave رو صفر میکنه. slave با صفر شدن SS اش متوجه میشه master با اون کار داره و داده بعدی که روی خط MOSI قرار میگیره رو باید ذخیره کنه. همزمان با این کار، داده خودش رو هم روی خط MISO قرار میده. وقتی کار master با اون slave تموم بشه، SS اون رو یک میکنه. با این کار اگر داده ای روی خط باشه، slave ای که SS اون یک شده باشه دیگه داده روی خط رو ذخیره نمیکنه، خودشم چیزی روی خط نمیذاره. حالا هر تعداد slave داشته باشیم، به همون تعداد، در دستگاه master پایه برای کنترل slave ها در نظر بگیریم.
                      وقتی یک میکروکنترلر AVR توی حالت slave باشه، SS اون ورودی میشه. خوب طبق اون چیزی که گفتم، با صفر شدن SS میکروکنترلر میفهمه master با اون کار داره. با پایان ارتباط اگر master پایه SS میکروکنترلر ما رو یک کنه، طبق گفته دیتاشیت، واحد SPI به حالت اولیه اش بر میگرده. پس برای ارتباط بعدی لازمه که SPI دوباره پیکر بندی بشه. کد شما این قسمت پیکربندی دوباره رو نداره! اینو بهش اضافه کنید، احتمالا درست میشه.
                      جدیدترین ویرایش توسط hossein.m98; ۱۶:۲۲ ۱۳۹۹/۰۲/۱۷.

                      دیدگاه


                        #12
                        پاسخ : مشکل دریافت رشته توسط ارتباط spi

                        نوشته اصلی توسط hossein.m98 نمایش پست ها
                        فعلا اون قضیه کی master باشه و کی slave رو بذارید کنار!
                        ببنید وقتی توی SPI، دستگاه master بخواد با یک slave داده رد و بد کنه، پایه SS اون slave رو صفر میکنه. slave با صفر شدن SS اش متوجه میشه master با اون کار داره و داده بعدی که روی خط MOSI قرار میگیره رو باید ذخیره کنه. همزمان با این کار، داده خودش رو هم روی خط MISO قرار میده. وقتی کار master با اون slave تموم بشه، SS اون رو یک میکنه. با این کار اگر داده ای روی خط باشه، slave ای که SS اون یک شده باشه دیگه داده روی خط رو ذخیره نمیکنه، خودشم چیزی روی خط نمیذاره. حالا هر تعداد slave داشته باشیم، به همون تعداد، در دستگاه master پایه برای کنترل slave ها در نظر بگیریم.
                        وقتی یک میکروکنترلر AVR توی حالت slave باشه، SS اون ورودی میشه. خوب طبق اون چیزی که گفتم، با صفر شدن SS میکروکنترلر میفهمه master با اون کار داره. با پایان ارتباط اگر master پایه SS میکروکنترلر ما رو یک کنه، طبق گفته دیتاشیت، واحد SPI به حالت اولیه اش بر میگرده. پس برای ارتباط بعدی لازمه که SPI دوباره پیکر بندی بشه. کد شما این قسمت پیکربندی دوباره رو نداره! اینو بهش اضافه کنید، احتمالا درست میشه.
                        خب درسته حرفتون ولی اگ مشکل این بود باید توی برنامه ای ک من با دوتا میکرو نوشتم فقط برایspi این مشکل بوجود میومد ولی درست کار میکنه فقط وقتی 3 میکرو عه میکنم برنامه رو و ارتباطtwi هم بهش اضافه میشه اشتباه میشه.

                        دیدگاه


                          #13
                          پاسخ : مشکل دریافت رشته توسط ارتباط spi

                          نوشته اصلی توسط ftmthri نمایش پست ها
                          خب درسته حرفتون ولی اگ مشکل این بود باید توی برنامه ای ک من با دوتا میکرو نوشتم فقط برایspi این مشکل بوجود میومد ولی درست کار میکنه فقط وقتی 3 میکرو عه میکنم برنامه رو و ارتباطtwi هم بهش اضافه میشه اشتباه میشه.
                          شما میکروکنترلر اصلی رو در هر دو ارتباط به صورت slave راه اندازی کردید، از اون بدتر از روش سرکشی برای در یافت داده استفاده کردید. تازه از delay هم استفاده کردید که من اصلا نمیفهمم چه قصدی از گذاشتنش داشتید! با این اوصاف احتمال تداخل هست. بهتره میکروکنترلر اصلی در هر دو رابط master باشه که خودش مدیریت و زمان بندی ارتباط رو به عهده بگیره و هم این که از وقفه برای دریافت اطلاعات استفاده بشه.
                          برای دریافت داده در رابط SPI وقتی تو مد master هستید، کافیه برای هر بایت داده که میخوایید دریافت کنید، یکبار SPDR رو با یک داده دلخواه مثل صفر مقدار دهی کنید تا رابط شروع به تبادل دیتا کنه. توی سمت slave هم کافیه داده به SPDR داده بشه و منتظر باشید تا پرچم SPIF یک بشه. به محض یک شدن پرچم، داده بعدی در SPDR قرار بگیره و همین روند ادامه پیدا کنه تا همه داده ها ارسال بشن و باز دوباره همین مراحل برای ارسال بسته بعدی داده ها تکرار بشه.

                          دیدگاه


                            #14
                            پاسخ : مشکل دریافت رشته توسط ارتباط spi

                            نوشته اصلی توسط hossein.m98 نمایش پست ها
                            شما میکروکنترلر اصلی رو در هر دو ارتباط به صورت slave راه اندازی کردید، از اون بدتر از روش سرکشی برای در یافت داده استفاده کردید. تازه از delay هم استفاده کردید که من اصلا نمیفهمم چه قصدی از گذاشتنش داشتید! با این اوصاف احتمال تداخل هست. بهتره میکروکنترلر اصلی در هر دو رابط master باشه که خودش مدیریت و زمان بندی ارتباط رو به عهده بگیره و هم این که از وقفه برای دریافت اطلاعات استفاده بشه.
                            برای دریافت داده در رابط SPI وقتی تو مد master هستید، کافیه برای هر بایت داده که میخوایید دریافت کنید، یکبار SPDR رو با یک داده دلخواه مثل صفر مقدار دهی کنید تا رابط شروع به تبادل دیتا کنه. توی سمت slave هم کافیه داده به SPDR داده بشه و منتظر باشید تا پرچم SPIF یک بشه. به محض یک شدن پرچم، داده بعدی در SPDR قرار بگیره و همین روند ادامه پیدا کنه تا همه داده ها ارسال بشن و باز دوباره همین مراحل برای ارسال بسته بعدی داده ها تکرار بشه.
                            ممنون از راهنماییتون

                            دیدگاه

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