Hỏi về phần I2C

bigboy061293

Thành Viên PIF
em có tìm trước trên diễn đàn phần I2C rồi, có tham khảo các code nữa nhưng em vẫn chưa thông lắm :)

em nhờ mọi người 1 chuyện đơn giản thôi, là như vầy, khi mình đổ được giây, phút, ... năm từ ds1307 vào pic rồi thì cái mảng đó hiện đang là kí tự, vậy các anh chị cho em code phần từ đầu đến lúc tạo được cái mảng đó đi, phần sau em nghĩ mình tự bương chải được :) em cám ơn trước
 

bigboy061293

Thành Viên PIF
à quên nữa, em cũng cần tham khảo cái code dùng nút để chỉnh lại giờ, phút cho ds1307, mọi người giúp dùm em nhe :)
 

bigboy061293

Thành Viên PIF
mọi người giúp dùm em với. Ý tưởng của em là thế này, tạo led sáng theo kim của đồng hồ (loại đồng hồ treo tường bình tường á), tức là khi kim đồng hồ chỉ tới số nào thì số đó sáng lên. Em mò được tới phần I2C với con ds1307 rồi, cho con ds1307 đếm, đếm cùng lúc với kim đồng hồ (thử kim giây trước), khi đó kim giây nhích tới đâu, led đó sáng lên. EM Cũng mò được tới code dưới đây, proteus chạy ngon lành nhưng đổ lên pic không chạy được, mọi người giúp em với, em cám ơn trước :)

Code:
#include <htc.h>
#include "i2c.h"

#include <stdlib.h>
__CONFIG(XT & WDTDIS & PWRTEN & MCLREN & UNPROTECT & SWBOREN & IESODIS & FCMDIS & LVPDIS & DEBUGDIS); //1st config. Word

__CONFIG(BORV21); //2st config. Word

#define _XTAL_FREQ 4000000 //t?n s? th?ch anh 4Mhz

// DS1307 7-bit address = 0b 110 1000 = 0x68
#define SLAVE_ADD 0x68
#define READ 1
#define WRITE 0
char b[7];
char c[14];
int xuat[7];
void delay()
{
	int i;
	for (i=0;i<10;i++) __delay_ms(100);
}
void khaibaocong()
{
	ANSELH=0;
	ANSEL=0;
	TRISD=0; 
	PORTD=0x00;
}


int chuyendoi(char k)
{
	int i;
	switch (k)
		{
			case 0x30: i=0; break;
			case 0x31: i=1; break;
			case 0x32: i=2; break;
			case 0x33: i=3; break;
			case 0x34: i=4; break;
			case 0x35: i=5; break;
			case 0x36: i=6; break;
			case 0x37: i=7; break;
			case 0x38: i=8; break;
			case 0x39: i=9; break;
		}
	return i;
}
void set_time()
{
i2c_start();
i2c_write((SLAVE_ADD<<1)|WRITE);
i2c_write(0X00);
i2c_write(0X01); //giay
i2c_write(0X23); //phut
i2c_write(0X09); //gio
i2c_write(0X07); //thu
i2c_write(0X20); //ngay
i2c_write(0X03); //thang
i2c_write(0X11); //nam
i2c_stop();
}
void read_time()
{ unsigned int i;
i2c_start();
i2c_write((SLAVE_ADD<<1)|WRITE);
i2c_write(0x00);
i2c_stop();
i2c_start();
i2c_write((SLAVE_ADD<<1)|READ);
for(i=0;i<=5;i++)
{
b[i]=i2c_read(0);
}
b[6]=i2c_read(1);
i2c_stop();
}

void Display(char b[])
{
int i,j=0;
// unsigned char c[];
// Luu y: ket qua doc tu RTC DS1307 la so BCD
// Vi du: 24giay --> Ket qua doc ve la: 0x24
// Nen phai tach chu so "2" va so "4" rieng ra de hien thi

// tach bcd tu mang b, luu vao mang c -------------------------//
for(i=0;i<7;i++)
{
// mang c chua cac gia tri ascii, 14 bytes
// tach BCD, lay nibble cao
c[j]=b[i]/16+0x30;
// lay nibble thap
c[j+1]=(b[i]-(c[j]-0x30)*16)+0x30;
j+=2;
}




//--------------- xuat ra mang so ---------------------------//
j=0;
for (i=0;i<15;i+=2)
	{
		xuat[j]=(chuyendoi(c[i]));
		xuat[j]=((xuat[j]*10)+chuyendoi(c[i+1]));
		j++;
	}
}



//      hien thi dong ho      //
void hienthi()
{
	switch (xuat[0])
	{
		case 00: PORTD=0b01111111; delay(); break;
		case 01: PORTD=0b10111111; delay(); break;
		case 02: PORTD=0b11011111; delay(); break;
		case 03: PORTD=0b11101111; delay(); break;
		case 04: PORTD=0b11110111; delay(); break;
		case 05: PORTD=0b11111011; delay(); break;
		case 06: PORTD=0b11111101; delay(); break;
		case 07: PORTD=0b11111111; delay(); break;
	}

}
void main()
{
khaibaocong();
i2c_init();

set_time();

while(1)
{
read_time();
Display(b);
hienthi();
__delay_ms(150);
__delay_ms(150);
}
}
 

supergoodfriends

Trứng gà
cho mình góp ý ngoài lề tí.
về ý tưởng của bạn. Sao mình không dùng các quang trở để xử lý lúc kim chạy đển đâu thì số đó sáng lên. Như vậy thì sẽ đơn giản hơn, bạn không cần phải đồng bộ giữa đồng hồ cơ và DS1308. Và sẽ dễ xử lý chương trình hơn.
 

bigboy061293

Thành Viên PIF
cám ơn bạn đã góp ý, đúng là dùng quang trở thì dễ hơn thật nhưng mà chắc không dùng được buổi tối :( Chắc mình sẽ đổi phương án quá nhưng dù sao cũng không hiểu được tại sao nó không chạy ngoài pic mà trong proteus thì rất ok :(
 

supergoodfriends

Trứng gà
cám ơn bạn đã góp ý, đúng là dùng quang trở thì dễ hơn thật nhưng mà chắc không dùng được buổi tối :( Chắc mình sẽ đổi phương án quá nhưng dù sao cũng không hiểu được tại sao nó không chạy ngoài pic mà trong proteus thì rất ok :(
Với DS1307 thì mình chưa làm nên cũng chưa biết nó như thế nào. Như ý tưởng trên thì cũng có thể dùng hồng ngoại cũng được. Hoặc kết hợp ánh sáng phát ra từ hồng ngoại với quang trở.
 
Top