اطلاعیه

Collapse
No announcement yet.

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

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

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

    با تشکر دوست عزیز . بله چون از توابع خودش استفاده می کنه نمی دونم دقیقا جزئیات کار چی جوری هست .

    نوشته اصلی توسط مرد نامرئی

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

    دیدگاه


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

      سلامی دوباره به همگی :wow: :wow:

      بعد از کلی کلنجار رفتن با کد های مختلف و خوندن دیتاشیت و داکیومنت های اتمل و دیتاشیت میکرو و TWI و غیره ....

      کدی که نوشتم کار می کنه فقط من دیگه خسته شدم اگر کسی تونست کمک کنه . مشکل اینکه آدرس های بالای 255 رو به مشکل می خوره نمی دونم از write یا از read

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

      کد:
      #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  0x50    
      #define EEPROM_ADDR 0x00   
      
      
      #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;
      
      //-----------------delays---------------------------------------------------------
      #define LOOP_CYCLES 8 	//Number of cycles that the loop takes
      
      #define fcpu_delay_us(num) delay_int(num/(LOOP_CYCLES*(1/(CPU_SPEED/1000000.0))))
      #define fcpu_delay_ms(num) delay_int(num/(LOOP_CYCLES*(1/(CPU_SPEED/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.CTRLA = TWI_MASTER_INTLVL_LO_gc |TWI_MASTER_RIEN_bm |TWI_MASTER_WIEN_bm |TWI_MASTER_ENABLE_bm;
      	TWIE.MASTER.BAUD = TWI_BAUDSETTING;
      	TWIE.MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
      }
      
      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
      		if (TWIE.MASTER.STATUS == 0x01 )
      		{
      			TWIE.MASTER.CTRLC = 0x01;
      			SlaveAddress = EEPROM_ID<<1;
      			TWIE.MASTER.ADDR = SlaveAddress ;
      			while(!(TWIE.MASTER.STATUS & 0x43));
      			TWIE.MASTER.DATA = addressH;
      			fcpu_delay_ms(5);
      			while(!(TWIE.MASTER.STATUS & 0x43));
      			TWIE.MASTER.DATA = addressL;
      			fcpu_delay_ms(5);
      			while(!(TWIE.MASTER.STATUS & 0x43));
      			TWIE.MASTER.DATA = Data;
      			fcpu_delay_ms(2);
      			while(!(TWIE.MASTER.STATUS & 0x43));
      			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
      	
      		if (TWIE.MASTER.STATUS == 0x01 )
      		{
      			
      			TWIE.MASTER.CTRLC = 0x01;
      			
      			SlaveAddress = EEPROM_ID<<1;
      			
      			TWIE.MASTER.ADDR = SlaveAddress;
      			while(!(TWIE.MASTER.STATUS & 0x40));
      			TWIE.MASTER.DATA = addressH;
      			fcpu_delay_ms(3);
      			while(!(TWIE.MASTER.STATUS & 0x40));
      			TWIE.MASTER.DATA = addressL;
      			fcpu_delay_ms(3);
      			while(!(TWIE.MASTER.STATUS & 0x40));
      			TWIE.MASTER.CTRLC = 0x05;
      			TWIE.MASTER.ADDR = (SlaveAddress | 1);
      			while(!(TWIE.MASTER.STATUS & 0xC0));
      			Data = TWIE.MASTER.DATA;
      			TWIE.MASTER.CTRLC=0x07;
      			fcpu_delay_ms(10);
      		}
      	return Data;
      }
      
      
      int main(void)
      {
      	char result = 0;
      	unsigned int addressMemory = 255;
      	char WriteDataChar = 65;
      
      	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)
      	{
      		
      		eeprom_bytewrite(EEPROM_ID,addressMemory,WriteDataChar);
      		
      		LCD.LCDclr();
      		LCD.LCDGotoXY(0,0);
      		LCD.LCDstring("write");
      		LCD.LCDGotoXY(10,0);
      		LCD.LCDsendChar(WriteDataChar);
      		
      		fcpu_delay_ms(1000);
      
      		result = eeprom_byteread(EEPROM_ID,addressMemory);
      
      		LCD.LCDclr();
      		LCD.LCDGotoXY(0,1);
      		LCD.LCDstring("Read");
      		LCD.LCDGotoXY(10,1);
      		LCD.LCDsendChar(result);
      		
      		fcpu_delay_ms(1000);
      	}
      }
      :nice:

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

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

      دیدگاه


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

        بررسی کد شما نیاز به صرف زمان کافی دارد، اما چند مورد در همان بدو امر به نظر می رسد. مورد اول اینکه چرا در توابع نوشتن و خواندن یکجا عملیات and را با 0x43 و در جای دیگر با 0x40 انجام دادید. مورد بعدی تاخیر های زیادی است که در برنامه در نقاط مختلف قرار داده اید که اکثرا لازم نیست. در روتین خواندن از حافظه هم or کردن بجای برابری و برگشت مقدار در خارج از if درست به نظر نمی رسد. در هر صورت اگر موفق به رفع اشکال نشدید، در فرصت های بعدی با دقت بیشتری جزئیات برنامه را بررسی خواهم کرد.
        اوژن: به معنای افکننده و شکست دهنده است
        دانایی، توانایی است-Knowledge is POWER
        برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
        وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
        قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
        اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
        ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

        دیدگاه


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

          :applause:

          آقای دکتر مثل همیشه مشکل گشا شما بودید . :nice:

          ممنونم بخش حافظه مشکلش حل شد . کد زیر که الحمدال.. بدون مشکل کار می کند برای ارتباط میکرو xmega مدل ATXmega128A1 با آی سی حافظه سری مدل 24c512 می باشد .
          که البته در xmega های دیگر هم قابل استفاده خواهد بود فقط با تغییرات قسمت پورت مورد استفاده برای ارتباط سخت افزاری . چون در این کد ارتباط توسط پورت e انجام میشود .

          عنوان :
          راه اندازی آی سی حافظه 24c512 توسط میکروکنترولر xmega به وسیله نرم افزار Atmel Studio 6.1 و زبان C++

          کد کامل :
          کد:
          #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  0x50    // I2C 24AA128 EEPROM Device Identifier
          #define EEPROM_ADDR 0x00    // I2C 24AA128 EEPROM Device Address
          
          #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 SLAVE_ADDRESS  0x50
          #define eeprom_read 10
          #define eeprom_write 11
          
          LCD_Rose LCD;
          
          //-----------------delays---------------------------------------------------------
          #define LOOP_CYCLES 8 				//Number of cycles that the loop takes
          
          #define fcpu_delay_us(num) delay_int(num/(LOOP_CYCLES*(1/(CPU_SPEED/1000000.0))))
          #define fcpu_delay_ms(num) delay_int(num/(LOOP_CYCLES*(1/(CPU_SPEED/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.CTRLA = TWI_MASTER_INTLVL_LO_gc |TWI_MASTER_RIEN_bm |TWI_MASTER_WIEN_bm |TWI_MASTER_ENABLE_bm;
          	TWIE.MASTER.BAUD = TWI_BAUDSETTING;
          	TWIE.MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
          }
          
          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
          	if (TWIE.MASTER.STATUS == 0x01 )
          	{
          		TWIE.MASTER.CTRLC = 0x01;
          		SlaveAddress = EEPROM_ID<<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
          	
          	if (TWIE.MASTER.STATUS == 0x01 )
          	{
          		
          		TWIE.MASTER.CTRLC = 0x01;
          		SlaveAddress = EEPROM_ID<<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 = 0x05;
          		TWIE.MASTER.ADDR = (SlaveAddress | 1);
          		while(!(TWIE.MASTER.STATUS & 0xC0));
          		Data = TWIE.MASTER.DATA;
          		TWIE.MASTER.CTRLC=0x07;
          		fcpu_delay_ms(10);
          	}
          	return Data;
          }
          
          
          int main(void)
          {
          	char result = 0;
          	unsigned int addressMemory = 63251;
          	char WriteDataChar = 79;
          
          	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)
          	{
          		
          		eeprom_bytewrite(EEPROM_ID,addressMemory,WriteDataChar);
          		
          		LCD.LCDclr();
          		LCD.LCDGotoXY(0,0);
          		LCD.LCDstring("STATUS_WR");
          		LCD.LCDGotoXY(13,0);
          		LCD.LCDnum(TWIE.MASTER.STATUS);
          		
          		fcpu_delay_ms(1000);
          		
          		LCD.LCDclr();
          		LCD.LCDGotoXY(0,0);
          		LCD.LCDstring("write");
          		LCD.LCDGotoXY(10,0);
          		LCD.LCDsendChar(WriteDataChar);
          		
          		fcpu_delay_ms(1000);
          
          		LCD.LCDclr();
          		LCD.LCDGotoXY(0,0);
          		LCD.LCDstring("STATUS_Read");
          		LCD.LCDGotoXY(13,0);
          		LCD.LCDnum(TWIE.MASTER.STATUS);
          		fcpu_delay_ms(1000);
          		
          		result = eeprom_byteread(EEPROM_ID,addressMemory);
          
          		LCD.LCDclr();
          		LCD.LCDGotoXY(0,1);
          		LCD.LCDstring("Read");
          		LCD.LCDGotoXY(10,1);
          		LCD.LCDsendChar(result);
          		
          		
          		fcpu_delay_ms(1000);
          
          	}
          }
          کد تابع فعال سازی TWI
          کد:
          void twi_init()
          {
          	TWIE.MASTER.CTRLA = TWI_MASTER_INTLVL_LO_gc |TWI_MASTER_RIEN_bm |TWI_MASTER_WIEN_bm |TWI_MASTER_ENABLE_bm;
          	TWIE.MASTER.BAUD = TWI_BAUDSETTING;
          	TWIE.MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
          }
          کد تابع خواندن دیتا از حافظه 24c512
          کد:
          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
          	
          	if (TWIE.MASTER.STATUS == 0x01 )
          	{
          		
          		TWIE.MASTER.CTRLC = 0x01;
          		SlaveAddress = EEPROM_ID<<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 = 0x05;
          		TWIE.MASTER.ADDR = (SlaveAddress | 1);
          		while(!(TWIE.MASTER.STATUS & 0xC0));
          		Data = TWIE.MASTER.DATA;
          		TWIE.MASTER.CTRLC=0x07;
          		fcpu_delay_ms(10);
          	}
          	return Data;
          }
          کد نوشتن در حافظه 24c512
          کد:
          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
          	if (TWIE.MASTER.STATUS == 0x01 )
          	{
          		TWIE.MASTER.CTRLC = 0x01;
          		SlaveAddress = EEPROM_ID<<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;
          	}
          }
          - به دنبال فرصت عمري تباه کردم ! فرصت جواني ام بود من اشتباه کردم .

          دیدگاه


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

            خوب در ادامه می خوام برم سراغ آی سی ساعت . امیدوارم زیاد طول نکشه . لطفا اگر کسی کدی در این رابطه برای xmega داره . لطفا لینکی ، چیزی برام بزاره .
            پیشاپیش ممنون .
            هدف : ارتباط میکرو xmega با آی سی ساعت DS1307 توسط Atmel studio 6.1 و C++ می باشد .

            بعد از انجام این کار در یک پروژه تحت Atmel Studio کامل ارتباط 24c512 و ساعت ds1307 و همچنین lcd کاراکتری را یکجا برای دانلود قرار خواهم داد .
            - به دنبال فرصت عمري تباه کردم ! فرصت جواني ام بود من اشتباه کردم .

            دیدگاه


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

              دوستان این یک سری تابع هست مربوط به AT24C512 , DS1307 و ارتباط اونا با ATXmega128A1 . توابعی رو که بالای کد اومده و 10 عدد هستند رو فقط استفاده کنید و مابقی توابع داخلی هستند.
              این توابع با TWI کاری ندارند و به صورت نرم افزاری I2C رو شبیه سازی میکنن.
              کد:
              void I2C_Init();
              byte ReadByte_I2C(uint address);
              void WriteByte_I2C(uint address,byte data);
              uint ReadInt_I2C(uint Add);
              void WriteInt_I2C(uint Add,uint data);
              void rtc_init();
              void rtc_get_time(unsigned char *hour,unsigned char *minute,unsigned char *second);
              void rtc_get_date(unsigned char *day,unsigned char *month,unsigned char *year);
              void rtc_set_time(unsigned char hour,unsigned char min,unsigned char sec);
              void rtc_set_date(unsigned char date,unsigned char month,unsigned char year);
              
              #define SCLPORT			PORTE_OUT	// i2c clock port
              #define SCLDDR			PORTE_DIR	// i2c clock port direction
              #define SDAPORT			PORTE_OUT	// i2c data port
              #define SDADDR			PORTE_DIR	// i2c data port direction
              #define SDAPIN			PORTE_IN	// i2c data port input
              #define SCL				1		// i2c clock pin
              #define SDA				0		// i2c data pin
              #define READ			0x01	// I2C READ bit
              #define QDEL			_delay_us(5);
              #define HDEL			_delay_us(10);
              #define I2C_SDA_LO   cbi( SDAPORT, SDA);
              #define I2C_SDA_HI   sbi( SDAPORT, SDA);
              #define I2C_SCL_LO   cbi( SCLPORT, SCL);
              #define I2C_SCL_HI   sbi( SCLPORT, SCL);
              #define I2C_SCL_TOGGLE HDEL; I2C_SCL_HI; HDEL; I2C_SCL_LO;
              #define I2C_START    I2C_SDA_LO; QDEL; I2C_SCL_LO;
              #define I2C_STOP    HDEL; I2C_SCL_HI; QDEL; I2C_SDA_HI; HDEL;
              //------------------------------------------------------------------------------------------------------
              uint i2cPutbyte(byte b)
              {
              	int i;
              	
              	for (i=7;i>=0;i--)
              	{
              		if ( b & (1<<i) )
              		{
              			I2C_SDA_HI;
              		}
              		else
              		{
              			I2C_SDA_LO;			// address bit
              		}
              		I2C_SCL_TOGGLE;		// clock HI, delay, then LO
              	}
              
              	I2C_SDA_HI;					// leave SDL HI
              	// added
              	cbi(SDADDR, SDA);			// change direction to input on SDA line (may not be needed)
              	HDEL;
              	I2C_SCL_HI;					// clock back up
               	b = (SDAPIN) & (1<<SDA);	// get the ACK bit
              
              	HDEL;
              	I2C_SCL_LO;					// not really ??
              	sbi(SDADDR, SDA);			// change direction back to output
              	HDEL;
              	return (b == 0);			// return ACK value
              }
              //------------------------------------------------------------------------------------------------------
              byte i2cGetbyte(uint last)
              {
              	int i;
              	byte c,b = 0;
              		
              	I2C_SDA_HI;					// make sure pullups are ativated
              	cbi(SDADDR, SDA);			// change direction to input on SDA line (may not be needed)
              
              	for(i=7;i>=0;i--)
              	{
              		HDEL;
              		I2C_SCL_HI;				// clock HI
              	 	c = (SDAPIN) & (1<<SDA);
              		b <<= 1;
              		if(c) b |= 1;
              		HDEL;
                	I2C_SCL_LO;				// clock LO
              	}
              
              	sbi(SDADDR, SDA);			// change direction to output on SDA line
              
              	if (last)
              	{
              		I2C_SDA_HI;				// set NAK
              	}
              	else
              	{
              		I2C_SDA_LO;				// set ACK
              	}
              	I2C_SCL_TOGGLE;				// clock pulse
              	I2C_SDA_HI;					// leave with SDL HI
              	return b;					// return received byte
              }
              //------------------------------------------------------------------------------------------------------//************************
              void I2C_Init()
              {
              	sbi( SDADDR, SDA);			// set SDA as output
              	sbi( SCLDDR, SCL);			// set SCL as output
              	I2C_SDA_HI;					// set I/O state and pull-ups
              	I2C_SCL_HI;					// set I/O state and pull-ups
              }
              //----------------------------------------------------------------------
              //! Send a byte sequence on the I2C bus
              void i2cSend(byte device, byte subAddr, byte length, byte *data)
              {
              	I2C_START;   			// do start transition
              	i2cPutbyte(device); 		// send DEVICE address
              	i2cPutbyte(subAddr);		// and the subaddress
              
              	// send the data
              	while (length--)
              		i2cPutbyte(*data++);
              
              	I2C_SDA_LO;					// clear data line and
              	I2C_STOP;					// send STOP transition
              }
              //----------------------------------------------------------------------
              //! Send a byte sequence on the I2C bus
              void i2cSend2(byte device, uint subAddr, byte length, byte *data)
              {
              	I2C_START;   			// do start transition
              	i2cPutbyte(device); 		// send DEVICE address
              	i2cPutbyte((subAddr>>8)&0xFF);		// and the subaddress H
              	i2cPutbyte(subAddr&0xFF);		// and the subaddress L
              
              	// send the data
              	while (length--)
              		i2cPutbyte(*data++);	
              
              	I2C_SDA_LO;					// clear data line and
              	I2C_STOP;					// send STOP transition
              }
              //----------------------------------------------------------------------
              //! Retrieve a byte sequence on the I2C bus
              void i2cReceive(byte device, byte subAddr, byte length, byte *data)
              {
              	int j = length;
              	byte *p = data;
              
              	I2C_START;					// do start transition
              	i2cPutbyte(device);			// send DEVICE address
              	i2cPutbyte(subAddr);  		// and the subaddress
              	HDEL;
              	I2C_SCL_HI;   			// do a repeated START
              	I2C_START;					// transition
              
              	i2cPutbyte(device | READ);	// resend DEVICE, with READ bit set
              
              	// receive data bytes
              	while (j--)
              		*p++ = i2cGetbyte(j == 0);
              
              	I2C_SDA_LO;					// clear data line and
              	I2C_STOP;					// send STOP transition
              }
              //----------------------------------------------------------------------
              //! Retrieve a byte sequence on the I2C bus
              void i2cReceive2(byte device, uint subAddr, byte length, byte *data)
              {
              	int j = length;
              	byte *p = data;
              
              	I2C_START;					// do start transition
              	i2cPutbyte(device);			// send DEVICE address
              	i2cPutbyte((subAddr>>8)&0xFF);		// and the subaddress H
              	i2cPutbyte(subAddr&0xFF);		// and the subaddress L
              	HDEL;
              	I2C_SCL_HI;   			// do a repeated START
              	I2C_START;					// transition
              
              	i2cPutbyte(device | READ);	// resend DEVICE, with READ bit set
              
              	// receive data bytes
              	while (j--)
              		*p++ = i2cGetbyte(j == 0);	
              
              	I2C_SDA_LO;					// clear data line and
              	I2C_STOP;					// send STOP transition
              }
              //----------------------------------------------------------------------
              byte ReadByte_I2C(uint address)
              {
              	byte s = SREG;
              	cli();
              	byte buf[5]="",p;
              	buf[0]=0;buf[1]=0;
              	i2cReceive2(0xA0,address,1,buf);
              	_delay_ms(1);
              	SREG = s;
              	return buf[0];
              }
              //----------------------------------------------------------------------
              void WriteByte_I2C(uint address,byte data)
              {
              	char s = SREG;
              	cli();
              	byte buf[5]="";
              	buf[0]=data;
              	buf[1]=0;
              	i2cSend2(0xA0,address,1,buf);
              	_delay_ms(10);
              	SREG = s;
              }
              //--------------------------------------------------------------------------------------------------
              struct SHighLow
              {
                unsigned char H;
                unsigned char L;
              };
              //--------------------------------------------------------------------------------------------------
              union UHL
              {
                struct SHighLow shl;
                uint d;
              };
              //--------------------------------------------------------------------------------------------------
              void WriteInt_I2C(uint Add,uint data)
              {
                union UHL uhliw;
                uhliw.d=data;
                WriteByte_I2C(Add,uhliw.shl.H);
                WriteByte_I2C(Add+1,uhliw.shl.L);
              }
              //--------------------------------------------------------------------------------------------------
              uint ReadInt_I2C(uint Add)
              {
                union UHL uhlir;
                uhlir.shl.H=ReadByte_I2C(Add);
                uhlir.shl.L=ReadByte_I2C(Add+1);
                return uhlir.d;
              }
              //----------------------------------------------------------------------
              void rtc_init()
              {
              	unsigned char buf[5];
              	buf[0]=0;buf[1]=0;
              	i2cSend(0xD0,7,1,buf);
              }
              //----------------------------------------------------------------------
              unsigned char bcd2bin(unsigned char x)
              {
                return (x >> 4) * 10 + (x & 0x0f);
              }
              //----------------------------------------------------------------------
              unsigned char bin2bcd(unsigned char x)
              {
                return (x%10) | ((x/10) << 4);
              }
              //----------------------------------------------------------------------
              void rtc_get_time(unsigned char *hour,unsigned char *minute,unsigned char *second)
              {
              	unsigned char buf[5]="";
              	char s = SREG;
              	cli();
              	rtc_init();
              	buf[0]=0;
              	buf[1]=0;
              	buf[2]=0;	
              	i2cReceive(0xD0,0,3,buf);
              	*second=bcd2bin(buf[0]);
              	*minute=bcd2bin(buf[1]);
              	*hour=bcd2bin(buf[2]);
              	SREG = s;
              }
              //----------------------------------------------------------------------
              void rtc_get_date(unsigned char *day,unsigned char *month,unsigned char *year)
              {
              	unsigned char buf[5]="";
              	char s = SREG;
              	cli();	
              	rtc_init();
              	buf[0]=0;
              	buf[1]=0;
              	buf[2]=0;	
              	i2cReceive(0xD0,4,3,buf);
              	*day=bcd2bin(buf[0]);
              	*month=bcd2bin(buf[1]);
              	*year=bcd2bin(buf[2]);
              	SREG = s;
              }
              //----------------------------------------------------------------------
              void rtc_set_time(unsigned char hour,unsigned char min,unsigned char sec)
              {
              	unsigned char buf[5]={0,0,0,0,0};
              	char s = SREG;
              	cli();	
              	rtc_init();
              	buf[0] = bin2bcd(sec);
              	buf[1] = bin2bcd(min);
              	buf[2] = bin2bcd(hour);
              	i2cSend(0xD0,0,3,buf);
              	SREG = s;
              }
              //----------------------------------------------------------------------
              void rtc_set_date(unsigned char date,unsigned char month,unsigned char year)
              {
              	unsigned char buf[5]={0,0,0,0,0};
              	char s = SREG;
              	cli();	
              	rtc_init();
              	buf[0] = bin2bcd(date);
              	buf[1] = bin2bcd(month);
              	buf[2] = bin2bcd(year);
              	i2cSend(0xD0,4,3,buf);
              	SREG = s;
              }

              دیدگاه


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

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

                دیدگاه


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

                  :applause:
                  خیلی ممنونی دوست عزیز بخش آی سی ساعتش رو چک کردم و البته با یه کوچولو تغییر در نوع متغییر ها که با کمپایلرم سازگار بشن . ok بود و به راحتی بخش ساعت رو در مدار راه اندازی کردم و البته کد های دیگرش هم بسیار عالی هستند که من دیگه استفاده نکردم .

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

                  دیدگاه


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

                    فقط باید بگم که این کد برای استفاده از آی سی ساعت سرعتش بنظرم یکم کند بود چون همین برنامه رو در Mega با توابع دیگه ای (مخصوص مگا ) باهاش کار کرده بودم با سرعت بالاتری ساعت و تاریخ رو می خوند و نمایش می داد ولی در اینجا فقط همین توابع جایگزین شدند و سرعتش یکم تاخیر داره .
                    ولی کار می کنه و مشکلی نیست . ممنون
                    - به دنبال فرصت عمري تباه کردم ! فرصت جواني ام بود من اشتباه کردم .

                    دیدگاه


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

                      در توابعی که دوستمون داده اند قسمت آی سی ساعت رو با اینکه اطلاعات را از آی سی ساعت می خواند و می نویسد میشه استفاده کرد و در برنامه خیلی مشکل بوجود نمی آورد .

                      باید بگویم که قبلا در توابع مگا هر زمان که نیاز به خواندن ساعت و تاریخ بود در همان لحظه این کار را انجام می دادم و بسایر سریع این کار انجام میشد ولی در این توابع سرعت آنقدر کند است که من با استفاده از تایمری در فواصل زمانی مختلف فقط ساعت را می خوانم (تاریخ فقط روزی یکبار) و در متغییری ذخیره می کنم و در هر زمانی که نیاز دارم فقط متغییر را می خوانم .
                      به این شکل استفاده کردم و بخش ساعت قابل قبول شد ولی بخش حافظه در این توابع آنقدر کند عمل می کند که در پروژه های صنعتی قابل استفاده نیست
                      oo: :eek:
                      خواستم از توابع خودم که در پست های قبلی آورده ام استفاده کنم ولی مشکلی دارم که بشرح زیر است :

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

                      فعال بعضی از کد ها رو قرار میدم اگر دوستان تونستن راهنمایی کنن اگر نه بفرمائید تمام کد های مشکل دار را بصورت یک پروژه کامل بگذارم .

                      فعال سازی اینتراپت ها و تایمر ها

                      کد:
                      	// Interupt Enable
                      	// External interrupt 0 on PF7, enable pullup, sence falling edge
                      	PORTF.PIN7CTRL = PORT_ISC_RISING_gc;
                      	PORTF.INT0MASK = PIN7_bm;
                      	
                      	// External interrupt 0 on PF4, enable pullup, sence falling edge
                      	PORTF.PIN4CTRL = PORT_ISC_RISING_gc;
                      	PORTF.INT1MASK = PIN4_bm;
                      	PORTF.INTCTRL = (PORTF.INTCTRL & (~(PORT_INT1LVL_gm | PORT_INT0LVL_gm))) | PORT_INT1LVL_LO_gc | PORT_INT0LVL_LO_gc; // PORT_INT0LVL_LO_gc | PORT_INT1LVL_LO_gc ;
                      	
                      	// Times Enable
                      	TCF1_PER = 7811;   // (F Crystal) 16.000.000 / (TC_CLKSEL_DIV1024_gc) 16000000 / 1024 = 15625 (1s) / 2 = 7812 = 500 ms
                      	TCF1_INTCTRLA = TC_ERRINTLVL_OFF_gc | TC_OVFINTLVL_LO_gc;
                      	TCF1_CTRLA = TC_CLKSEL_DIV1024_gc;
                      	
                      	// Times Enable
                      	TCD1_PER = 15624;   // (F Crystal) 16.000.000 / (TC_CLKSEL_DIV1024_gc) 16000000 / 1024 = 15625 (1s)
                      	TCD1_INTCTRLA = TC_ERRINTLVL_OFF_gc | TC_OVFINTLVL_LO_gc;
                      	TCD1_CTRLA = TC_CLKSEL_DIV1024_gc;
                      	
                      	PMIC_CTRL = PMIC_LOLVLEN_bm;
                      	
                      	cli();
                      	sei();
                      کد مربوط به توابع خواندن و نوشتن
                      کد:
                      void TWI_Hard_init()
                      {
                      	TWID.MASTER.CTRLA = TWI_MASTER_INTLVL_LO_gc |TWI_MASTER_RIEN_bm |TWI_MASTER_WIEN_bm |TWI_MASTER_ENABLE_bm;
                      	TWID.MASTER.BAUD = TWI_BAUDSETTING;
                      	TWID.MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
                      }
                      
                      void TWI_eeprom_bytewrite(unsigned int SlaveAddress,unsigned int MemoryAddress,char Data)
                      {
                      	
                      	unsigned char addressL = MemoryAddress & 0xff;
                      	unsigned char addressH = MemoryAddress >> 8;
                      	
                      	TWID.MASTER.STATUS  = 0x01; //force idle
                      	
                      	TWID.MASTER.CTRLC = 0x01;
                      	SlaveAddress = EEPROM_ID<<1;
                      	TWID.MASTER.ADDR = SlaveAddress ;
                      	while(!(TWID.MASTER.STATUS & 0x40));
                      	TWID.MASTER.DATA = addressH;
                      	while(!(TWID.MASTER.STATUS & 0x40));
                      	TWID.MASTER.DATA = addressL;
                      	while(!(TWID.MASTER.STATUS & 0x40));
                      	TWID.MASTER.DATA = Data;
                      	while(!(TWID.MASTER.STATUS & 0x40));
                      	fcpu_delay_ms(10);
                      	TWID.MASTER.CTRLC = 0x03;
                      	
                      	
                      }
                      
                      char TWI_eeprom_byteread(unsigned int SlaveAddress,unsigned int MemoryAddress)
                      {
                      	
                      	unsigned char addressL = MemoryAddress & 0xff;
                      	unsigned char addressH = MemoryAddress >> 8;
                      	char Data = 0;
                      	TWID.MASTER.STATUS = 0x01; // force idle
                      	
                      	TWID.MASTER.CTRLC = 0x01;
                      	fcpu_delay_ms(3);
                      	SlaveAddress = EEPROM_ID<<1;
                      	TWID.MASTER.ADDR = SlaveAddress;
                      	while(!(TWID.MASTER.STATUS & 0x40));
                      	TWID.MASTER.DATA = addressH;
                      	while(!(TWID.MASTER.STATUS & 0x40));
                      	TWID.MASTER.DATA = addressL;
                      	while(!(TWID.MASTER.STATUS & 0x40));
                      	TWID.MASTER.CTRLC = 0x05;
                      	TWID.MASTER.ADDR = (SlaveAddress | 1);
                      	while(!(TWID.MASTER.STATUS & 0xC0));
                      	Data = TWID.MASTER.DATA;
                      	TWID.MASTER.CTRLC=0x07;
                      	fcpu_delay_ms(10);
                      
                      	
                      	return Data;
                      }
                      - به دنبال فرصت عمري تباه کردم ! فرصت جواني ام بود من اشتباه کردم .

                      دیدگاه


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

                        در مورد کند بودن توابع مخصوصا خواندن و نوشتن در حافظه ، بهترین راه حل غیر فعال کردن اینتراپتها قبل از فراخوانی و فعال کردن آنها بعد از اتمام تابع هست.
                        مثلا شما میخواید 1000 بایت در eeprom بنویسید. اگر اینتراپتها فعال باشند این کار زمان زیادی طول میکشد. اما در صورتی که اینتراپتها غیر فعال باشند به سرعت انجام میگیرد.
                        کد:
                        char s = SREG;
                        cli();
                        
                        .
                        .
                        .
                        
                        SREG = s;

                        دیدگاه


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

                          خیلی ممنون از شما .
                          راستی باید بگم دقیقا همین کد
                          کد:
                          cli();
                          رو از توابع حذف کرده بودم . چون من در برنامه اینتراپت داشتم و وجود اون اینتراپت های منو غیر فعال میکرد . پس کارش دقیقا همین غیر فعال کردن اینتراپت ها ست دیگه ؟

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

                          دیدگاه


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

                            اون تابع نیست
                            کد:
                            #define   cli()      		__disable_interrupt()
                            شما باید از کد پست قبلی استفاده کنید تا در صورتیکه اینتراپتها فعال هستند ، ابتدا آن را غیر فعال و بعد به حالت قبل برگردد.

                            دیدگاه


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

                              نوشته اصلی توسط امیر . م
                              اون تابع نیست
                              کد:
                              #define   cli()      		__disable_interrupt()
                              شما باید از کد پست قبلی استفاده کنید تا در صورتیکه اینتراپتها فعال هستند ، ابتدا آن را غیر فعال و بعد به حالت قبل برگردد.
                              با تشکر از شما . دقیقا با اضافه نمودن همین کد ها در همون توابعی که خودتان معرفی نمودید مشکل سرعت آن برطرف شد .
                              و با اضافه نمودن همین کد به کد های خواندن و نوشتن از حافظه 24C512 مشکلات این توابع نیز حل شد . (ریست کردن میکرو در هنگام فعال بودن اینتراپت )

                              کد های کامل خواندن و نوشتن از حافظه سری 24C512 با Xmega

                              کد:
                              void TWI_Hard_init()
                              {
                              	TWID.MASTER.CTRLA = TWI_MASTER_INTLVL_LO_gc |TWI_MASTER_RIEN_bm |TWI_MASTER_WIEN_bm |TWI_MASTER_ENABLE_bm;
                              	TWID.MASTER.BAUD = TWI_BAUDSETTING;
                              	TWID.MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
                              }
                              
                              void TWI_eeprom_bytewrite(unsigned int SlaveAddress,unsigned int MemoryAddress,char Data)
                              {
                              	
                              	unsigned char addressL = MemoryAddress & 0xff;
                              	unsigned char addressH = MemoryAddress >> 8;
                              	
                              	char s = SREG;
                              	cli();
                              	
                              	TWID.MASTER.STATUS  = 0x01; //force idle
                              	
                              	TWID.MASTER.CTRLC = 0x01;
                              	SlaveAddress = EEPROM_ID<<1;
                              	TWID.MASTER.ADDR = SlaveAddress ;
                              	while(!(TWID.MASTER.STATUS & 0x40));
                              	TWID.MASTER.DATA = addressH;
                              	while(!(TWID.MASTER.STATUS & 0x40));
                              	TWID.MASTER.DATA = addressL;
                              	while(!(TWID.MASTER.STATUS & 0x40));
                              	TWID.MASTER.DATA = Data;
                              	while(!(TWID.MASTER.STATUS & 0x40));
                              	fcpu_delay_ms(10);
                              	TWID.MASTER.CTRLC = 0x03;
                              	
                              	SREG = s;
                              }
                              
                              char TWI_eeprom_byteread(unsigned int SlaveAddress,unsigned int MemoryAddress)
                              {
                              	
                              	unsigned char addressL = MemoryAddress & 0xff;
                              	unsigned char addressH = MemoryAddress >> 8;
                              	char Data = 0;
                              	char s = SREG;
                              	cli();
                              	
                              	TWID.MASTER.STATUS = 0x01; // force idle
                              	
                              	TWID.MASTER.CTRLC = 0x01;
                              	fcpu_delay_ms(3);
                              	SlaveAddress = EEPROM_ID<<1;
                              	TWID.MASTER.ADDR = SlaveAddress;
                              	while(!(TWID.MASTER.STATUS & 0x40));
                              	TWID.MASTER.DATA = addressH;
                              	while(!(TWID.MASTER.STATUS & 0x40));
                              	TWID.MASTER.DATA = addressL;
                              	while(!(TWID.MASTER.STATUS & 0x40));
                              	TWID.MASTER.CTRLC = 0x05;
                              	TWID.MASTER.ADDR = (SlaveAddress | 1);
                              	while(!(TWID.MASTER.STATUS & 0xC0));
                              	Data = TWID.MASTER.DATA;
                              	TWID.MASTER.CTRLC=0x07;
                              	fcpu_delay_ms(10);
                              	
                              	SREG = s;
                              	
                              	return Data;
                              }
                              - به دنبال فرصت عمري تباه کردم ! فرصت جواني ام بود من اشتباه کردم .

                              دیدگاه


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

                                کد:
                                #define BAUDRATE  100000
                                #define TWI_BAUD(F_SYS, F_TWI) ((F_SYS / (2 * F_TWI)) - 5)
                                #define TWI_BAUDSETTING TWI_BAUD(CPU_SPEED, BAUDRATE)
                                دوستان من این قسمت از کد رو متوجه نشدم
                                لطف میکنید توضیح بدید
                                در ضمن در کس مگا اونجوری که من در دیتا شیت و کدها دیدم رجیستر دیتا 7 بیتی هست و در نتیجه باید شیف بخوره ..درسته؟

                                دیدگاه

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