اطلاعیه

Collapse
No announcement yet.

اتصال eeprom خارجی و آی سی ساعت به Xmega

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

    اتصال eeprom خارجی و آی سی ساعت به Xmega

    خسته نباشید
    میشه لطفا کمک کنید معادل رجیستر ها در قطعه کد زیر در Xmega چیست ؟

    کد:
    	switch(type) {
    		case I2C_START:  // Send Start Condition
    		TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
    		break;
    		case I2C_DATA:   // Send Data with No-Acknowledge
    		TWCR = (1 << TWINT) | (1 << TWEN);
    		break;
    		case I2C_DATA_ACK: // Send Data with Acknowledge
    		TWCR = (1 << TWEA) | (1 << TWINT) | (1 << TWEN);
    		break;
    		case I2C_STOP:   // Send Stop Condition
    		TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
    		return 0;
    	}
    	// Wait for TWINT flag set on Register TWCR
    	while (!(TWCR & (1 << TWINT)));
    	// Return TWI Status Register, mask the prescaller bits (TWPS1,TWPS0)
    	return (TWSR & 0xF8);
    کد مربوطه TWI می باشد . برای مثال رجیستر TWSR معادل آن بر روی پورت E بصورت زیر است .
    TWIE_MASTER_STATUS = TWSR

    یا اینکه لطفا بفرمائید چطور پیدا کنم ؟
    - به دنبال فرصت عمري تباه کردم ! فرصت جواني ام بود من اشتباه کردم .

    #2
    پاسخ : معادل رجیستر های Mega در Xmega

    کد بالایی رو بی خیال شدم و رفتم دنبال کد های دیگه . متاسفانه چیز شسته رفته ای برای Atmel Studio اونم بزبان C++ نبود . یا من پیدا نکردم .

    کدی رو که استاد کی نژاد در سایت knowledgeplus.ir قرار دادند رو نیز دانلود کردم ولی فکر کنم بخاطر IAR بودنش نتونستم باهاش کار کنم و با خطاهای زیادی روبروی شدم

    یه کدی پیدا کردم برای کار با آی سی ساعت DS1307 این کد داره کار می کنه ولی یکی دو تا مشکل هست که اگر میشه لطفا کمک نمائید .

    1 - نرخ ارسال و دریافت TWI رو باید روی چه عددی بزارم . 100000 یا 400000 یا عدد دیگه ای ؟
    2 - نمی دونم برای چی این کد بگیر نگیر داره یه بار می خونه 5 بار نمی خونه ؟!

    کد مربوطه
    کد:
    //--------------------------
    #define CPU_SPEED 16000000
    #define BAUDRATE  200000
    #define TWI_BAUD(F_SYS, F_TWI) ((F_SYS / (2 * F_TWI)) - 5)
    #define TWI_BAUDSETTING TWI_BAUD(CPU_SPEED, BAUDRATE)
    
    #define RTC_SLAVE_ADDRESS 0xD0 ; // already shifted !!!!
    
    
    TWI_t * rtc = &TWIE; //port
    
    //uint8_t twitest[7]={0x05, 0x06, 0x07, 0x08, 0x25, 0x45, 0x65}; // only some test bytes
    
    void twi_init(TWI_t * twiname){
    
    	
    	twiname->MASTER.CTRLB = TWI_MASTER_SMEN_bm;
    	twiname->MASTER.BAUD = TWI_BAUDSETTING;
    	twiname->MASTER.CTRLA = TWI_MASTER_ENABLE_bm;
    	twiname->MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
    
    
    	return;
    }
    
    
    void twi_write_rtc(TWI_t *twiname, uint8_t *writeData){
    
    	uint8_t i;
    	
    	twiname->MASTER.ADDR = RTC_SLAVE_ADDRESS; // write to RTC
    	while(!(twiname->MASTER.STATUS&TWI_MASTER_WIF_bm));
    	twiname->MASTER.DATA = 0x00;    // write word addr
    	while(!(twiname->MASTER.STATUS&TWI_MASTER_WIF_bm));
    	for(i=0;i<7;i++)
    	{   // write date and time
    		twiname->MASTER.DATA =writeData[i];
    		while(!(twiname->MASTER.STATUS&TWI_MASTER_WIF_bm));
    		fcpu_delay_ms(10);
    	}
    
    
    	return;
    }
    
    void twi_read_rtc(TWI_t *twiname, uint8_t *readData){
    	// read from RTC
    	uint8_t i;
    	uint8_t address = RTC_SLAVE_ADDRESS;
    
    	address |= 0x01;
    	twiname->MASTER.ADDR = RTC_SLAVE_ADDRESS;
    	while(!(twiname->MASTER.STATUS&TWI_MASTER_WIF_bm));
    	twiname->MASTER.DATA = 0x00;    // write word addrpointer first
    	twiname->MASTER.ADDR = address;  // send read command
    	for(i=0;i<7;i++)
    	{   // read date and time
    		while(!(twiname->MASTER.STATUS&TWI_MASTER_RIF_bm));
    		readData[i] = twiname->MASTER.DATA;
    		fcpu_delay_ms(10);
    	}
    
    
    	return;
    }
    
    
    
    //--------------------------

    در تابع اصلی

    کد:
    	twi_init(rtc);

    برای خواندن ساعت و تاریخ
    کد:
    void Read_DS1307(void)
    {
    	uint8_t data[7];
    	// DS1307 Register Address
    	// Second: ds1307_addr[0]
    	// Minute: ds1307_addr[1]
    	// Hour : ds1307_addr[2]
    	// Day  : ds1307_addr[3]
    	// Date : ds1307_addr[4]
    	// Month : ds1307_addr[5]
    	// Year : ds1307_addr[6]
    	
    	twi_read_rtc(rtc,data);
    	ds1307_addr[0]=bcd2dec(data[0] & 0x7F);
    	ds1307_addr[1]=bcd2dec(data[1]);
    	if ((data[2] & 0x40) == 0x40)
    	{
    		hour_mode = HOUR_12;
    		ampm_mode=(data[2] & 0x20) >> 5;  // ampm_mode: 0-AM, 1-PM
    		ds1307_addr[2]=bcd2dec(data[2] & 0x1F);
    		} else {
    		hour_mode = HOUR_24;
    		ampm_mode=0;
    		ds1307_addr[2]=bcd2dec(data[2] & 0x3F);
    	}
    	ds1307_addr[3]=bcd2dec(data[3]);
    	ds1307_addr[4]=bcd2dec(data[4]);
    	ds1307_addr[5]=bcd2dec(data[5]);
    	ds1307_addr[6]=bcd2dec(data[6]);
    }
    برای نوشتن ساعت و تاریخ

    کد:
    void Write_DS1307(void)
    {
    	// Make sure we enable the Oscillator control bit CH=0 on Register 0x00
    	ds1307_addr[0]=ds1307_addr[0] & 0x7F;
    	twi_write_rtc(rtc,ds1307_addr);
    }
    مشکل در توابع زیر مجموعه مثل bcd2dec یا غیره نیست چون این توابع در پروژه های دیگه ای کاملا تست شده اند . ممنون :redface:
    - به دنبال فرصت عمري تباه کردم ! فرصت جواني ام بود من اشتباه کردم .

    دیدگاه


      #3
      پاسخ : معادل رجیستر های Mega در Xmega

      دوستان چند روز درگیر هستم با این پروژه . لطفا کسی راهنمایی کنه .
      من ارتباط با ds1307 و 24c512 رو نیاز دارم که قبلا توی mega انجام می دادم و راحت بود ولی حالا توی xmega سخت شده .
      تکنولوزی پیشرفت کرده بجای اینکه راحت تر بشه سخت تر شده . :surprised:

      با C++ در Atmel studio 6.1 کار میکنم . کد های پست قبلی رو برای ds1307 دارم که مشکلی دارن .
      کد های زیر رو هم برای eeprom . که کار نمی کنه .

      اومدم کلا یه پروژه جدا درست کردم برای تست eeprom کد زیر که درست کار نمی کنه . :angry:

      کد:
      /*
      * GLtest06DetailTest.cpp
      *
      * Created: 2014/03/03 03:38:48 ب.ظ
      * Author: User
      */
      
      
      #include <avr/io.h>
      #include <stdlib.h>
      #include <stdio.h>
      #include <avr/interrupt.h>
      #include <string.h>
      #include <avr/pgmspace.h>
      #include <compat/twi.h>
      #include "RoseLCD.h"
      
      LCD_Rose LCD;
      
      //delay functions
      #define F_CPU 16000000UL 		//Your clock speed in Hz
      
      //-----------------delays---------------------------------------------------------
      #define LOOP_CYCLES 8 				//Number of cycles that the loop takes
      
      #define fcpu_delay_us(num) delay_int(num/(LOOP_CYCLES*(1/(F_CPU/1000000.0))))
      #define fcpu_delay_ms(num) delay_int(num/(LOOP_CYCLES*(1/(F_CPU/1000.0))))
      
      void delay_int(unsigned long delay);
      //--------------------------------------------------------------------------------
      
      
      // System Clocks initialization
      void system_clocks_init(void)
      {
      	OSC.XOSCCTRL=0XCB;
      	OSC.CTRL = 9;
      	while(!(OSC.STATUS & 8));
      	CCP = 0xD8;
      	CLK.CTRL = 0x03;
      	CLK.PSCTRL = 0x01;
      }
      
      void delay_int(unsigned long delay)
      {
      	while(delay--) asm volatile("nop");
      };
      
      
      
      
      #define CPU_SPEED 16000000
      #define BAUDRATE  400000
      #define TWI_BAUD(F_SYS, F_TWI) ((F_SYS / (2 * F_TWI)) - 5)
      #define TWI_BAUDSETTING TWI_BAUD(CPU_SPEED, BAUDRATE)
      
      
      void twi_init()
      {
       
      	TWIE.MASTER.CTRLC = TWI_MASTER_SMEN_bm;
      	TWIE.MASTER.CTRLB = TWI_MASTER_SMEN_bm;
      	TWIE.MASTER.BAUD = TWI_BAUDSETTING;
      	TWIE.MASTER.CTRLA = TWI_MASTER_ENABLE_bm;
      	TWIE.MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
      }
      
      
      void eeprom_bytewrite(unsigned int SlaveAddress,unsigned int MemoryAddress,char Data)
      {
      	TWIE_MASTER_STATUS|=0x01;
      	SlaveAddress=SlaveAddress<<1;
      	TWIE_MASTER_ADDR=SlaveAddress;
      	while(!(TWIE_MASTER_STATUS & 0x40));
      	TWIE_MASTER_DATA=MemoryAddress;
      	while(!(TWIE_MASTER_STATUS & 0x40));
      	TWIE_MASTER_DATA=Data;
      	while(!(TWIE_MASTER_STATUS & 0x40));
      	TWIE_MASTER_CTRLC=0x03;
      }
      
      char eeprom_byteread(unsigned int SlaveAddress,unsigned int MemoryAddress)
      {
      	TWIE_MASTER_STATUS|=0x01;//force idle
      	SlaveAddress=SlaveAddress<<1;
      	TWIE_MASTER_ADDR=SlaveAddress;
      	while(!(TWIE_MASTER_STATUS & 0x40));
      	TWIE_MASTER_DATA=MemoryAddress;
      	while(!(TWIE_MASTER_STATUS & 0x40));
      	TWIE_MASTER_ADDR=(SlaveAddress | 1);
      	while(!(TWIE_MASTER_STATUS & 0xC0));
      	return TWIE_MASTER_DATA;
      	TWIE_MASTER_CTRLC=0x06;
      }
      
      char data = 0;
      
      
      int main(void)
      {
      	system_clocks_init();
      	LCD.LCDinit();
      	LCD.LCDcursorOFF();
      	
      	
      	
      	twi_init();
      	
      	
      	
      	
      	while(1)
      	{
      		LCD.LCDclr();
      		
      		eeprom_bytewrite(0x50,1,66);
      		
      		fcpu_delay_ms(1000);
      		
      		data = eeprom_byteread(0x50,1);
      		
      		LCD.LCDGotoXY(0,0);
      		LCD.LCDsendChar(data);
      		fcpu_delay_ms(1000);
      		LCD.LCDGotoXY(5,0);
      		LCD.LCDsendChar(65);
      		fcpu_delay_ms(1000);
      
      	}
      }
      هر دو آی سی ساعت و حافظه روی پورت E هستند و مقاومت pullup نیز دارند . آی سی ها را نیز عوض کرده و تست کرده ام . نتیجه یکسان بود .
      - به دنبال فرصت عمري تباه کردم ! فرصت جواني ام بود من اشتباه کردم .

      دیدگاه


        #4
        پاسخ : معادل رجیستر های Mega در Xmega

        عملکرد رجیسترهای بخش TWI برای سری mega با رجیسترهای XMEGA دارای تفاوت های زیادی است و بیت های معادل در رجیستر TWCR در بیش از یک رجیستر قرار دارند. برای کاربرد شما با توجه به وقت گیر بودن تحلیل جزئیات کدهایی که قرار داده اید (که در حال حاضر به دلیل محدودیت وقت مقدور نیست) پیشنهاد می کنم بر اساس همان کتابخانه AVR1308 عمل کنید که نمونه کدی هم که قرار داده ام، بر اساس همین کتابخانه است. در غیر اینصورت باید بصورت دقیق جزئیات رجیسترهای این بخش را مطالعه کنید تا بتوانید بر مبنای رجیسترها به تحلیل نمونه کدها بپردازید. در این رابطه توجه کنید کتابخانه های قرار داده شده توسط Atmel در صورت include کردن avr_compiler.h برای IAR و GCC بصورت مشترک قابل استفاده هستند و از این جهت مشکلی وجود ندارد.
        اوژن: به معنای افکننده و شکست دهنده است
        دانایی، توانایی است-Knowledge is POWER
        برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
        وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
        قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
        اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
        ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

        دیدگاه


          #5
          اتصال eeprom خارجی و آی سی ساعت به Xmega

          با عرض سلام خدمت همه دوستان و اساتید گرامی
          راستش چند روزی هست که در یک پروژه نیاز مبرمی به اتصال 24c512 و آی سی ساعت DS1307 بر روی یک خط TWI به میکرو Xmega مدل ATXMega128A1 دارم و تمام کد های موجود در انجمن Xmega رو بررسی کردم تست کردم . به www.avrfreaks نیز سر زدم توی گوگل هم سرچ کردم .

          متاسفانه تمام کدهایی که پیدا کردم یا مشکل داشتن و ناقص بودن یا با زبانهای متفاوتی نوشته شده بودند و با اطلاعات ناقص من امکان تغییرشون میسر نشد که نشد :angry:

          این پست رو با هدف این زدم که هم مشکل خودم حل بشه و هم اینکه دوستان همکاری کنند که در پایان این نتیجه حاصل بشه :

          اتصال میکرو Xmega به آی سی ساعت DS1307 و EEprom 24C512 توسط زبان C++ در Atmel Studio

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

          دیدگاه


            #6
            پاسخ : اتصال eeprom خارجی و آی سی ساعت به Xmega

            برای اولین پست کدی رو که برای راه اندازی EEProm اماده کردم اینجا آوردم و لی این کد انگار مشکلی داره چون جواب نمی ده . لطفا راهنمایی فرمائید .

            کد:
            #include <avr/io.h>
            #include <stdlib.h>
            #include <stdio.h>
            #include <avr/interrupt.h>
            #include <string.h>
            #include <avr/pgmspace.h>
            #include <compat/twi.h>
            
            
            
            #include "RoseLCD.h"
            
            
            
            
            #define SLAVE_ADDRESS  0x50
            #define CPU_SPEED    16000000
            #define BAUDRATE	100000
            #define TWI_BAUD(F_SYS, F_TWI) ((F_SYS / (2 * F_TWI)) - 5)
            #define TWI_BAUDSETTING TWI_BAUD(CPU_SPEED, BAUDRATE)
            #define eeprom_read 10
            #define eeprom_write 11
            
            
            
            LCD_Rose LCD;
            
            
            //delay functions
            #define F_CPU 16000000UL 		//Your clock speed in Hz
            
            //-----------------delays---------------------------------------------------------
            #define LOOP_CYCLES 8 				//Number of cycles that the loop takes
            
            #define fcpu_delay_us(num) delay_int(num/(LOOP_CYCLES*(1/(F_CPU/1000000.0))))
            #define fcpu_delay_ms(num) delay_int(num/(LOOP_CYCLES*(1/(F_CPU/1000.0))))
            
            void delay_int(unsigned long delay)
            {
            	while(delay--) asm volatile("nop");
            }
            //--------------------------------------------------------------------------------
            
            // System Clocks initialization
            void system_clocks_init(void)
            {
            	OSC.XOSCCTRL=0XCB;
            	OSC.CTRL = 9;
            	while(!(OSC.STATUS & 8));
            	CCP = 0xD8;
            	CLK.CTRL = 0x03;
            	CLK.PSCTRL = 0x01;
            }
            
            
            void eeprom_bytewrite(unsigned int SlaveAddress,unsigned int MemoryAddress,char Data)
            {
            	TWIE_MASTER_STATUS|=0x01;
            	SlaveAddress=SlaveAddress<<1;
            	TWIE_MASTER_ADDR=SlaveAddress;
            	while(!(TWIE_MASTER_STATUS & 0x40));
            	TWIE_MASTER_DATA=MemoryAddress;
            
            	while(!(TWIE_MASTER_STATUS & 0x40));
            	TWIE_MASTER_DATA=Data;
            	while(!(TWIE_MASTER_STATUS & 0x40));
            	TWIE_MASTER_CTRLC=0x03;
            	 fcpu_delay_ms(20);
            }
            
            char eeprom_byteread(unsigned int SlaveAddress,unsigned int MemoryAddress)
            {
            	TWIE_MASTER_STATUS|=0x01;//force idle
            	SlaveAddress=SlaveAddress<<1;
            	TWIE_MASTER_ADDR=SlaveAddress;
            	while(!(TWIE_MASTER_STATUS & 0x40));
            	TWIE_MASTER_DATA=MemoryAddress;
            	while(!(TWIE_MASTER_STATUS & 0x40));
             
            	TWIE_MASTER_ADDR=(SlaveAddress | 1);
            	while(!(TWIE_MASTER_STATUS & 0xC0));
            	return TWIE_MASTER_DATA;
            	TWIE_MASTER_CTRLC=0x06;
            	 fcpu_delay_ms(20);
            }
            
            
            
            int main(void)
            {
            	char result ;
            	char WriteDataChar = 0x67;
            	unsigned int Address = 123;
            	
            	system_clocks_init();
            	
            	LCD.LCDinit();
            	LCD.LCDclr();
            	LCD.LCDGotoXY(0,0);
            	LCD.LCDstring("Ds1307");
            	LCD.LCDGotoXY(0,1);
            	LCD.LCDstring("Test");
            	fcpu_delay_ms(1000);
            	
            
            	
            			TWIE.MASTER.CTRLA = TWI_MASTER_INTLVL_LO_gc |TWI_MASTER_RIEN_bm |TWI_MASTER_WIEN_bm |TWI_MASTER_ENABLE_bm;
            			TWIE.MASTER.BAUD = 0x95;
            			TWIE.MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
            	
            	
            	sei();
            	
            	while(1)
            	{
            		LCD.LCDclr();
            		LCD.LCDGotoXY(0,0);
            		LCD.LCDstring("write");
            		
            		LCD.LCDGotoXY(10,0);
            		LCD.LCDsendChar(WriteDataChar);
            		
            		eeprom_bytewrite(SLAVE_ADDRESS,Address,WriteDataChar);
            		
            		fcpu_delay_ms(1000);
            
            		
            		LCD.LCDGotoXY(0,1);
            		LCD.LCDstring("Read");
            		
            		result = eeprom_byteread(SLAVE_ADDRESS,Address);
            		LCD.LCDGotoXY(10,1);
            		LCD.LCDsendChar(result);
            		
            		fcpu_delay_ms(1000);
            	}
            }
            - به دنبال فرصت عمري تباه کردم ! فرصت جواني ام بود من اشتباه کردم .

            دیدگاه


              #7
              پاسخ : اتصال eeprom خارجی و آی سی ساعت به Xmega

              یکی از بهترین منابع برای راه اندازی twi راه اندازی است که توسط خود اتمل ارائه شده. avr1308 را جست و جو کنید.

              دیدگاه


                #8
                پاسخ : اتصال eeprom خارجی و آی سی ساعت به Xmega

                به دلیل مشابهت سوال با تاپیک دیگری که تشکیل داده اید، محتوای دو تاپیک ترکیب شد.
                از روی کدی که قرار داده اید، اینطور به نظر می رسد که به datasheet چیپ های مورد استفاده توجه نشده است. اساسی ترین مسئله این است که برای دسترسی به 24c512 باید دو بایت را به عنوان آدرس حافظه برای eeprom ارسال کنید. در حالیکه در متن کد تنها یک بایت به عنوان آدرس فرستاده شده که مناسب شماره های با ظرفیت پائین تر مانند 24c16 است. همچنین در تابع خواندن از eeprom نحوه نوشتن return باعث می شود که دستورات بعد از آن اجرا نشود. توصیه من به شما این است که با صرف وقت و دقت کافی، محتوای datasheet مربوط به XMEGA و 24c512 و ds1307 را مطالعه کنید تا سریعتر به نتیجه برسید. ضمنا در جزئیات کد، ارتباطی با ds1307 ایجاد نشده است (در حالیکه پیغام روی LCD چنین ارتباطی را اعلام می کند).
                اوژن: به معنای افکننده و شکست دهنده است
                دانایی، توانایی است-Knowledge is POWER
                برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
                وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
                قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
                اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
                ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

                دیدگاه


                  #9
                  پاسخ : اتصال eeprom خارجی و آی سی ساعت به Xmega

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

                  فقط یه سوال که درست متوجه نشدم در راهنمای شماره 8054 Atmel که راجع به TWI هست راجه به ACK و NACK صحبت شده که من خیلی از این موضوع چیزی دستگیرم نشد . اگر ممکن هست در این مورد یه توضیحی بدید . ممنون
                  - به دنبال فرصت عمري تباه کردم ! فرصت جواني ام بود من اشتباه کردم .

                  دیدگاه


                    #10
                    پاسخ : اتصال eeprom خارجی و آی سی ساعت به Xmega

                    سوال پست قبلی هنوز مطرح هست .؟؟

                    بعد از خواندن دیتاشیت و Manual میکرو های xmega و 24c512 و 8054 Atmel دیدم نسبت به این ارتباط TWI خیلی باز شد .
                    الان دیگه دقیقا می دونم چه اتفاقاتی داره می افته . و رجیسترهای مربوطه رو هم کاملا می شناسم که انشاال.. در روز های آتی در یک زمان مناسب اطلاعات کامل آنرا در همین پست برای استفاده عمومی قرار می دهم .

                    در حال حاضر کدی آماده نمودم که متاسفانه هنوز جواب درستی ندارد که چون نمی توانم در چند ساعت آینده روی آن کار کنم گفتم کد رو در اینجا قرار بدم تا اگر از دوستان و اساتید کسی به اینجا سر زد توی این مدت و با یک نگاه متوجه ایراد آن شد . کارم سریعتر راه بیافتد . ممنون

                    کد تست TWI برای اتصال 24c512 به Xmega

                    کد:
                    #include <avr/io.h>
                    #include <stdlib.h>
                    #include <stdio.h>
                    #include <avr/interrupt.h>
                    #include <string.h>
                    #include <avr/pgmspace.h>
                    #include <compat/twi.h>
                    #include "RoseLCD.h"
                    
                    
                    
                    
                    #define EEPROM_ID  0xA0   
                    
                    #define CPU_SPEED 16000000
                    #define BAUDRATE  100000
                    #define TWI_BAUD(F_SYS, F_TWI) ((F_SYS / (2 * F_TWI)) - 5)
                    #define TWI_BAUDSETTING TWI_BAUD(CPU_SPEED, BAUDRATE)
                    
                    
                    LCD_Rose LCD;
                    
                    
                    //delay functions
                    #define F_CPU 16000000UL 		//Your clock speed in Hz
                    
                    //-----------------delays---------------------------------------------------------
                    #define LOOP_CYCLES 8 				//Number of cycles that the loop takes
                    
                    #define fcpu_delay_us(num) delay_int(num/(LOOP_CYCLES*(1/(F_CPU/1000000.0))))
                    #define fcpu_delay_ms(num) delay_int(num/(LOOP_CYCLES*(1/(F_CPU/1000.0))))
                    
                    void delay_int(unsigned long delay);
                    //--------------------------------------------------------------------------------
                    
                    
                    // System Clocks initialization
                    void system_clocks_init(void)
                    {
                    	OSC.XOSCCTRL=0XCB;
                    	OSC.CTRL = 9;
                    	while(!(OSC.STATUS & 8));
                    	CCP = 0xD8;
                    	CLK.CTRL = 0x03;
                    	CLK.PSCTRL = 0x01;
                    }
                    
                    void delay_int(unsigned long delay)
                    {
                    	while(delay--) asm volatile("nop");
                    };
                    
                    
                    
                    void twi_init()
                    {
                    	TWIE.MASTER.CTRLB = 0x07;
                    	TWIE.MASTER.BAUD = TWI_BAUDSETTING;
                    	TWIE.MASTER.CTRLA = 0x08;
                    	TWIE.MASTER.STATUS = 0x01;
                    }
                    
                    
                    void eeprom_bytewrite(unsigned int SlaveAddress,unsigned int MemoryAddress,char Data)
                    {
                    	unsigned char addressL = MemoryAddress & 0xff;
                    	unsigned char addressH = MemoryAddress >> 8;
                    	
                    	TWIE_MASTER_STATUS|= 0x01; //force idle
                    	SlaveAddress=SlaveAddress<<1;
                    	TWIE_MASTER_ADDR=SlaveAddress;
                    	while(!(TWIE_MASTER_STATUS & 0x40));
                    	TWIE_MASTER_DATA=addressH;
                    	while(!(TWIE_MASTER_STATUS & 0x40));
                    	TWIE_MASTER_DATA=addressL;
                    	while(!(TWIE_MASTER_STATUS & 0x40));
                    	TWIE_MASTER_DATA=Data;
                    	while(!(TWIE_MASTER_STATUS & 0x40));
                    	fcpu_delay_ms(10);
                    	TWIE_MASTER_CTRLC=0x03;
                    }
                    
                    char eeprom_byteread(unsigned int SlaveAddress,unsigned int MemoryAddress)
                    {
                    	unsigned char addressL = MemoryAddress & 0xff;
                    	unsigned char addressH = MemoryAddress >> 8;
                    	char Data = 0;
                    	TWIE_MASTER_STATUS|=0x01; //force idle
                    	SlaveAddress = SlaveAddress<<1;
                    	TWIE_MASTER_ADDR = SlaveAddress;
                    	while(!(TWIE_MASTER_STATUS & 0x40));
                    	TWIE_MASTER_DATA=addressH;
                    	while(!(TWIE_MASTER_STATUS & 0x40));
                    	TWIE_MASTER_DATA=addressL;
                    	while(!(TWIE_MASTER_STATUS & 0x40));
                    	TWIE_MASTER_CTRLC = 0x01;
                    	TWIE_MASTER_ADDR=(SlaveAddress | 1);
                    	while(!(TWIE_MASTER_STATUS & 0xC0));
                    	Data = TWIE_MASTER_DATA;
                    	TWIE_MASTER_CTRLC=0x03;
                    	fcpu_delay_ms(10);
                    	return Data;
                    }
                    
                    
                    //-------------------------------
                    
                    int main(void)
                    {
                    	char result = 0;
                    	int addressMemory = 65;
                    	char WriteDataChar = 67;
                    	
                    	
                    	system_clocks_init();
                    	LCD.LCDinit();
                    	LCD.LCDcursorOFF();
                    	
                    	twi_init();
                    	
                    	
                    	LCD.LCDinit();
                    	LCD.LCDclr();
                    	LCD.LCDGotoXY(0,0);
                    	LCD.LCDstring("EEprom");
                    	LCD.LCDGotoXY(0,1);
                    	LCD.LCDstring("Test");
                    	fcpu_delay_ms(1000);
                    	
                    	
                    	while(1)
                    	{
                    		
                    		LCD.LCDclr();
                    		LCD.LCDGotoXY(0,0);
                    		LCD.LCDstring("write");
                    		
                    
                    
                    		eeprom_bytewrite(EEPROM_ID,addressMemory,WriteDataChar);
                    		
                    		LCD.LCDGotoXY(10,0);
                    		LCD.LCDsendChar(WriteDataChar);
                    		
                    		fcpu_delay_ms(1000);
                    		
                    		
                    		LCD.LCDGotoXY(0,1);
                    		LCD.LCDstring("Read");
                    		
                    		result = eeprom_byteread(EEPROM_ID,addressMemory);
                    		
                    		
                    		LCD.LCDGotoXY(10,1);
                    		LCD.LCDsendChar(result);
                    		
                    		
                    		fcpu_delay_ms(1000);
                    	}
                    }
                    البته بعد از چند ساعتی دوباره خودم روش کار می کنم . و نتیجه رو اعلام می کنم . ممنون
                    - به دنبال فرصت عمري تباه کردم ! فرصت جواني ام بود من اشتباه کردم .

                    دیدگاه


                      #11
                      پاسخ : اتصال eeprom خارجی و آی سی ساعت به Xmega

                      با سلام

                      نحوه اسال داده برای اسلیو تو کدتون مشخص نیست، به نظرم شما بعد از اینکه آدرس رو میدید کامند ارسال رو نمیفرستید (رجیستر twcr). و اینکه بنظر کامند شروع رو هم نمیفرستید (البته این روال تو سری مگا هست). من تو سری مگا برای ارسال آدرس از این تابع استفاده میکنم فکر میکنم کلیت کار باید یکی باشه:

                      کد:
                      bool I2cSendAddr(uint8_t SlaveAddr)
                      {
                      	if((GetI2cStatus()==START)||(GetI2cStatus()==REP_START))
                      	{
                      		DATA_REG=SlaveAddr;
                      		CMD=CMD_TRANS;
                      		while (!READY); // wait
                      		if(STATUS==MT_SLA_ACK)
                      			return(1);
                      	}		
                      	else 
                      			return(0); // return 1 if found; 0 otherwise
                      }
                      مورد بعدی اینکه مقدار رجیستر وضعیت بعد از ارسال آدرس با دیتا فرق میکنه البته شاید تو ایکسمگا یکیه ولی بعید میدونم اینو چک کنید، شما جفتش رو 0x40 گرفتید.

                      دیدگاه


                        #12
                        پاسخ : اتصال eeprom خارجی و آی سی ساعت به Xmega

                        ممنون از پاسختون دوست عزیز

                        نحوه اسال داده برای اسلیو تو کدتون مشخص نیست
                        مگه باید کد اسلیو رو هم مشخص میکردم . من دارم توی مد مستر کار می کنم و در واقع میکرو در حالت مستر قرار میگیره و باید روتین مستر رو اجرا کنم . اسلیو که در واقع همون آی سی حافظه میشه که خودش کار خودش رو بلده ! درست نمی گم ؟ oo:

                        مورد بعدی اینکه مقدار رجیستر وضعیت بعد از ارسال آدرس با دیتا فرق میکنه البته شاید تو ایکسمگا یکیه ولی بعید میدونم اینو چک کنید، شما جفتش رو 0x40 گرفتید
                        به نظرم شما بعد از اینکه آدرس رو میدید کامند ارسال رو نمیفرستید (رجیستر twcr). و اینکه بنظر کامند شروع رو هم نمیفرستید
                        نمی دونم چشم چک میکنم و بیشتر بررسی می کنم ببینم چی میشه . ممنونم از همکاریتون .
                        - به دنبال فرصت عمري تباه کردم ! فرصت جواني ام بود من اشتباه کردم .

                        دیدگاه


                          #13
                          پاسخ : اتصال eeprom خارجی و آی سی ساعت به Xmega

                          منظور من این بود که روند ارسال داده برای اسلیو مشخص نیست به عبارت دیگه با اونچه که تو ذهنم بود تطابق نداشت. من الان دیتا شیت xmega رو دیدم،مثله اینکه اصلا شکل کار تو اینجا خیلی با مگا فرق میکنه. ببخشید پست من رو نادیده بگیرید دوباره مثله اینکه خودمو نخود آش کردم.

                          دیدگاه


                            #14
                            پاسخ : اتصال eeprom خارجی و آی سی ساعت به Xmega

                            خواهش میکنم نه بی راهم نبود . راستش من خودم خیلی باهاش سر و کله زدم ولی برای امشب دیگه خسته شدم . فردا ادامه می دم . به نظرم رسید یه بار دیگه فایل IAR آقای دکتر رو بررسی کنم و با کد های خودم مطابقت بدم . ایشاال.. فردا دیگه این مشکل حل بشه . :agree:
                            - به دنبال فرصت عمري تباه کردم ! فرصت جواني ام بود من اشتباه کردم .

                            دیدگاه


                              #15
                              پاسخ : اتصال eeprom خارجی و آی سی ساعت به Xmega

                              سلام دوست عزیز
                              من برنامه کدویژنش رو دارم ولی فکر نکنم تو کامپایلرهای دیگه کار کنه. چون از توابع خودش برای ارتباط 2 سیمه استفاده میکنه
                              کد:
                              #include <twix.h>
                              #include <bcd.h>
                              
                              #define ds1307_addr 0xd0
                              
                              // Declare your global variables here
                              struct {
                                byte addr;
                                byte sec;
                                byte mint;
                                byte hour;
                                byte weekd;
                                byte day;
                                byte month;
                                byte year;
                                byte control;
                                }bcd_t_d,t_d,t_ds;
                              
                              char rtc_get()
                              {
                              char i,res,addr=0;
                              char *p1,*p2;
                              res=twi_master_trans(&twie_master,(ds1307_addr>>1),&addr,1,(byte*)&bcd_t_d+1,7);
                              p1=(byte*)&t_d;
                              p2=(byte*)&bcd_t_d;
                              for (i=0;i<8;i++) (*p1++=bcd2bin(*p2++));
                              return res;  
                              }
                              
                              char rtc_set_time(char hour,char mint,char sec)
                              {
                              char i;
                              char *p1,*p2;
                              p1=(byte*)&t_d;
                              p2=(byte*)&bcd_t_d;
                              for (i=0;i<8;i++) (*p2++=bin2bcd(*p1++));
                              bcd_t_d.addr=0;
                              bcd_t_d.hour=bin2bcd(hour);
                              bcd_t_d.mint=bin2bcd(mint);
                              bcd_t_d.sec=bin2bcd(sec);
                              return twi_master_trans(&twie_master,(ds1307_addr>>1),(byte*)&bcd_t_d,8,(byte*)&bcd_t_d+1,7);
                              } 
                              
                              char rtc_set_date(char weekd,char day,char month,char year)
                              {
                              char i;
                              char *p1,*p2;
                              //if (!rtc_get()) return 0;
                              p1=(byte*)&t_d;
                              p2=(byte*)&bcd_t_d;
                              for (i=0;i<8;i++) (*p2++=bin2bcd(*p1++));
                              bcd_t_d.addr=0;
                              bcd_t_d.weekd=bin2bcd(weekd);
                              bcd_t_d.day=bin2bcd(day);
                              bcd_t_d.month=bin2bcd(month);
                              bcd_t_d.year=bin2bcd(year);
                              return twi_master_trans(&twie_master,(ds1307_addr>>1),(byte*)&bcd_t_d,8,(byte*)&bcd_t_d+1,7);
                              }
                              شما فقط با bcd_t_d کار دارید.
                              زندگي را تو بساز ،
                              نه بدان ساز که سازند و پذيري بي حرف ،
                              زندگي يعني جنگ ، تو بجنگ ،
                              زندگي يعني عشق ، تو بدان عشق بورز.

                              دیدگاه

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