با سلام
میخواستم i2c رو در avr به صورت نرم افزاری خودم بنوسیم و با ds1307 ارتباط برقرار کنم کدی که زیر نوشتم دو بخش داره 1) پیدا سازی نرم افزای i2c که خوندم نوشتم و 2) ارتباط با ds1307..... که این بخش رو مشکلی ندارم و کاملا فهمیدم البته برای راحتی کار از کتابخانه ds1307.lib کد ویژن استفاده کردم اما در بخش اول میخوام کدم تصحیح بشه و مشکلم در ACK و NACK بر طرف بشه در واقع میخوام این کار کنه :agree:
میخواستم 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();
}




دیدگاه