اطلاعیه

Collapse
No announcement yet.

مشکل پیداسازی I2C به صورت نرم افزاری

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

    مشکل پیداسازی I2C به صورت نرم افزاری

    با سلام
    میخواستم i2c رو در avr به صورت نرم افزاری خودم بنوسیم و با ds1307 ارتباط برقرار کنم کدی که زیر نوشتم دو بخش داره 1) پیدا سازی نرم افزای i2c که خوندم نوشتم و 2) ارتباط با ds1307..... که این بخش رو مشکلی ندارم و کاملا فهمیدم البته برای راحتی کار از کتابخانه ds1307.lib کد ویژن استفاده کردم اما در بخش اول میخوام کدم تصحیح بشه و مشکلم در ACK و NACK بر طرف بشه در واقع میخوام این کار کنه :agree:

    کد:
    #include <mega32a.h>
    #include <delay.h>
    #include <bcd.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    
    #pragma used+
     void I2c_Start(void);
     void I2c_Stop(void);
     unsigned char I2c_Write(unsigned char ); 
     unsigned char i2c_rx(char ack);  
     ////////////////////////////////////////////////////////////////////////////////////////////////
     unsigned char rtc_read(unsigned char );
     void rtc_write(unsigned char ,unsigned char );
     void rtc_init(unsigned char ,unsigned char ,unsigned char );
     void rtc_get_time(unsigned char *,unsigned char *,unsigned char *);
     void rtc_set_time(unsigned char ,unsigned char ,unsigned char );
     void rtc_get_date(unsigned char *,unsigned char *,unsigned char *,unsigned char *);
     void rtc_set_date(unsigned char ,unsigned char ,unsigned char ,unsigned char );  
    #pragma used-
    
    
    #define SCL  PORTA.0 
    #define SDA  PORTA.1 
    
    #define SDA_IN  PINA.1 
    
    
    //#define DS1307_ADDR_WRITE 0xD0 
    //#define DS1307_ADDR_READ 0xD1
    
     unsigned char h,m,s,nn[10];
    
    void main(void)
    {
    
    
    // Input/Output Ports initialization
    // Port A initialization
    // Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=Out Bit0=Out 
    DDRA=(0<<DDA7) | (0<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) | (1<<DDA1) | (1<<DDA0);
    // State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=0 Bit0=0 
    PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);
    
    
    // Port C initialization
    // Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=Out Bit0=Out 
    DDRC=(0<<DDC7) | (0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) | (1<<DDC1) | (1<<DDC0);
    // State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=0 Bit0=0 
    PORTC=(0<<PORTC7) | (0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);
    
    // USART initialization
    // Communication Parameters: 8 Data, 1 Stop, No Parity
    // USART Receiver: On
    // USART Transmitter: On
    // USART Mode: Asynchronous
    // USART Baud Rate: 9600
    UCSRA=(0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<UPE) | (0<<U2X) | (0<<MPCM);
    UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (1<<RXEN) | (1<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
    UCSRC=(1<<URSEL) | (0<<UMSEL) | (0<<UPM1) | (0<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL);
    UBRRH=0x00;
    UBRRL=0x47;
    
     
      rtc_init(0,0,0);
      
    while (1)
       {
       rtc_get_time(&h,&m,&s);
        itoa(h,nn);
        puts(nn);
       delay_ms(500);
       
       }
    }
     ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
     ///////I2C
     
     void I2c_Start(void)
     {
      DDRA=0x03;      //sda=input scl=output
      SCL=1;
      SDA=1;
      
      delay_us(10); 
      SDA=0;       //start
      delay_us(10);
      
      SCL=0;
       delay_us(10);
     }
     
     void I2c_Stop(void)
     {
      DDRA=0x03;        //sda=input scl=output
     
       delay_us(5);     // i2c stop bit sequence  
     SCL = 1;
       delay_us(10);
     SDA = 1;
      delay_us(10);
     }
     
     unsigned char I2c_Write( unsigned char address)
     { 
     
     char i,ac;
     
     for(i=0;i<=7;i++)
      {
      if( (address) & ( 1<<(7-i)) )
        SDA=1; else SDA=0;
        SCL=1;
        delay_us(10);
         SCL=0;      
      } 
       SDA = 1;
       SCL = 1;
      
      DDRA=0x01;      // SDA Input 
      SCL = 1;
      delay_us(1);
       ac = SDA_IN;  
                    // Clear SDA
       SCL = 0;
       return ac;         
     }
    
     unsigned char i2c_rx(char ack)
    {
    unsigned char i,Data=0 ;
     DDRA=0x01;
      
     for(i=0;i<=7;i++)
       {
        SCL=1;
        delay_us(10);
        Data= Data | (SDA_IN<<(7-i));
        SCL=0;
        delay_us(10);  
       }
      
      DDRA=0x03;
     if(ack) SDA = 0; else SDA = 1;
     
     SCL = 1;
      delay_us(10);       // send (N)ACK bit
     SCL = 0;
     delay_us(10);
     
     return Data;
    }
    
    
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
     // Ds1307 
     
    unsigned char rtc_read(unsigned char address)
    {
    unsigned char data;
    I2c_Start();
    I2c_Write(0xd0);
    I2c_Write(address);
    I2c_Stop(); 
    I2c_Start();
    I2c_Write(0xd1);
    data=i2c_rx(0);
    I2c_Stop();
    return data;
    }
    
    void rtc_write(unsigned char address,unsigned char data)
    {
    I2c_Start();
    I2c_Write(0xd0);
    I2c_Write(address);
    I2c_Write(data);
    I2c_Stop();
    }
    
    void rtc_init(unsigned char rs,unsigned char sqwe,unsigned char out)
    {
    rs&=3;
    if (sqwe) rs|=0x10;
    if (out) rs|=0x80;
    I2c_Start();
    I2c_Write(0xd0);
    I2c_Write(7);
    I2c_Write(rs);
    I2c_Stop();
    }
    
    void rtc_get_time(unsigned char *hour,unsigned char *min,unsigned char *sec)
    {
    I2c_Start();
    I2c_Write(0xd0);
    I2c_Write(0);
    I2c_Stop(); 
    I2c_Start();
    I2c_Write(0xd1);
    *sec=bcd2bin(i2c_rx(1));
    *min=bcd2bin(i2c_rx(1));
    *hour=bcd2bin(i2c_rx(0));
    I2c_Stop();
    }
    
    void rtc_set_time(unsigned char hour,unsigned char min,unsigned char sec)
    {
    I2c_Start();
    I2c_Write(0xd0);
    I2c_Write(0);
    I2c_Write(bin2bcd(sec));
    I2c_Write(bin2bcd(min));
    I2c_Write(bin2bcd(hour));
    I2c_Stop();
    }
    
    void rtc_get_date(unsigned char *week_day,unsigned char *day,unsigned char *month,unsigned char *year)
    {
    I2c_Start();
    I2c_Write(0xd0);
    I2c_Write(3); 
    I2c_Stop(); 
    I2c_Start();
    I2c_Write(0xd1);
    *week_day=i2c_rx(1);
    *day=bcd2bin(i2c_rx(1));
    *month=bcd2bin(i2c_rx(1));
    *year=bcd2bin(i2c_rx(0));
    I2c_Stop();
    }
    
    void rtc_set_date(unsigned char week_day,unsigned char day,unsigned char month,unsigned char year)
    {
    I2c_Start();
    I2c_Write(0xd0);
    I2c_Write(3); 
    I2c_Write(week_day); 
    I2c_Write(bin2bcd(day));
    I2c_Write(bin2bcd(month));
    I2c_Write(bin2bcd(year));
    I2c_Stop();
    }

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

    کسی نیست یعنی ؟

    دیدگاه


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

      یه بار یه جواب نوشتم براتون ولی پاک شد و ارسال نشد . حوصله نداشتم دوباره تایپ کنم

      تا اونجایی که من میدونم توی پروتکل i2c هیچ میکرویی حق نداره خروجی یک ( HIGH ) تولید کنه . بلکه فقط حق داره یا صفر تولید کنه یا اینکه پایه خودشو قطع کنه ( ورودی کنه ) و اون دو تا مقاومت پول پ وظیفه ایجاد یک روی باس رو دارند ( این کار رو کردند تا اتصال کوتاه پیش نیاد )

      پس شما باید رجیستر PORT پایه های SDA و SCL رو صفر کنی و برای ارسال صفر ، رجیستر DDR پایه مورد نظر رو یک کنی و برای ارسال یک ، رجیستر DDR پایه مورد نظر رو صفر کنی ( برعکس )

      دیدگاه


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

        برنامه رو ببینید این کار رو کردم :(
        میخوام ببینم مشکل برنامم چیهه؟؟

        دیدگاه


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

          نوشته اصلی توسط yashar666
          برنامه رو ببینید این کار رو کردم :(
          میخوام ببینم مشکل برنامم چیهه؟؟
          برنامه رو دیدم

          این کار رو نکردی !

          رجیستر پورت باید همیشه صفر بمونه

          هر وقت خواستی پایه های SDA و SCL رو صفر کنی فقط باید رجیستر DDR اونها رو یک کنی و
          هر وقت خواستی پایه های SDA و SCL رو یک کنی فقط باید رجیستر DDR اونها رو صفر کنی . به رجیستر PORT هیچ کاری نداشته باش !

          پس اون دو تا Define که برای SDA و SCL نوشتی رو عوض کن و بکن DDRA.0 و DDRA.1 !

          بازم نگاه میکنم اشکال دیگه پیدا کردم میگم

          دیدگاه


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

            مشکلم حل نشد

            دیدگاه


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

              چرا از کتابخونه i2c.h استفاده نمیکنید؟
              آیا جهالت نیست که آدمی ساعات شیرین امروز را فدای روزهای آینده کند؟

              دیدگاه


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

                چون دقیقا میخوام درک کنم چه اتفاقی میوفته با اون کتاب خونه کارمو انجام دادم اما خودم میخوام بنویسم
                ممنون میشم کدم رو نگاه کنید و درستش کنید ....

                دیدگاه


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

                  من خودم با قسمت سخت افزاری کار کردم.کتابخونه نرم افزاریش را هم دارم که مطمئنم درست کار میکنه.از روش ببینید و چک کنید.
                  کد:
                  #include <delay.h>
                  #include <mega32.h>
                  #include <stdio.h>
                  #define OUTPUT 1
                  #define INPUT 0
                  #define SCL_DDR DDRC.0
                  #define SDA_DDR DDRC.1
                  #define SCL_PIN PINC.0
                  #define SDA_PIN PINC.1
                  #define SCL PORTC.0
                  #define SDA PORTC.1
                  
                  void SCCB_init(void);
                  void SCCB_start(void);
                  void SCCB_stop(void);
                  void noAck(void);
                  unsigned char SCCB_write(unsigned char m_data);
                  unsigned char SCCB_read(void);
                  void SCCB_init(void)
                  {
                    SCL_DDR=OUTPUT;
                    SDA_DDR=OUTPUT;
                  //REALSING THE LINE
                    SCL=1;
                    SDA=1;
                  }
                  
                  void SCCB_start(void)
                  {
                    SDA=1;
                    delay_us(100);
                  
                    SCL=1;
                    delay_us(100);
                  
                    SDA=0;
                    delay_us(100);
                  
                    SCL=0;;
                    delay_us(100);
                  }
                  
                  void SCCB_stop(void)
                  {
                  	SDA=0;
                    delay_us(100);
                  
                    SCL=1;
                    delay_us(100);
                  
                  
                    SDA=1;
                    delay_us(100);
                  }
                  
                  void noAck(void)
                  {
                  
                  	SDA=1;
                  	delay_us(100);
                  
                  	SCL=1;
                  	delay_us(100);
                  
                  	SCL=0;
                  	delay_us(100);
                  
                  	SDA=0;
                  	delay_us(100);
                  
                  }
                  
                  unsigned char SCCB_write(unsigned char m_data)
                  {
                    unsigned char j,tem;
                  
                    for(j=0;j<8;j++)
                    {
                      if((m_data<<j)&0x80)
                      {
                        SDA=1;
                      }
                      else
                      {
                        SDA=0;
                      }
                      delay_us(100);
                      SCL=1;
                      delay_us(100);
                      SCL=0;
                      delay_us(100);
                  
                    }
                    delay_us(100);
                  
                  	SDA_DDR=INPUT;
                  	delay_us(100);
                  	SCL=1;
                  	delay_us(1000);
                  	if(SDA_PIN)
                  	{
                  		tem=0;
                  	}
                  	else
                  	{
                  		tem=1;
                  	}
                  	SCL=0;
                  	delay_us(100);
                    SDA_DDR=OUTPUT;
                  
                  	return(tem);
                  }
                  
                  
                  unsigned char SCCB_read(void)
                  {
                  	unsigned char read,j;
                  	read=0x00;
                  
                  	SDA_DDR=INPUT;
                  	delay_us(100);
                    printf("\tbe for");
                  	for(j=8;j>0;j--)
                  	{
                  		delay_us(100);
                  		SCL=1;
                  		delay_us(100);
                  		read=read<<1;
                  		if(SDA_PIN)
                  		{
                  			read=read+1;
                  		}
                  		SCL=0;
                  		delay_us(100);
                  	}
                    SDA_DDR=OUTPUT;
                  	return(read);
                  }
                  آیا جهالت نیست که آدمی ساعات شیرین امروز را فدای روزهای آینده کند؟

                  دیدگاه

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